Migrate and enhance BitBox integration with updated library (#3765)
What changed, and why it matters
This commit updates Cake Wallet's integration with BitBox hardware wallets. It swaps an older local library for a newer one fetched from GitHub, rewrites the connection code to support both USB and Bluetooth (BLE), and adds a user-facing pairing-code confirmation screen. The changes are mostly a feature/refactor rather than a clear security fix, but they touch sensitive areas: how the app talks to a hardware wallet, verifies the pairing channel, and signs cryptocurrency transactions.
Review the new bitbox_flutter dependency source (cake-tech/bitbox_flutter at the pinned ref) for supply-chain integrity, verify that channel-hash verification cannot be bypassed programmatically, and audit the BLE pairing/scanning flow for man-in-the-middle risks. Because the diff does not show the new library's implementation, treat this as a partial patch requiring follow-up review.
Security signals we found
Hardware wallet signing path refactored
Channel hash verification UI added for BitBox pairing
BLE transport introduced for hardware wallet communication
Dependency source changed from local path to external Git repository
CI build steps and Docker integration for BitBox removed
Evidence from the diff
The patch migrates from BitboxManager to BitboxConnection/BitboxConnectionManager classes in the cake-tech/bitbox_flutter fork. It removes local build scripts and Docker stages for bitbox_flutter, replacing the path dependency with a Git dependency at ref 3d1c607f14c6d5bace2971ec4c10b5201053cc56. Service classes for Bitcoin, Litecoin and EVM chains are refactored to use BitboxBitcoin/BitboxEthereum helpers. A new channel-hash verification bottom sheet is added, and BLE scanning is enabled for iOS only. The commit also restricts BitBox availability to mobile non-monero-only builds and swaps SvgPicture for CakeImageWidget in manufacturer lists.
Changed components
BitBox hardware wallet integrationcw_bitcoin/lib/hardware/bitbox_service.dartcw_evm/lib/hardware/evm_chain_bitbox_service.dartcw_evm/lib/hardware/evm_chain_bitbox_credentials.dartlib/view_model/hardware_wallet/bitbox_view_model.dartlib/new-ui/widgets/hardware_wallet/bitbox_paring_sheet.dartpubspec_base.yaml / cw_bitcoin/pubspec.yaml / cw_evm/pubspec.yaml bitbox_flutter dependencyAndroid and Linux CI/Docker build scriptsInspect captured patch +471 / −386
### .github/workflows/lint.yml
@@ -73,13 +73,6 @@ jobs:
# rm ./reown_flutter.tar.gz
# popd
#
-# - name: Build Bitbox Flutter
-# run: |
-# set -x -e
-# pushd scripts
-# ./build_bitbox_flutter.sh
-# popd
-#
# - name: Prepare Zcash
# run: |
# set -x -e
@@ -112,4 +105,4 @@ jobs:
#
# - name: Lint
# run: |
-# ABORT_ON_CHANGE=yeah scripts/lint.sh
\ No newline at end of file
+# ABORT_ON_CHANGE=yeah scripts/lint.sh
### .github/workflows/pr_test_build_ios.yml
@@ -220,12 +220,6 @@ jobs:
-e '/ZanoWallet\.xcframework/d' \
ios/Runner.xcodeproj/project.pbxproj
- - name: Prepare bitbox_flutter
- run: |
- pushd scripts
- ./build_bitbox_flutter.sh clone-only
- popd
-
- name: Prepare reown_flutter
run: ./scripts/prepare_reown.sh
### .github/workflows/pr_test_build_linux.yml
@@ -49,27 +49,6 @@ jobs:
- name: Build base
run: ./scripts/linux/docker/build.sh --only base
- bitbox:
- needs: base
- runs-on: puzl-ubuntu-latest
- timeout-minutes: 360
- steps:
- - uses: actions/checkout@v4
- if: ${{ env.ACT != 'true' }}
- with:
- ref: ${{ github.event.pull_request.head.sha }}
- repository: ${{ github.event.pull_request.head.repo.full_name }}
- - name: Docker sock permissions
- run: sudo chmod 666 /var/run/docker.sock || true
- - name: Log in to GitHub Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- - name: Build bitbox
- run: ./scripts/linux/docker/build.sh --only bitbox
-
mwebd:
needs: base
runs-on: puzl-ubuntu-latest
@@ -200,7 +179,7 @@ jobs:
run: ./scripts/linux/docker/build.sh --only monero --merge
final:
- needs: [bitbox, mwebd, reown, zcash, torch, monero_merge]
+ needs: [mwebd, reown, zcash, torch, monero_merge]
runs-on: puzl-ubuntu-latest
timeout-minutes: 360
steps:
### .github/workflows/reusable-build.yml
@@ -42,26 +42,6 @@ jobs:
- name: Build base
run: ./scripts/android/docker/build.sh --only base
- bitbox:
- needs: base
- runs-on: puzl-ubuntu-latest
- timeout-minutes: 360
- steps:
- - uses: actions/checkout@v4
- if: ${{ env.ACT != 'true' }}
- with:
- ref: ${{ inputs.ref }}
- - name: Docker sock permissions
- run: sudo chmod 666 /var/run/docker.sock || true
- - name: Log in to GitHub Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- - name: Build bitbox
- run: ./scripts/android/docker/build.sh --only bitbox
-
mwebd:
needs: base
runs-on: puzl-ubuntu-latest
@@ -236,7 +216,7 @@ jobs:
run: ./scripts/android/docker/build.sh --only decred
final:
- needs: [bitbox, mwebd, reown, zcash, torch_merge, monero_merge, decred]
+ needs: [mwebd, reown, zcash, torch_merge, monero_merge, decred]
runs-on: puzl-ubuntu-latest
timeout-minutes: 360
steps:
### cw_bitcoin/lib/hardware/bitbox_service.dart
@@ -1,47 +1,51 @@
-import 'dart:async';
-import 'dart:convert';
-import 'dart:developer';
-import 'dart:typed_data';
-
-import 'package:bitbox_flutter/bitbox_manager.dart';
-import 'package:bitcoin_base/bitcoin_base.dart';
-import 'package:blockchain_utils/blockchain_utils.dart';
-import 'package:cw_bitcoin/electrum_wallet.dart';
-import 'package:cw_bitcoin/hardware/bitcoin_hardware_wallet_service.dart';
-import 'package:cw_bitcoin/psbt/transaction_builder.dart';
-import 'package:cw_bitcoin/psbt/v0_deserialize.dart';
-import 'package:cw_bitcoin/psbt/v0_finalizer.dart';
-import 'package:cw_bitcoin/utils.dart';
-import 'package:cw_core/hardware/hardware_account_data.dart';
-import 'package:cw_core/hardware/hardware_wallet_service.dart';
-import 'package:ledger_bitcoin/psbt.dart';
+import "dart:async";
+import "dart:convert";
+import "dart:developer";
+import "dart:typed_data";
+
+import "package:bitbox_flutter/bitbox_flutter.dart";
+import "package:bitcoin_base/bitcoin_base.dart";
+import "package:blockchain_utils/blockchain_utils.dart";
+import "package:cw_bitcoin/electrum_wallet.dart";
+import "package:cw_bitcoin/hardware/bitcoin_hardware_wallet_service.dart";
+import "package:cw_bitcoin/psbt/transaction_builder.dart";
+import "package:cw_bitcoin/psbt/v0_deserialize.dart";
+import "package:cw_bitcoin/psbt/v0_finalizer.dart";
+import "package:cw_bitcoin/utils.dart";
+import "package:cw_core/hardware/hardware_account_data.dart";
+import "package:cw_core/hardware/hardware_wallet_service.dart";
+import "package:ledger_bitcoin/psbt.dart";
class BitcoinBitboxService extends HardwareWalletService with BitcoinHardwareWalletService {
BitcoinBitboxService(this.manager);
// https://github.com/BitBoxSwiss/bitbox02-api-go/blob/ae070b1d41bf1cf00588fa6f498b4734b5ecd6fc/api/firmware/messages/btc.pb.go#L40
static const int bitboxCoinType = 0;
- final BitboxManager manager;
+ final BitboxConnection manager;
+
+ BitboxBitcoin _getBitcoin() => BitboxBitcoin(manager.ffi, coinType: bitboxCoinType);
@override
Future<List<HardwareAccountData>> getAvailableAccounts({int index = 0, int limit = 5}) async {
final accounts = <HardwareAccountData>[];
final indexRange = List.generate(limit, (i) => i + index);
// https://github.com/BitBoxSwiss/bitbox02-api-go/blob/ae070b1d41bf1cf00588fa6f498b4734b5ecd6fc/api/firmware/messages/btc.pb.go#L252
- final keyType = 1; // xPUB
+ const keyType = 1; // xPUB
for (final i in indexRange) {
final derivationPath = "m/84'/0'/$i'";
- final xPub = await manager.getBTCXPub(bitboxCoinType, derivationPath, keyType);
+ final xPub = await _getBitcoin().getXPub(derivationPath, addressType: keyType);
final hd = Bip32Slip10Secp256k1.fromExtendedKey(xPub).childKey(Bip32KeyIndex(0));
final address = generateP2WPKHAddress(hd: hd, index: 0, network: BitcoinNetwork.mainnet);
- accounts.add(HardwareAccountData(
- address: address,
- accountIndex: i,
- derivationPath: derivationPath,
- xpub: xPub,
- ));
+ accounts.add(
+ HardwareAccountData(
+ address: address,
+ accountIndex: i,
+ derivationPath: derivationPath,
+ xpub: xPub,
+ ),
+ );
}
return accounts;
@@ -50,9 +54,9 @@ class BitcoinBitboxService extends HardwareWalletService with BitcoinHardwareWal
@override
Future<Uint8List> signTransaction({required String transaction}) async {
final psbt = PsbtV2()..deserialize(base64Decode(transaction));
- log(base64Encode(psbt.asPsbtV0()), name: 'PSBT');
- final signedPsbt = await manager.signBTCPsbt(bitboxCoinType, base64Encode(psbt.asPsbtV0()));
- log(signedPsbt, name: 'signed PSBT');
+ log(base64Encode(psbt.asPsbtV0()), name: "PSBT");
+ final signedPsbt = await _getBitcoin().signPsbt(base64Encode(psbt.asPsbtV0()));
+ log(signedPsbt, name: "signed PSBT");
final transactionRes = PsbtV2()
..deserializeV0(base64Decode(signedPsbt))
..finalizeV0();
@@ -61,48 +65,52 @@ class BitcoinBitboxService extends HardwareWalletService with BitcoinHardwareWal
@override
Future<Uint8List> signMessage({required Uint8List message, String? derivationPath}) =>
- manager.signBTCMessage(bitboxCoinType, derivationPath ?? "m/84'/0'/0'/0/0", message);
+ _getBitcoin().signMessage(derivationPath ?? "m/84'/0'/0'/0/0", message);
@override
- Future<Uint8List> getMasterFingerprint() => manager.getMasterFingerprint();
+ Future<Uint8List> getMasterFingerprint() => _getBitcoin().getMasterFingerprint();
}
class LitecoinBitboxService extends HardwareWalletService
with BitcoinHardwareWalletService, LitecoinHardwareWalletService {
LitecoinBitboxService(this.manager);
- final BitboxManager manager;
+ final BitboxConnection manager;
// https://github.com/BitBoxSwiss/bitbox02-api-go/blob/ae070b1d41bf1cf00588fa6f498b4734b5ecd6fc/api/firmware/messages/btc.pb.go#L40
static const int bitboxCoinType = 2;
+ BitboxBitcoin _getBitcoin() => BitboxBitcoin(manager.ffi, coinType: bitboxCoinType);
+
@override
Future<List<HardwareAccountData>> getAvailableAccounts({int index = 0, int limit = 5}) async {
final accounts = <HardwareAccountData>[];
final indexRange = List.generate(limit, (i) => i + index);
// https://github.com/BitBoxSwiss/bitbox02-api-go/blob/ae070b1d41bf1cf00588fa6f498b4734b5ecd6fc/api/firmware/messages/btc.pb.go#L252
- final keyType = 1; // xPUB
+ const keyType = 1; // xPUB
for (final i in indexRange) {
final derivationPath = "m/84'/2'/$i'";
- final xPub = await manager.getBTCXPub(bitboxCoinType, derivationPath, keyType);
+ final xPub = await _getBitcoin().getXPub(derivationPath, addressType: keyType);
final hd = Bip32Slip10Secp256k1.fromExtendedKey(xPub).childKey(Bip32KeyIndex(0));
final address = generateP2WPKHAddress(hd: hd, index: 0, network: LitecoinNetwork.mainnet);
- accounts.add(HardwareAccountData(
- address: address,
- accountIndex: i,
- derivationPath: derivationPath,
- xpub: xPub,
- ));
+ accounts.add(
+ HardwareAccountData(
+ address: address,
+ accountIndex: i,
+ derivationPath: derivationPath,
+ xpub: xPub,
+ ),
+ );
}
return accounts;
}
@override
Future<Uint8List> signMessage({required Uint8List message, String? derivationPath}) =>
- manager.signBTCMessage(bitboxCoinType, derivationPath ?? "m/84'/0'/0'/0/0", message);
+ _getBitcoin().signMessage(derivationPath ?? "m/84'/0'/0'/0/0", message);
@override
Future<String> signLitecoinTransaction({
@@ -112,7 +120,7 @@ class LitecoinBitboxService extends HardwareWalletService
}) async {
final psbt = PSBTTransactionBuild(inputs: inputs, outputs: outputs).psbt;
- final signedPsbt = await manager.signBTCPsbt(bitboxCoinType, base64Encode(psbt.asPsbtV0()));
+ final signedPsbt = await _getBitcoin().signPsbt(base64Encode(psbt.asPsbtV0()));
final transactionRes = PsbtV2()
..deserializeV0(base64Decode(signedPsbt))
..finalizeV0();
@@ -121,5 +129,5 @@ class LitecoinBitboxService extends HardwareWalletService
}
@override
- Future<Uint8List> getMasterFingerprint() => manager.getMasterFingerprint();
+ Future<Uint8List> getMasterFingerprint() => _getBitcoin().getMasterFingerprint();
}
### cw_bitcoin/pubspec.yaml
@@ -61,7 +61,9 @@ dependencies:
ref: 591d4b8c821b9c10561f848b866324a9a8dcb489
path: trezor-flutter
bitbox_flutter:
- path: ../scripts/bitbox_flutter
+ git:
+ url: https://github.com/cake-tech/bitbox_flutter.git
+ ref: 3d1c607f14c6d5bace2971ec4c10b5201053cc56
socks_socket:
git:
url: https://github.com/sneurlax/socks_socket
### cw_evm/lib/hardware/evm_chain_bitbox_credentials.dart
@@ -1,23 +1,25 @@
-import 'dart:async';
-import 'dart:typed_data';
+import "dart:async";
+import "dart:typed_data";
-import 'package:bitbox_flutter/bitbox_manager.dart';
-import 'package:cw_core/hardware/device_not_connected_exception.dart' as exception;
-import 'package:web3dart/crypto.dart';
-import 'package:web3dart/web3dart.dart';
+import "package:bitbox_flutter/bitbox_flutter.dart";
+import "package:cw_core/hardware/device_not_connected_exception.dart" as exception;
+import "package:web3dart/crypto.dart";
+import "package:web3dart/web3dart.dart";
class EvmBitboxCredentials extends CredentialsWithKnownAddress {
- final String _address;
+ EvmBitboxCredentials(this._address);
- BitboxManager? bitboxManager;
+ BitboxConnection? bitboxManager;
String? derivationPath;
+ final String _address;
- EvmBitboxCredentials(this._address);
+ BitboxEthereum _getEthereum(int? chainId) =>
+ BitboxEthereum(bitboxManager!.ffi, chainId: chainId ?? 1);
@override
EthereumAddress get address => EthereumAddress.fromHex(_address);
- void setBitbox(BitboxManager connection, [String? derivationPath_]) {
+ void setBitbox(BitboxConnection connection, [String? derivationPath_]) {
bitboxManager = connection;
derivationPath = derivationPath_ ?? "m/44'/60'/0'/0/0";
}
@@ -27,15 +29,20 @@ class EvmBitboxCredentials extends CredentialsWithKnownAddress {
throw UnimplementedError("EvmLedgerCredentials.signToEcSignature");
@override
- Future<MsgSignature> signToSignature(Uint8List payload,
- {int? chainId, bool isEIP1559 = false}) async {
+ Future<MsgSignature> signToSignature(
+ Uint8List payload, {
+ int? chainId,
+ bool isEIP1559 = false,
+ }) async {
if (bitboxManager == null) {
throw exception.DeviceNotConnectedException();
}
- if (isEIP1559) payload = payload.sublist(1);
- final sig = await bitboxManager!
- .signETHRLPTransaction(chainId ?? 1, derivationPath!, bytesToHex(payload), isEIP1559);
+ if (isEIP1559) {
+ payload = payload.sublist(1);
+ }
+ final sig = await _getEthereum(chainId)
+ .signRLPTransaction(derivationPath!, bytesToHex(payload), isEIP1559);
final r = bytesToHex(sig.sublist(0, 32));
final s = bytesToHex(sig.sublist(32, 32 + 32));
@@ -66,9 +73,11 @@ class EvmBitboxCredentials extends CredentialsWithKnownAddress {
}
@override
- Future<Uint8List> signPersonalMessage(Uint8List payload, {int? chainId}) async {
- if (isNotConnected) throw exception.DeviceNotConnectedException();
- return await bitboxManager!.signETHMessage(chainId ?? 1, derivationPath!, payload);
+ Future<Uint8List> signPersonalMessage(Uint8List payload, {int? chainId}) {
+ if (isNotConnected) {
+ throw exception.DeviceNotConnectedException();
+ }
+ return _getEthereum(chainId).signMessage(derivationPath!, payload);
}
@override
### cw_evm/lib/hardware/evm_chain_bitbox_service.dart
@@ -1,13 +1,13 @@
-import 'dart:async';
+import "dart:async";
-import 'package:bitbox_flutter/bitbox_manager.dart';
-import 'package:cw_core/hardware/hardware_account_data.dart';
-import 'package:cw_core/hardware/hardware_wallet_service.dart';
+import "package:bitbox_flutter/bitbox_flutter.dart";
+import "package:cw_core/hardware/hardware_account_data.dart";
+import "package:cw_core/hardware/hardware_wallet_service.dart";
class EVMChainBitboxService extends HardwareWalletService {
EVMChainBitboxService(this.manager, {this.chainId = 1});
- final BitboxManager manager;
+ final BitboxConnection manager;
final int chainId;
@override
@@ -17,13 +17,16 @@ class EVMChainBitboxService extends HardwareWalletService {
for (final i in indexRange) {
final derivationPath = "m/44'/60'/0'/0/$i";
- final address = await manager.getETHAddress(chainId, derivationPath);
+ final address =
+ await BitboxEthereum(manager.ffi, chainId: chainId).getAddress(derivationPath);
- accounts.add(HardwareAccountData(
- address: address,
- accountIndex: i,
- derivationPath: derivationPath,
- ));
+ accounts.add(
+ HardwareAccountData(
+ address: address,
+ accountIndex: i,
+ derivationPath: derivationPath,
+ ),
+ );
}
return accounts;
### cw_evm/pubspec.yaml
@@ -33,7 +33,9 @@ dependencies:
path: packages/ledger-ethereum
ref: f4761cd5171d4c1e2e42fd3298261650539fb2db
bitbox_flutter:
- path: ../scripts/bitbox_flutter
+ git:
+ url: https://github.com/cake-tech/bitbox_flutter.git
+ ref: 3d1c607f14c6d5bace2971ec4c10b5201053cc56
trezor_connect:
git:
url: https://github.com/cake-tech/trezor_connect
### docs/builds/ANDROID.md
@@ -25,9 +25,6 @@ git config --global --add safe.directory '*'
pushd scripts/android
./build_torch.sh # optional: this will fail on case-insensitive fs and will add extra few hours to the build process, without this embedded tor will not work.
./build_reown_deps.sh
- pushd ..
- ./build_bitbox_flutter.sh
- popd
source ./app_env.sh cakewallet
# source ./app_env.sh monero.com # Uncomment this line to build monero.com
./app_config.sh
### docs/builds/LINUX.md
@@ -30,7 +30,6 @@ pushd scripts
./prepare_torch.sh
./prepare_zcash.sh
./prepare_reown.sh
- ./build_bitbox_flutter.sh
pushd android
./build_mwebd.sh
popd
### lib/bitcoin/cw_bitcoin.dart
@@ -554,7 +554,7 @@ class CWBitcoin extends Bitcoin {
@override
HardwareWalletService getBitboxHardwareWalletService(
- bitbox.BitboxManager manager, bool isBitcoin) {
+ bitbox.BitboxConnection manager, bool isBitcoin) {
if (isBitcoin) return BitcoinBitboxService(manager);
return LitecoinBitboxService(manager);
}
### lib/entities/hardware_wallet/hardware_wallet_device.dart
@@ -1,6 +1,6 @@
-import 'package:bitbox_flutter/usb/bitbox_device.dart' as bitbox;
-import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
-import 'package:trezor_flutter/trezor_flutter.dart' as trezor;
+import "package:bitbox_flutter/bitbox_flutter.dart" as bitbox;
+import "package:ledger_flutter_plus/ledger_flutter_plus.dart" as ledger;
+import "package:trezor_flutter/trezor_flutter.dart" as trezor;
abstract class HardwareWalletDevice {
String get name;
@@ -11,10 +11,10 @@ abstract class HardwareWalletDevice {
}
class LedgerHardwareWalletDevice extends HardwareWalletDevice {
- final ledger.LedgerDevice device;
-
LedgerHardwareWalletDevice(this.device);
+ final ledger.LedgerDevice device;
+
@override
String get name => device.name;
@@ -26,27 +26,28 @@ class LedgerHardwareWalletDevice extends HardwareWalletDevice {
}
class BitboxHardwareWalletDevice extends HardwareWalletDevice {
- final bitbox.BitboxDevice device;
-
BitboxHardwareWalletDevice(this.device);
+ final bitbox.BitboxDevice device;
+
@override
String get name => device.productName;
@override
HardwareWalletDeviceType get type => name.contains("BitBox02 Nova")
- ? HardwareWalletDeviceType.BitBox02Nova
- : HardwareWalletDeviceType.BitBox02;
+ ? HardwareWalletDeviceType.bitBox02Nova
+ : HardwareWalletDeviceType.bitBox02;
@override
- HardwareWalletConnectionType get connectionType => HardwareWalletConnectionType.usb;
+ HardwareWalletConnectionType get connectionType =>
+ device.isUsb ? HardwareWalletConnectionType.usb : HardwareWalletConnectionType.ble;
}
class TrezorHardwareWalletDevice extends HardwareWalletDevice {
- final trezor.TrezorDevice device;
-
TrezorHardwareWalletDevice(this.device);
+ final trezor.TrezorDevice device;
+
@override
String get name => device.name;
@@ -65,8 +66,8 @@ enum HardwareWalletDeviceType {
ledgerNanoGen5,
ledgerStax,
ledgerFlex,
- BitBox02,
- BitBox02Nova,
+ bitBox02,
+ bitBox02Nova,
trezorModelOne,
trezorModelT,
trezorSafe3,
### lib/evm/cw_evm.dart
@@ -341,7 +341,7 @@ class CWEVM extends EVM {
EVMChainLedgerService(connection);
@override
- HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager) =>
+ HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxConnection manager) =>
EVMChainBitboxService(manager);
@override
### lib/new-ui/widgets/coins_page/wallet_info.dart
@@ -1,7 +1,7 @@
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
-import 'package:cw_core/wallet_info.dart';
-import 'package:flutter/material.dart';
+import "package:cake_wallet/generated/i18n.dart";
+import "package:cake_wallet/src/widgets/cake_image_widget.dart";
+import "package:cw_core/wallet_info.dart";
+import "package:flutter/material.dart";
class WalletInfoBar extends StatelessWidget {
const WalletInfoBar({required this.name, required this.hardwareWalletType, super.key});
@@ -30,16 +30,18 @@ class WalletInfoBar extends StatelessWidget {
),
child: hardwareWalletIcon == null
? const SizedBox.shrink(key: ValueKey("empty"))
- : Padding(
- padding: const EdgeInsets.only(right: 8),
- child: CakeImageWidget(
- imageUrl: hardwareWalletIcon!,
- key: const ValueKey("hardware_wallet_icon"),
- width: 24,
- height: 24,
- colorFilter: ColorFilter.mode(
- Theme.of(context).colorScheme.onSurfaceVariant,
- BlendMode.srcIn,
+ : Center(
+ child: Padding(
+ padding: const EdgeInsets.only(right: 8),
+ child: CakeImageWidget(
+ imageUrl: hardwareWalletIcon,
+ key: const ValueKey("hardware_wallet_icon"),
+ width: 24,
+ height: 24,
+ colorFilter: ColorFilter.mode(
+ Theme.of(context).colorScheme.onSurfaceVariant,
+ BlendMode.srcIn,
+ ),
),
),
),
### lib/new-ui/widgets/hardware_wallet/bitbox_paring_sheet.dart
@@ -0,0 +1,78 @@
+import "package:cake_wallet/generated/i18n.dart";
+import "package:cake_wallet/new-ui/widgets/new_primary_button.dart";
+import "package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart";
+import "package:flutter/material.dart";
+
+class HardwareWalletBitboxParingSheet extends StatelessWidget {
+ const HardwareWalletBitboxParingSheet({required this.paringCode, super.key});
+
+ final String paringCode;
+
+ @override
+ Widget build(BuildContext context) => SafeArea(
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: const BorderRadius.vertical(top: Radius.circular(18)),
+ color: Theme.of(context).colorScheme.surface,
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ ModalTopBar(
+ title: S.of(context).pairing_code,
+ onLeadingPressed: () => Navigator.of(context).pop(false),
+ onTrailingPressed: () {},
+ leadingIcon: const Icon(Icons.close),
+ leadingSemanticLabel: S.of(context).close,
+ ),
+ Padding(
+ padding: const EdgeInsets.all(18),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ spacing: 12,
+ children: [
+ const SizedBox(),
+ Text(
+ S.of(context).pairing_code_bitbox_confirm,
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 14,
+ color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
+ ),
+ ),
+ Container(
+ padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 16),
+ decoration: BoxDecoration(
+ color: Theme.of(context).colorScheme.surfaceContainer,
+ borderRadius: BorderRadius.circular(16),
+ ),
+ child: SelectableText(
+ paringCode,
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 20,
+ height: 1.5,
+ fontWeight: FontWeight.w600,
+ fontFamily: "IBM Plex Mono",
+ letterSpacing: 2,
+ color: Theme.of(context).colorScheme.onSurface,
+ ),
+ ),
+ ),
+ const SizedBox(),
+ NewPrimaryButton(
+ text: S.of(context).continue_text,
+ onPressed: () => Navigator.of(context).pop(true),
+ color: Theme.of(context).colorScheme.primary,
+ textColor: Theme.of(context).colorScheme.onPrimary,
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+}
### lib/src/screens/connect_device/connect_device_page.dart
@@ -235,8 +235,8 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
return "assets/new-ui/hardware_wallets/device_ledger_stax.svg";
case HardwareWalletDeviceType.ledgerFlex:
return "assets/new-ui/hardware_wallets/device_ledger_flex.svg";
- case HardwareWalletDeviceType.BitBox02:
- case HardwareWalletDeviceType.BitBox02Nova:
+ case HardwareWalletDeviceType.bitBox02:
+ case HardwareWalletDeviceType.bitBox02Nova:
return "assets/new-ui/hardware_wallets/device_bitbox.svg";
case HardwareWalletDeviceType.trezorModelOne:
return "assets/new-ui/hardware_wallets/device_trezor_model_one.svg";
### lib/src/screens/connect_device/select_device_manufacturer_page.dart
@@ -1,18 +1,20 @@
-import 'dart:io';
-
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/src/screens/base_page.dart';
-import 'package:cake_wallet/src/screens/connect_device/widgets/dotted_divider.dart';
-import 'package:cake_wallet/src/screens/connect_device/widgets/manufacturer_option_tile.dart';
-import 'package:cake_wallet/utils/permission_handler.dart';
-import 'package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart';
-import 'package:cw_core/utils/print_verbose.dart';
-import 'package:cw_core/wallet_info.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import 'package:fluttertoast/fluttertoast.dart';
-import 'package:permission_handler/permission_handler.dart';
+import "dart:io";
+
+import "package:cake_wallet/generated/i18n.dart";
+import "package:cake_wallet/routes.dart";
+import "package:cake_wallet/src/screens/base_page.dart";
+import "package:cake_wallet/src/screens/connect_device/widgets/dotted_divider.dart";
+import "package:cake_wallet/src/screens/connect_device/widgets/manufacturer_option_tile.dart";
+import "package:cake_wallet/src/widgets/cake_image_widget.dart";
+import "package:cake_wallet/utils/device_info.dart";
+import "package:cake_wallet/utils/permission_handler.dart";
+import "package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart";
+import "package:cake_wallet/wallet_type_utils.dart";
+import "package:cw_core/utils/print_verbose.dart";
+import "package:cw_core/wallet_info.dart";
+import "package:flutter/material.dart";
+import "package:fluttertoast/fluttertoast.dart";
+import "package:permission_handler/permission_handler.dart";
class SelectDeviceManufacturerPage extends BasePage {
SelectDeviceManufacturerPage({
@@ -34,52 +36,50 @@ class SelectDeviceManufacturerPage extends BasePage {
ColorFilter get _colorFilter =>
ColorFilter.mode(currentTheme.colorScheme.onSurface, BlendMode.srcIn);
- List<_DeviceManufacturer> get availableManufacturers => [
+ List<_DeviceManufacturer> get _availableManufacturers => [
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/ledger_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/ledger_man.svg",
height: 25,
colorFilter: _colorFilter,
),
hardwareWalletType: HardwareWalletType.ledger,
),
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/trezor_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/trezor_man.svg",
height: 25,
colorFilter: _colorFilter,
),
hardwareWalletType: HardwareWalletType.trezor,
// tag: S.current.new_tag,
),
- if (Platform.isAndroid) ...[
+ if (DeviceInfo.instance.isMobile && !isMoneroOnly) ...[
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/bitbox_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/bitbox_man.svg",
height: 25,
colorFilter: _colorFilter,
),
hardwareWalletType: HardwareWalletType.bitbox,
- // tag: S.current.new_tag,
+ tag: Platform.isIOS ? S.current.new_tag : null,
),
],
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/cupcake_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/cupcake_man.svg",
height: 25,
colorFilter: _colorFilter,
),
hardwareWalletType: HardwareWalletType.cupcake,
- // tag: S.current.new_tag,
),
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/coldcard_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/coldcard_man.svg",
height: 25,
colorFilter: _colorFilter,
),
hardwareWalletType: HardwareWalletType.coldcard,
- // tag: S.current.new_tag,
),
// _DeviceManufacturer(
// image: SvgPicture.asset(
@@ -91,43 +91,34 @@ class SelectDeviceManufacturerPage extends BasePage {
// tag: S.current.new_tag,
// ),
]
- .where((e) => availableHardwareWalletTypes == null
- ? ![HardwareWalletType.cupcake].contains(e.hardwareWalletType)
- : availableHardwareWalletTypes!.contains(e.hardwareWalletType))
+ .where(
+ (e) => availableHardwareWalletTypes == null
+ ? ![HardwareWalletType.cupcake].contains(e.hardwareWalletType)
+ : availableHardwareWalletTypes!.contains(e.hardwareWalletType),
+ )
.toList();
- List<_DeviceManufacturer> get comingManufacturers => [
- if (!Platform.isAndroid) ...[
- _DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/bitbox_man.svg',
- height: 25,
- colorFilter: _colorFilter,
- ),
- hardwareWalletType: HardwareWalletType.bitbox,
- tag: S.current.coming_soon_tag,
- ),
- ],
+ List<_DeviceManufacturer> get _comingManufacturers => [
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/seedsigner_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/seedsigner_man.svg",
height: 25,
colorFilter: _colorFilter,
),
hardwareWalletType: HardwareWalletType.seedsigner,
tag: S.current.coming_soon_tag,
),
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/foundation_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/foundation_man.svg",
height: 25,
colorFilter: _colorFilter,
),
tag: S.current.coming_soon_tag,
),
_DeviceManufacturer(
- image: SvgPicture.asset(
- 'assets/images/hardware_wallet/keystone_man.svg',
+ image: CakeImageWidget(
+ imageUrl: "assets/images/hardware_wallet/keystone_man.svg",
height: 25,
colorFilter: _colorFilter,
),
@@ -136,56 +127,57 @@ class SelectDeviceManufacturerPage extends BasePage {
];
@override
- Widget body(BuildContext context) => Container(
- child: Center(
- child: Container(
- padding: EdgeInsets.only(left: 24, right: 24),
- height: double.infinity,
- child: SingleChildScrollView(
- child: Column(
- children: [
- ...availableManufacturers.map(
+ Widget body(BuildContext context) => Center(
+ child: Container(
+ padding: const EdgeInsets.only(left: 24, right: 24),
+ height: double.infinity,
+ child: SingleChildScrollView(
+ child: Column(
+ children: [
+ ..._availableManufacturers.map(
+ (manufacturer) => Padding(
+ padding: const EdgeInsets.only(top: 10),
+ child: ManufacturerOptionTile(
+ image: manufacturer.image,
+ tag: manufacturer.tag,
+ onPressed: () {
+ if (onSelect != null) {
+ return onSelect!.call(context, manufacturer.hardwareWalletType!);
+ }
+
+ if (isAirgappedWallet(manufacturer.hardwareWalletType)) {
+ _onScanQRCode(context, manufacturer.hardwareWalletType!);
+ } else if (manufacturer.hardwareWalletType != null) {
+ Navigator.pushNamed(
+ context,
+ Routes.connectHardwareWallet,
+ arguments: [manufacturer.hardwareWalletType],
+ );
+ }
+ },
+ ),
+ ),
+ ),
+ if (showUnavailable) ...[
+ Padding(
+ padding: const EdgeInsets.only(top: 20, bottom: 10),
+ child: DottedDivider(color: Theme.of(context).colorScheme.surfaceContainer),
+ ),
+ ..._comingManufacturers.map(
(manufacturer) => Padding(
- padding: EdgeInsets.only(top: 10),
+ padding: const EdgeInsets.only(top: 10),
child: ManufacturerOptionTile(
image: manufacturer.image,
tag: manufacturer.tag,
- onPressed: () {
- if (onSelect != null)
- return onSelect!.call(context, manufacturer.hardwareWalletType!);
-
- if (isAirgappedWallet(manufacturer.hardwareWalletType)) {
- _onScanQRCode(context, manufacturer.hardwareWalletType!);
- } else if (manufacturer.hardwareWalletType != null) {
- Navigator.pushNamed(context, Routes.connectHardwareWallet,
- arguments: [manufacturer.hardwareWalletType]);
- }
- },
+ onPressed: () =>
+ Fluttertoast.showToast(msg: "One more tap and it might work"),
+ // Ester egg
+ isUnavailable: true,
),
),
),
- if (showUnavailable) ...[
- Padding(
- padding: EdgeInsets.only(top: 20, bottom: 10),
- child: DottedDivider(color: Theme.of(context).colorScheme.surfaceContainer),
- ),
- ...comingManufacturers.map(
- (manufacturer) => Padding(
- padding: EdgeInsets.only(top: 10),
- child: ManufacturerOptionTile(
- image: manufacturer.image,
- tag: manufacturer.tag,
- onPressed: () =>
- Fluttertoast.showToast(msg: 'One more tap and it might work'),
- // Ester egg
-
- isUnavailable: true,
- ),
- ),
- ),
- ]
],
- ),
+ ],
),
),
),
@@ -204,18 +196,22 @@ class SelectDeviceManufacturerPage extends BasePage {
final isCameraPermissionGranted =
await PermissionHandler.checkPermission(Permission.camera, context);
- if (!isCameraPermissionGranted) return;
+ if (!isCameraPermissionGranted) {
+ return;
+ }
try {
- if (isRestoring) return;
+ if (isRestoring) {
+ return;
+ }
isRestoring = true;
final restoredWallet = await WalletRestoreFromQRCode.scanQRCodeForRestoring(context);
final params = {
- 'walletType': restoredWallet.type,
- 'restoredWallet': restoredWallet,
- 'hardwareWalletType': type,
+ "walletType": restoredWallet.type,
+ "restoredWallet": restoredWallet,
+ "hardwareWalletType": type,
};
Navigator.pushNamed(context, Routes.restoreWallet, arguments: params)
@@ -227,9 +223,9 @@ class SelectDeviceManufacturerPage extends BasePage {
}
class _DeviceManufacturer {
- final SvgPicture image;
+ const _DeviceManufacturer({required this.image, this.hardwareWalletType, this.tag});
+
+ final CakeImageWidget image;
final HardwareWalletType? hardwareWalletType;
final String? tag;
-
- _DeviceManufacturer({required this.image, this.hardwareWalletType, this.tag});
}
### lib/view_model/hardware_wallet/bitbox_view_model.dart
@@ -2,18 +2,22 @@ import "dart:async";
import "dart:io";
import "package:bitbox_flutter/bitbox_flutter.dart" as sdk;
+import "package:bitbox_flutter/ffi/bitbox_ffi.dart";
import "package:cake_wallet/bitcoin/bitcoin.dart";
import "package:cake_wallet/entities/hardware_wallet/hardware_wallet_device.dart";
import "package:cake_wallet/evm/evm.dart";
+import "package:cake_wallet/main.dart";
+import "package:cake_wallet/new-ui/widgets/hardware_wallet/bitbox_paring_sheet.dart";
import "package:cake_wallet/view_model/hardware_wallet/hardware_wallet_view_model.dart";
import "package:cake_wallet/wallet_type_utils.dart";
import "package:cw_core/exceptions/cake_exception.dart";
import "package:cw_core/hardware/hardware_wallet_service.dart";
-import "package:cw_core/root_dir.dart";
import "package:cw_core/utils/print_verbose.dart";
import "package:cw_core/wallet_base.dart";
import "package:cw_core/wallet_info.dart";
import "package:cw_core/wallet_type.dart";
+import "package:flutter/material.dart";
+import "package:ledger_flutter_plus/ledger_flutter_plus.dart" show UniversalBle, AvailabilityState;
import "package:mobx/mobx.dart";
part "bitbox_view_model.g.dart";
@@ -22,15 +26,24 @@ class BitboxViewModel = BitboxViewModelBase with _$BitboxViewModel;
abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
BitboxViewModelBase() {
- if (!Platform.isIOS && !isMoneroOnly) {
- bitboxManager = sdk.BitboxManager();
+ if (!isMoneroOnly) {
+ reaction((_) => isBleEnabled, (_) {
+ if (isBleEnabled && hasBluetooth) {
+ _initBLE();
+ }
+ });
+
+ if (!Platform.isIOS) {
+ usbManager = sdk.BitboxUsbConnectionManager();
+ }
}
}
- late final sdk.BitboxManager bitboxManager;
+ late final sdk.BitboxConnectionManager bleManager;
+ late final sdk.BitboxUsbConnectionManager usbManager;
- BitboxHardwareWalletDevice? _connectedDevice;
- Timer? _isConnectedTimer;
+ sdk.BitboxConnection? _connection;
+ StreamSubscription<sdk.BitboxConnectionStatus>? _statusChanges;
@override
HardwareWalletType get hardwareWalletType => HardwareWalletType.bitbox;
@@ -44,20 +57,45 @@ abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
bool isConnecting = false;
@override
- bool get hasBluetooth => Platform.isIOS && false; // TODO(Konsti): remove when we enable bluetooth
+ bool get hasBluetooth => Platform.isIOS;
+
+ bool _bleIsInitialized = false;
+
+ Future<void> _initBLE() async {
+ if (isBleEnabled && !_bleIsInitialized) {
+ bleManager = sdk.BitboxBleConnectionManager();
+ _bleIsInitialized = true;
+ }
+ }
@override
- Future<void> updateBleState() async {}
+ Future<void> updateBleState() async {
+ final bleState = await UniversalBle.getBluetoothAvailabilityState();
+
+ final newState = bleState == AvailabilityState.poweredOn;
+
+ if (newState != isBleEnabled) {
+ isBleEnabled = newState;
+ }
+ }
@override
- Stream<HardwareWalletDevice> scanForBleDevices() => throw UnimplementedError();
+ Stream<HardwareWalletDevice> scanForBleDevices() =>
+ bleManager.scan().map(BitboxHardwareWalletDevice.new);
@override
- Future<List<HardwareWalletDevice>> getAllUsbDevices() => bitboxManager.devices
+ Future<List<HardwareWalletDevice>> getAllUsbDevices() => usbManager.currentDevices
.then((devices) => devices.map(BitboxHardwareWalletDevice.new).toList());
@override
- Future<void> stopScanning() async {}
+ Future<void> stopScanning() async {
+ if (_bleIsInitialized) {
+ await bleManager.stopScan();
+ }
+ if (!Platform.isIOS) {
+ await usbManager.stopScan();
+ }
+ }
@override
@action
@@ -70,53 +108,85 @@ abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
}
isConnecting = true;
+ StreamSubscription<BitboxEvent>? events;
try {
- final appDocDir = await getAppDir();
-
- await bitboxManager.connect(device.device);
- printV("Got Connection", file: "${appDocDir.path}/error.txt");
- await bitboxManager.initBitBox();
- printV("Bitbox initialized!", file: "${appDocDir.path}/error.txt");
- await bitboxManager.channelHashVerify();
- printV("Bitbox channel-hash verified!", file: "${appDocDir.path}/error.txt");
-
- _connectedDevice = device;
- _isConnectedTimer = Timer.periodic(const Duration(seconds: 1), (_) => _isStillConnected());
+ final bitBoxManager =
+ device.connectionType == HardwareWalletConnectionType.ble ? bleManager : usbManager;
+
+ _connection = await bitBoxManager.connect(device.device);
+
+ final channelHashVerified = Completer<bool>();
+ events = bitBoxManager.events.listen((event) async {
+ printV(event.event);
+ if (event.event == "channelHashChanged" &&
+ event.channelHash.isNotEmpty &&
+ !event.channelHashVerified) {
+ final verifiedChannelHash = await showModalBottomSheet<bool?>(
+ context: navigatorKey.currentContext!,
+ isScrollControlled: true,
+ isDismissible: false,
+ enableDrag: false,
+ useSafeArea: true,
+ builder: (_) => HardwareWalletBitboxParingSheet(paringCode: event.channelHash),
+ );
+
+ if (!channelHashVerified.isCompleted) {
+ channelHashVerified.complete(verifiedChannelHash ?? false);
+ }
+ }
+ });
+
+ await _connection!.initBitBox();
+
+ final isChannelHashVerified = await channelHashVerified.future;
+
+ if (isChannelHashVerified) {
+ await _connection!.channelHashVerify();
+ } else {
+ isConnecting = false;
+ unawaited(disconnect());
+ return false;
+ }
+
+ _statusChanges = _connection?.statusChanges.listen((e) {
+ if (e == sdk.BitboxConnectionStatus.disconnected) {
+ unawaited(disconnect());
+ }
+ });
isConnecting = false;
return true;
} catch (e) {
+ unawaited(disconnect());
printV(e);
+ } finally {
+ unawaited(events?.cancel());
+ isConnecting = false;
}
- isConnecting = false;
- _connectedDevice = null;
- _isConnectedTimer?.cancel();
- _isConnectedTimer = null;
return false;
}
- @override
- bool isConnected(WalletType type) => _connectedDevice != null;
-
- Future<void> _isStillConnected() async {
- final devices = await getAllUsbDevices();
-
- if (!devices.any((d) => d.name == _connectedDevice?.name)) {
- _connectedDevice = null;
- _isConnectedTimer?.cancel();
- _isConnectedTimer = null;
- }
+ Future<void> disconnect() async {
+ try {
+ await _connection?.disconnect();
+ await _statusChanges?.cancel();
+ } catch (_) {}
+ _connection = null;
+ _statusChanges = null;
}
+ @override
+ bool isConnected(WalletType type) => _connection != null;
+
@override
HardwareWalletService getHardwareWalletService(WalletType type) {
switch (type) {
case WalletType.bitcoin:
- return bitcoin!.getBitboxHardwareWalletService(bitboxManager, true);
+ return bitcoin!.getBitboxHardwareWalletService(_connection!, true);
case WalletType.litecoin:
- return bitcoin!.getBitboxHardwareWalletService(bitboxManager, false);
+ return bitcoin!.getBitboxHardwareWalletService(_connection!, false);
case WalletType.ethereum:
case WalletType.polygon:
- return evm!.getBitboxHardwareWalletService(bitboxManager);
+ return evm!.getBitboxHardwareWalletService(_connection!);
default:
throw UnimplementedError();
}
@@ -127,13 +197,15 @@ abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
switch (wallet.type) {
case WalletType.bitcoin:
case WalletType.litecoin:
- return bitcoin!
- .setHardwareWalletService(wallet, getHardwareWalletService(wallet.type));
+ return bitcoin!.setHardwareWalletService(wallet, getHardwareWalletService(wallet.type));
case WalletType.ethereum:
case WalletType.polygon:
return evm!.setHardwareWalletService(wallet, getHardwareWalletService(wallet.type));
default:
- throw BadWalletTypeException('Unexpected wallet type: ${wallet.type} for bitbox', wallet.type);
+ throw BadWalletTypeException(
+ "Unexpected wallet type: ${wallet.type} for bitbox",
+ wallet.type,
+ );
}
}
}
### pubspec.lock
@@ -209,10 +209,12 @@ packages:
bitbox_flutter:
dependency: "direct main"
description:
- path: "scripts/bitbox_flutter"
- relative: true
- source: path
- version: "0.0.1"
+ path: "."
+ ref: "3d1c607f14c6d5bace2971ec4c10b5201053cc56"
+ resolved-ref: "3d1c607f14c6d5bace2971ec4c10b5201053cc56"
+ url: "https://github.com/cake-tech/bitbox_flutter.git"
+ source: git
+ version: "0.1.0"
bitcoin_base:
dependency: "direct overridden"
description:
@@ -3491,5 +3493,5 @@ packages:
source: git
version: "6.31.0"
sdks:
- dart: ">=3.9.0 <4.0.0"
+ dart: ">=3.10.0 <4.0.0"
flutter: ">=3.19.0"
### pubspec_base.yaml
@@ -134,7 +134,9 @@ dependencies:
ref: 591d4b8c821b9c10561f848b866324a9a8dcb489
path: trezor-flutter
bitbox_flutter:
- path: ./scripts/bitbox_flutter
+ git:
+ url: https://github.com/cake-tech/bitbox_flutter.git
+ ref: 3d1c607f14c6d5bace2971ec4c10b5201053cc56
hashlib: 1.19.2
on_chain:
git:
### res/values/strings_ar.arb
@@ -802,6 +802,7 @@
"overshot": "تجاوز الحد",
"overwrite_amount": "استبدال المبلغ",
"pairing_code": "رمز الإقران",
+ "pairing_code_bitbox_confirm": "تأكد من أن الرمز أدناه يطابق الرمز المعروض على جهاز BitBox الخاص بك",
"pairing_code_desc_1": "سيعرض جهازك رمز إقران.",
"pairing_code_desc_2": "أدخله هنا للمتابعة",
"pairing_error": "خطأ في الإقران",
### res/values/strings_bg.arb
@@ -802,6 +802,7 @@
"overshot": "Надвишено",
"overwrite_amount": "Презапиши сумата",
"pairing_code": "Код за сдвояване",
+ "pairing_code_bitbox_confirm": "Потвърдете, че кодът по-долу съвпада с този, показан на вашия BitBox",
"pairing_code_desc_1": "Вашето устройство ще покаже код за сдвояване.",
"pairing_code_desc_2": "Въведете го тук, за да продължите",
"pairing_error": "Грешка при сдвояване",
### res/values/strings_cs.arb
@@ -802,6 +802,7 @@
"overshot": "Přestřelení",
"overwrite_amount": "Přepsat částku",
"pairing_code": "Párovací kód",
+ "pairing_code_bitbox_confirm": "Ověřte, že níže uvedený kód odpovídá kódu zobrazenému na vašem BitBoxu",
"pairing_code_desc_1": "Vaše zařízení zobrazí párovací kód.",
"pairing_code_desc_2": "Zadejte ho zde a pokračujte",
"pairing_error": "Chyba párování",
### res/values/strings_de.arb
@@ -848,6 +848,7 @@
"overshot": "Überschuss",
"overwrite_amount": "Betrag überschreiben",
"pairing_code": "Kopplungscode",
+ "pairing_code_bitbox_confirm": "Bestätigen Sie, dass der untenstehende Code mit dem auf Ihrer BitBox angezeigten übereinstimmt",
"pairing_code_desc_1": "Ihr Gerät zeigt einen Kopplungscode an.",
"pairing_code_desc_2": "Geben Sie ihn hier ein, um fortzufahren",
"pairing_error": "Kopplungsfehler",
### res/values/strings_en.arb
@@ -848,6 +848,7 @@
"overshot": "Overshot",
"overwrite_amount": "Overwrite amount",
"pairing_code": "Pairing Code",
+ "pairing_code_bitbox_confirm": "Confirm that the code below matches the one shown on your BitBox",
"pairing_code_desc_1": "Your device will show a pairing code.",
"pairing_code_desc_2": "Input here to continue",
"pairing_error": "Pairing Error",
### res/values/strings_es.arb
@@ -802,6 +802,7 @@
"overshot": "Excedido",
"overwrite_amount": "Sobrescribir monto",
"pairing_code": "Código de emparejamiento",
+ "pairing_code_bitbox_confirm": "Confirma que el código de abajo coincide con el que se muestra en tu BitBox",
"pairing_code_desc_1": "Tu dispositivo mostrará un código de emparejamiento.",
"pairing_code_desc_2": "Introdúcelo aquí para continuar",
"pairing_error": "Error de emparejamiento",
### res/values/strings_fa.arb
@@ -802,6 +802,7 @@
"overshot": "فراتر رفت",
"overwrite_amount": "بازنویسی مقدار",
"pairing_code": "کد جفتسازی",
+ "pairing_code_bitbox_confirm": "تأیید کنید که کد زیر با کدی که روی BitBox شما نمایش داده میشود مطابقت دارد",
"pairing_code_desc_1": "دستگاه شما یک کد جفتسازی نمایش میدهد.",
"pairing_code_desc_2": "برای ادامه، اینجا وارد کنید",
"pairing_error": "خطای جفتسازی",
### res/values/strings_fr.arb
@@ -802,6 +802,7 @@
"overshot": "Dépassement",
"overwrite_amount": "Écraser le montant",
"pairing_code": "Code de jumelage",
+ "pairing_code_bitbox_confirm": "Confirmez que le code ci-dessous correspond à celui affiché sur votre BitBox",
"pairing_code_desc_1": "Votre appareil affichera un code de jumelage.",
"pairing_code_desc_2": "Saisissez-le ici pour continuer",
"pairing_error": "Erreur de jumelage",
### res/values/strings_gn.arb
@@ -801,6 +801,7 @@
"overshot": "Ohasa hetave (overshot)",
"overwrite_amount": "Embyekovia hetakue",
"pairing_code": "Pairing Código",
+ "pairing_code_bitbox_confirm": "Ehechauka pe código oĩva yvy gotyo ojoja pe ojehechaukáva ne BitBox-pe",
"pairing_code_desc_1": "Ne mba'e'oka ohechaukáta peteĩ pairing código.",
"pairing_code_desc_2": "Emoinge ko'ápe resegí hag̃ua",
"pairing_error": "Pairing Jejavy",
### res/values/strings_ha.arb
@@ -804,6 +804,7 @@
"overshot": "Overshot",
"overwrite_amount": "Maye gurbin adadi",
"pairing_code": "Lambar haɗawa (pairing)",
+ "pairing_code_bitbox_confirm": "Tabbatar cewa lambar da ke ƙasa ta yi daidai da wadda aka nuna a kan BitBox ɗinka",
"pairing_code_desc_1": "Na'urarka za ta nuna lambar haɗawa (pairing).",
"pairing_code_desc_2": "Shigar da ita a nan don ci gaba",
"pairing_error": "Kuskuren haɗawa (pairing)",
### res/values/strings_hi.arb
@@ -802,6 +802,7 @@
"overshot": "लक्ष्य से अधिक हो गया",
"overwrite_amount": "राशि ओवरराइट करें",
"pairing_code": "पेयरिंग कोड",
+ "pairing_code_bitbox_confirm": "पुष्टि करें कि नीचे दिया गया कोड आपके BitBox पर दिखाए गए कोड से मेल खाता है",
"pairing_code_desc_1": "आपका डिवाइस एक पेयरिंग कोड दिखाएगा।",
"pairing_code_desc_2": "जारी रखने के लिए यहाँ दर्ज करें",
"pairing_error": "पेयरिंग त्रुटि",
### res/values/strings_hr.arb
@@ -802,6 +802,7 @@
"overshot": "Prekoračeno",
"overwrite_amount": "Prepiši iznos",
"pairing_code": "Kod za uparivanje",
+ "pairing_code_bitbox_confirm": "Potvrdite da se kôd ispod podudara s onim prikazanim na vašem BitBoxu",
"pairing_code_desc_1": "Vaš će uređaj prikazati kod za uparivanje.",
"pairing_code_desc_2": "Unesite ga ovdje za nastavak",
"pairing_error": "Pogreška pri uparivanju",
### res/values/strings_hy.arb
@@ -802,6 +802,7 @@
"overshot": "Գերազանցել է",
"overwrite_amount": "Վերագրել գումարը",
"pairing_code": "Զուգակցման կոդ",
+ "pairing_code_bitbox_confirm": "Հաստատեք, որ ստորև նշված կոդը համընկնում է ձեր BitBox-ում ցուցադրվածի հետ",
"pairing_code_desc_1": "Ձեր սարքը ցույց կտա զուգակցման կոդ։",
"pairing_code_desc_2": "Մուտքագրեք այստեղ՝ շարունակելու համար",
"pairing_error": "Զուգակցման սխալ",
### res/values/strings_id.arb
@@ -804,6 +804,7 @@
"overshot": "Melebihi",
"overwrite_amount": "Timpa jumlah",
"pairing_code": "Kode Pairing",
+ "pairing_code_bitbox_confirm": "Pastikan kode di bawah ini cocok dengan kode yang ditampilkan di BitBox Anda",
"pairing_code_desc_1": "Perangkat Anda akan menampilkan kode pairing.",
"pairing_code_desc_2": "Masukkan di sini untuk melanjutkan",
"pairing_error": "Kesalahan Pairing",
### res/values/strings_it.arb
@@ -803,6 +803,7 @@
"overshot": "Superato",
"overwrite_amount": "Sovrascrivi importo",
"pairing_code": "Codice di associazione",
+ "pairing_code_bitbox_confirm": "Conferma che il codice qui sotto corrisponde a quello mostrato sul tuo BitBox",
"pairing_code_desc_1": "Il tuo dispositivo mostrerà un codice di associazione.",
"pairing_code_desc_2": "Inseriscilo qui per continuare",
"pairing_error": "Errore di associazione",
### res/values/strings_ja.arb
@@ -803,6 +803,7 @@
"overshot": "オーバーシュート",
"overwrite_amount": "金額を上書き",
"pairing_code": "ペアリングコード",
+ "pairing_code_bitbox_confirm": "以下のコードがBitBoxに表示されているコードと一致することを確認してください",
"pairing_code_desc_1": "デバイスにペアリングコードが表示されます。",
"pairing_code_desc_2": "続行するにはここに入力してください",
"pairing_error": "ペアリングエラー",
### res/values/strings_ko.arb
@@ -802,6 +802,7 @@
"overshot": "초과",
"overwrite_amount": "금액 덮어쓰기",
"pairing_code": "페어링 코드",
+ "pairing_code_bitbox_confirm": "아래 코드가 BitBox에 표시된 코드와 일치하는지 확인하세요",
"pairing_code_desc_1": "기기에 페어링 코드가 표시됩니다.",
"pairing_code_desc_2": "계속하려면 여기에 입력하세요",
"pairing_error": "페어링 오류",
### res/values/strings_my.arb
@@ -802,6 +802,7 @@
"overshot": "ကျော်လွန်သွားသည်",
"overwrite_amount": "ပမာဏကို အစားထိုးရေးပါ",
"pairing_code": "တွဲချိတ်ကုဒ်",
+ "pairing_code_bitbox_confirm": "အောက်ပါကုဒ်သည် သင့် BitBox တွင် ပြသထားသောကုဒ်နှင့် ကိုက်ညီကြောင်း အတည်ပြုပါ",
"pairing_code_desc_1": "သင့်စက်ပစ္စည်းသည် တွဲချိတ်ကုဒ်တစ်ခုကို ပြသပါမည်။",
"pairing_code_desc_2": "ဆက်လက်လုပ်ဆောင်ရန် ဤနေရာတွင် ထည့်ပါ",
"pairing_error": "တွဲချိတ်မှု အမှား",
### res/values/strings_nl.arb
@@ -802,6 +802,7 @@
"overshot": "Overschreden",
"overwrite_amount": "Bedrag overschrijven",
"pairing_code": "Koppelingscode",
+ "pairing_code_bitbox_confirm": "Bevestig dat de onderstaande code overeenkomt met de code op je BitBox",
"pairing_code_desc_1": "Je apparaat toont een koppelingscode.",
"pairing_code_desc_2": "Voer deze hier in om door te gaan",
"pairing_error": "Koppelingsfout",
### res/values/strings_pl.arb
@@ -802,6 +802,7 @@
"overshot": "Przekroczono",
"overwrite_amount": "Nadpisz kwotę",
"pairing_code": "Kod parowania",
+ "pairing_code_bitbox_confirm": "Potwierdź, że poniższy kod jest zgodny z kodem wyświetlanym na Twoim BitBoxie",
"pairing_code_desc_1": "Twoje urządzenie wyświetli kod parowania.",
"pairing_code_desc_2": "Wprowadź go tutaj, aby kontynuować",
"pairing_error": "Błąd parowania",
### res/values/strings_pt.arb
@@ -804,6 +804,7 @@
"overshot": "Excedido",
"overwrite_amount": "Substituir valor",
"pairing_code": "Código de emparelhamento",
+ "pairing_code_bitbox_confirm": "Confirme que o código abaixo corresponde ao apresentado no seu BitBox",
"pairing_code_desc_1": "O seu dispositivo irá mostrar um código de emparelhamento.",
"pairing_code_desc_2": "Introduza-o aqui para continuar",
"pairing_error": "Erro de emparelhamento",
### res/values/strings_pt_BR.arb
@@ -811,6 +811,7 @@
"overshot": "Excedido",
"overwrite_amount": "Substituir valor",
"pairing_code": "Código de emparelhamento",
+ "pairing_code_bitbox_confirm": "Confirme que o código abaixo corresponde ao exibido no seu BitBox",
"pairing_code_desc_1": "Seu dispositivo exibirá um código de emparelhamento.",
"pairing_code_desc_2": "Insira aqui para continuar",
"pairing_error": "Erro de emparelhamento",
### res/values/strings_ru.arb
@@ -803,6 +803,7 @@
"overshot": "Превышено",
"overwrite_amount": "Перезаписать сумму",
"pairing_code": "Код сопряжения",
+ "pairing_code_bitbox_confirm": "Убедитесь, что код ниже совпадает с кодом, отображаемым на вашем BitBox",
"pairing_code_desc_1": "Ваше устройство покажет код сопряжения.",
"pairing_code_desc_2": "Введите его здесь, чтобы продолжить",
"pairing_error": "Ошибка сопряжения",
### res/values/strings_th.arb
@@ -802,6 +802,7 @@
"overshot": "เกิน",
"overwrite_amount": "เขียนทับจำนวนเงิน",
"pairing_code": "รหัสจับคู่",
+ "pairing_code_bitbox_confirm": "ยืนยันว่ารหัสด้านล่างตรงกับรหัสที่แสดงบน BitBox ของคุณ",
"pairing_code_desc_1": "อุปกรณ์ของคุณจะแสดงรหัสจับคู่",
"pairing_code_desc_2": "ป้อนที่นี่เพื่อดำเนินการต่อ",
"pairing_error": "เกิดข้อผิดพลาดในการจับคู่",
### res/values/strings_tl.arb
@@ -802,6 +802,7 @@
"overshot": "Lumampas",
"overwrite_amount": "Patungan ang halaga",
"pairing_code": "Pairing Code",
+ "pairing_code_bitbox_confirm": "Kumpirmahin na tugma ang code sa ibaba sa ipinapakita sa iyong BitBox",
"pairing_code_desc_1": "Magpapakita ang iyong device ng isang pairing code.",
"pairing_code_desc_2": "Ilagay dito upang magpatuloy",
"pairing_error": "Error sa Pagpa-pair",
### res/values/strings_tr.arb
@@ -802,6 +802,7 @@
"overshot": "Aşıldı",
"overwrite_amount": "Miktarın üzerine yaz",
"pairing_code": "Eşleştirme Kodu",
+ "pairing_code_bitbox_confirm": "Aşağıdaki kodun BitBox'ınızda gösterilen kodla eşleştiğini onaylayın",
"pairing_code_desc_1": "Cihazınız bir eşleştirme kodu gösterecektir.",
"pairing_code_desc_2": "Devam etmek için buraya girin",
"pairing_error": "Eşleştirme Hatası",
### res/values/strings_uk.arb
@@ -802,6 +802,7 @@
"overshot": "Перевищено",
"overwrite_amount": "Перезаписати суму",
"pairing_code": "Код сполучення",
+ "pairing_code_bitbox_confirm": "Переконайтеся, що код нижче збігається з кодом, що відображається на вашому BitBox",
"pairing_code_desc_1": "Ваш пристрій покаже код сполучення.",
"pairing_code_desc_2": "Введіть його тут, щоб продовжити",
"pairing_error": "Помилка сполучення",
### res/values/strings_ur.arb
@@ -804,6 +804,7 @@
"overshot": "اوور شوٹ",
"overwrite_amount": "رقم کو اوور رائٹ کریں",
"pairing_code": "پیئرنگ کوڈ",
+ "pairing_code_bitbox_confirm": "تصدیق کریں کہ نیچے دیا گیا کوڈ آپ کے BitBox پر دکھائے گئے کوڈ سے میل کھاتا ہے",
"pairing_code_desc_1": "آپ کا ڈیوائس ایک پیئرنگ کوڈ دکھائے گا۔",
"pairing_code_desc_2": "جاری رکھنے کے لیے یہاں درج کریں",
"pairing_error": "پیئرنگ کی خرابی",
### res/values/strings_vi.arb
@@ -803,6 +803,7 @@
"overshot": "Vượt quá",
"overwrite_amount": "Ghi đè số lượng",
"pairing_code": "Mã ghép nối",
+ "pairing_code_bitbox_confirm": "Xác nhận rằng mã bên dưới khớp với mã hiển thị trên BitBox của bạn",
"pairing_code_desc_1": "Thiết bị của bạn sẽ hiển thị một mã ghép nối.",
"pairing_code_desc_2": "Nhập vào đây để tiếp tục",
"pairing_error": "Lỗi ghép nối",
### res/values/strings_yo.arb
@@ -803,6 +803,7 @@
"overshot": "Ti kọja iye",
"overwrite_amount": "Rọ́pò iye",
"pairing_code": "Kóòdù Ìsopọ̀",
+ "pairing_code_bitbox_confirm": "Jẹ́rìí pé kóòdù tó wà nísàlẹ̀ bá èyí tí ó hàn lórí BitBox rẹ mu",
"pairing_code_desc_1": "Ẹrọ rẹ yóò ṣàfihàn kóòdù ìsopọ̀ kan.",
"pairing_code_desc_2": "Tẹ̀ ẹ́ sílẹ̀ níbí láti tẹ̀síwájú",
"pairing_error": "Àṣìṣe Ìsopọ̀",
### res/values/strings_zh.arb
@@ -802,6 +802,7 @@
"overshot": "超出",
"overwrite_amount": "覆盖金额",
"pairing_code": "配对码",
+ "pairing_code_bitbox_confirm": "请确认下方代码与您的 BitBox 上显示的代码一致",
"pairing_code_desc_1": "您的设备将显示一个配对码。",
"pairing_code_desc_2": "在此处输入以继续",
"pairing_error": "配对错误",
### scripts/android/docker/Dockerfile.bitbox
@@ -1,9 +0,0 @@
-ARG BASE_IMAGE
-FROM --platform=linux/amd64 ${BASE_IMAGE} AS build
-
-RUN mkdir -p /w/scripts
-COPY scripts/build_bitbox_flutter.sh /w/scripts/build_bitbox_flutter.sh
-RUN cd /w/scripts && /w/scripts/build_bitbox_flutter.sh
-
-FROM --platform=linux/amd64 alpine
-COPY --from=build /w /w
### scripts/android/docker/Dockerfile.final
@@ -1,15 +1,13 @@
ARG BASE_IMAGE
ARG TORCH_IMAGE
ARG REOWN_IMAGE
-ARG BITBOX_IMAGE
ARG MONERO_IMAGE
ARG DECRED_IMAGE
ARG MWEBD_IMAGE
ARG ZCASH_IMAGE
FROM ${TORCH_IMAGE} AS torch_src
FROM ${REOWN_IMAGE} AS reown_src
-FROM ${BITBOX_IMAGE} AS bitbox_src
FROM ${MONERO_IMAGE} AS monero_src
FROM ${DECRED_IMAGE} AS decred_src
FROM ${MWEBD_IMAGE} AS mwebd_src
@@ -19,7 +17,6 @@ FROM --platform=linux/amd64 alpine
COPY --from=torch_src /w /w.top
COPY --from=reown_src /w /w.top
-COPY --from=bitbox_src /w /w.top
COPY --from=monero_src /w /w.top
COPY --from=decred_src /w /w.top
COPY --from=mwebd_src /w /w.top
### scripts/android/docker/build.sh
@@ -236,13 +236,12 @@ merge_slices() {
base_ver="latest"
torch_ver="$(tinysha $SCRIPT_DIR/Dockerfile.torch $REPO_ROOT/scripts/prepare_torch.sh $REPO_ROOT/scripts/android/build_torch.sh)"
reown_ver=$(tinysha $SCRIPT_DIR/Dockerfile.reown $REPO_ROOT/scripts/functions.sh $REPO_ROOT/scripts/prepare_reown.sh $REPO_ROOT/scripts/android/build_reown_deps.sh)
-bitbox_ver=$(tinysha $SCRIPT_DIR/Dockerfile.bitbox $REPO_ROOT/scripts/build_bitbox_flutter.sh)
monero_ver=$(tinysha $SCRIPT_DIR/Dockerfile.monero $REPO_ROOT/scripts/prepare_moneroc.sh $REPO_ROOT/scripts/android/build_monero_all.sh)
mwebd_ver=$(tinysha $SCRIPT_DIR/Dockerfile.mwebd $REPO_ROOT/pubspec_overrides.yaml $(find $REPO_ROOT/cw_mweb/go -type f | sort))
zcash_ver=$(tinysha $SCRIPT_DIR/Dockerfile.zcash $REPO_ROOT/scripts/prepare_zcash.sh $REPO_ROOT/scripts/android/build_zcash.sh)
torch_assembled_extra > /tmp/cw_torch_assembled_extra
decred_ver=$(tinysha $SCRIPT_DIR/Dockerfile.torch $SCRIPT_DIR/Dockerfile.decred $REPO_ROOT/scripts/android/build_decred.sh $REPO_ROOT/cw_decred/pubspec.yaml $REPO_ROOT/pubspec_overrides.yaml /tmp/cw_torch_assembled_extra)
-echo $base_ver $torch_ver $reown_ver $bitbox_ver $monero_ver $mwebd_ver $zcash_ver $decred_ver "$(torch_assembled_extra)" "$(monero_assembled_extra)" > /tmp/docker_build_versions
+echo $base_ver $torch_ver $reown_ver $monero_ver $mwebd_ver $zcash_ver $decred_ver "$(torch_assembled_extra)" "$(monero_assembled_extra)" > /tmp/docker_build_versions
final_ver=$(tinysha /tmp/docker_build_versions)
extract_final() {
@@ -276,10 +275,6 @@ build_base() {
build base "$base_ver"
}
-build_bitbox() {
- build bitbox "$bitbox_ver" --build-arg BASE_IMAGE="$(img base "$base_ver")"
-}
-
build_mwebd() {
build mwebd "$mwebd_ver" --build-arg BASE_IMAGE="$(img base "$base_ver")"
}
@@ -336,7 +331,6 @@ build_final() {
--build-arg BASE_IMAGE="$(img base "$base_ver")" \
--build-arg TORCH_IMAGE="$(img torch "$torch_ver" "$(torch_assembled_extra)")" \
--build-arg REOWN_IMAGE="$(img reown "$reown_ver")" \
- --build-arg BITBOX_IMAGE="$(img bitbox "$bitbox_ver")" \
--build-arg MONERO_IMAGE="$(img monero "$monero_ver" "$(monero_assembled_extra)")" \
--build-arg DECRED_IMAGE="$(img decred "$decred_ver")" \
--build-arg MWEBD_IMAGE="$(img mwebd "$mwebd_ver")" \
@@ -348,7 +342,6 @@ build_final() {
run_one() {
case "$1" in
base) build_base ;;
- bitbox) build_bitbox ;;
mwebd) build_mwebd ;;
reown) build_reown ;;
zcash) build_zcash ;;
@@ -375,7 +368,6 @@ if [[ -z "$ONLY" ]]; then
COIN=""
MERGE=false
build_base
- build_bitbox
build_mwebd
build_reown
build_monero
### scripts/build_bitbox_flutter.sh
@@ -1,25 +0,0 @@
-#!/bin/bash
-set -x -e
-
-if [[ ! -d "bitbox_flutter" ]];
-then
- git clone https://github.com/konstantinullrich/bitbox_flutter
-fi
-
-cd bitbox_flutter
-git fetch -a
-git reset --hard
-git checkout 5a6e6dd388ef64003f86094af80d5453518b601d
-git reset --hard
-
-if [[ "$1" == "clone-only" ]];
-then
- exit 0
-fi
-
-bash ./build_bindings.sh --dont-install
-
-FILE=api.aar
-if [ -f "$FILE" ]; then
- echo "$FILE exists."
-fi
### scripts/linux/docker/Dockerfile.bitbox
@@ -1,9 +0,0 @@
-ARG BASE_IMAGE
-FROM --platform=linux/amd64 ${BASE_IMAGE} AS build
-
-RUN mkdir -p /w/scripts
-COPY scripts/build_bitbox_flutter.sh /w/scripts/build_bitbox_flutter.sh
-RUN cd /w/scripts && /w/scripts/build_bitbox_flutter.sh
-
-FROM --platform=linux/amd64 alpine
-COPY --from=build /w /w
### scripts/linux/docker/Dockerfile.final
@@ -1,14 +1,12 @@
ARG BASE_IMAGE
ARG TORCH_IMAGE
ARG REOWN_IMAGE
-ARG BITBOX_IMAGE
ARG MONERO_IMAGE
ARG MWEBD_IMAGE
ARG ZCASH_IMAGE
FROM --platform=linux/amd64 ${TORCH_IMAGE} AS torch_src
FROM --platform=linux/amd64 ${REOWN_IMAGE} AS reown_src
-FROM --platform=linux/amd64 ${BITBOX_IMAGE} AS bitbox_src
FROM --platform=linux/amd64 ${MONERO_IMAGE} AS monero_src
FROM --platform=linux/amd64 ${MWEBD_IMAGE} AS mwebd_src
FROM --platform=linux/amd64 ${ZCASH_IMAGE} AS zcash_src
@@ -17,7 +15,6 @@ FROM --platform=linux/amd64 alpine
COPY --from=torch_src /w /w.top
COPY --from=reown_src /w /w.top
-COPY --from=bitbox_src /w /w.top
COPY --from=monero_src /w /w.top
COPY --from=mwebd_src /w /w.top
COPY --from=zcash_src /w /w.top
### scripts/linux/docker/build.sh
@@ -217,11 +217,10 @@ merge_slices() {
base_ver="latest"
torch_ver="$(tinysha $SCRIPT_DIR/Dockerfile.torch $REPO_ROOT/scripts/prepare_torch.sh $REPO_ROOT/scripts/linux/build_torch.sh)"
reown_ver=$(tinysha $SCRIPT_DIR/Dockerfile.reown $REPO_ROOT/scripts/functions.sh $REPO_ROOT/scripts/prepare_reown.sh $REPO_ROOT/scripts/android/build_reown_deps.sh)
-bitbox_ver=$(tinysha $SCRIPT_DIR/Dockerfile.bitbox $REPO_ROOT/scripts/build_bitbox_flutter.sh)
monero_ver=$(tinysha $SCRIPT_DIR/Dockerfile.monero $REPO_ROOT/scripts/prepare_moneroc.sh $REPO_ROOT/scripts/linux/build_monero_all.sh)
mwebd_ver=$(tinysha $SCRIPT_DIR/Dockerfile.mwebd $REPO_ROOT/pubspec_overrides.yaml $(find $REPO_ROOT/cw_mweb/go -type f | sort))
zcash_ver=$(tinysha $SCRIPT_DIR/Dockerfile.zcash $REPO_ROOT/scripts/prepare_zcash.sh $REPO_ROOT/scripts/linux/build_zcash.sh)
-echo $base_ver $torch_ver $reown_ver $bitbox_ver $monero_ver $mwebd_ver $zcash_ver "$(monero_assembled_extra)" > /tmp/docker_build_versions
+echo $base_ver $torch_ver $reown_ver $monero_ver $mwebd_ver $zcash_ver "$(monero_assembled_extra)" > /tmp/docker_build_versions
final_ver=$(tinysha /tmp/docker_build_versions)
extract_final() {
@@ -255,10 +254,6 @@ build_base() {
build base "$base_ver"
}
-build_bitbox() {
- build bitbox "$bitbox_ver" --build-arg BASE_IMAGE="$(img base "$base_ver")"
-}
-
build_mwebd() {
build mwebd "$mwebd_ver" --build-arg BASE_IMAGE="$(img base "$base_ver")"
}
@@ -300,7 +295,6 @@ build_final() {
--build-arg BASE_IMAGE="$(img base "$base_ver")" \
--build-arg TORCH_IMAGE="$(img torch "$torch_ver")" \
--build-arg REOWN_IMAGE="$(img reown "$reown_ver")" \
- --build-arg BITBOX_IMAGE="$(img bitbox "$bitbox_ver")" \
--build-arg MONERO_IMAGE="$(img monero "$monero_ver" "$(monero_assembled_extra)")" \
--build-arg MWEBD_IMAGE="$(img mwebd "$mwebd_ver")" \
--build-arg ZCASH_IMAGE="$(img zcash "$zcash_ver")"
@@ -311,7 +305,6 @@ build_final() {
run_one() {
case "$1" in
base) build_base ;;
- bitbox) build_bitbox ;;
mwebd) build_mwebd ;;
reown) build_reown ;;
zcash) build_zcash ;;
@@ -337,7 +330,6 @@ if [[ -z "$ONLY" ]]; then
COIN=""
MERGE=false
build_base
- build_bitbox
build_mwebd
build_reown
build_monero
### tool/configure.dart
@@ -282,7 +282,7 @@ abstract class Bitcoin {
int getMaxCustomFeeRate(Object wallet);
Future<void> setHardwareWalletService(WalletBase wallet, HardwareWalletService service);
HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection, bool isBitcoin);
- HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager, bool isBitcoin);
+ HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxConnection manager, bool isBitcoin);
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect? connect, trezor.TrezorClient? client, bool isBitcoin);
List<Output> updateOutputs(PendingTransaction pendingTransaction, List<Output> outputs);
bool txIsReceivedSilentPayment(TransactionInfo txInfo);
@@ -1580,7 +1580,7 @@ abstract class EVM {
// Hardware wallet methods
Future<void> setHardwareWalletService(WalletBase wallet, HardwareWalletService service);
HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection);
- HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager);
+ HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxConnection manager);
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect);
// Utility methodsWhy this scored 22/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.