Skip to content

Commit

Permalink
bitcoin: add regtest support
Browse files Browse the repository at this point in the history
It has a different bech32 address HRP (prefix).

Third party integrations sometimes are missing this and use testnet as
a workaround, but proper support is nicer.
  • Loading branch information
benma committed Sep 11, 2024
1 parent 0b2085b commit 373383e
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ customers cannot upgrade their bootloader, its changes are recorded separately.
## Firmware

### [Unreleased]
- Bitcoin: add support for regtest

### 9.20.0
- Bitcoin: UX improvements for payment request confirmations
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ endif()
#
# Versions MUST contain three parts and start with lowercase 'v'.
# Example 'v1.0.0'. They MUST not contain a pre-release label such as '-beta'.
set(FIRMWARE_VERSION "v9.20.0")
set(FIRMWARE_BTC_ONLY_VERSION "v9.20.0")
set(FIRMWARE_VERSION "v9.21.0")
set(FIRMWARE_BTC_ONLY_VERSION "v9.21.0")
set(BOOTLOADER_VERSION "v1.0.6")

find_package(PythonInterp 3.6 REQUIRED)
Expand Down
2 changes: 2 additions & 0 deletions messages/btc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ enum BTCCoin {
TBTC = 1;
LTC = 2;
TLTC = 3;
// Regtest
RBTC = 4;
};


Expand Down
1 change: 1 addition & 0 deletions py/bitbox02/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# 8.0.0
- SD card: Remove API to prompt removal of the microSD card from the device
- Add support for regtest (supported from firmware version v9.21.0)

# 7.0.0
- get_info: add optional device initialized boolean to returned tuple
Expand Down
2 changes: 1 addition & 1 deletion py/bitbox02/bitbox02/bitbox02/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from __future__ import print_function
import sys

__version__ = "7.0.0"
__version__ = "8.0.0"

if sys.version_info.major != 3 or sys.version_info.minor < 6:
print(
Expand Down
8 changes: 4 additions & 4 deletions py/bitbox02/bitbox02/communication/generated/btc_pb2.py

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions py/bitbox02/bitbox02/communication/generated/btc_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@ class _BTCCoinEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy
TBTC: _BTCCoin.ValueType # 1
LTC: _BTCCoin.ValueType # 2
TLTC: _BTCCoin.ValueType # 3
RBTC: _BTCCoin.ValueType # 4
"""Regtest"""

class BTCCoin(_BTCCoin, metaclass=_BTCCoinEnumTypeWrapper):
pass

BTC: BTCCoin.ValueType # 0
TBTC: BTCCoin.ValueType # 1
LTC: BTCCoin.ValueType # 2
TLTC: BTCCoin.ValueType # 3
RBTC: BTCCoin.ValueType # 4
"""Regtest"""

global___BTCCoin = BTCCoin


Expand Down
13 changes: 11 additions & 2 deletions src/rust/bitbox02-rust/src/hww/api/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub async fn antiklepto_get_host_nonce(
fn coin_enabled(coin: pb::BtcCoin) -> Result<(), Error> {
use pb::BtcCoin::*;
#[cfg(feature = "app-bitcoin")]
if let Btc | Tbtc = coin {
if let Btc | Tbtc | Rbtc = coin {
return Ok(());
}
#[cfg(feature = "app-litecoin")]
Expand Down Expand Up @@ -580,7 +580,7 @@ mod tests {
assert!(block_on(process_pub(&req_invalid)).is_err());
// -- Wrong coin: MAX + 1
let mut req_invalid = req.clone();
req_invalid.coin = BtcCoin::Tltc as i32 + 1;
req_invalid.coin = BtcCoin::Rbtc as i32 + 1;
assert!(block_on(process_pub(&req_invalid)).is_err());
}

Expand Down Expand Up @@ -690,6 +690,15 @@ mod tests {
expected_address: "tb1qnlyrq9pshg0v0lsuudjgga4nvmjxhcvketqwdg",
expected_display_title: "BTC Testnet",
},
// RBTC P2WPKH
Test {
mnemonic: TEST_MNEMONIC,
coin: BtcCoin::Rbtc,
keypath: &[84 + HARDENED, 1 + HARDENED, 0 + HARDENED, 0, 0],
simple_type: SimpleType::P2wpkh,
expected_address: "bcrt1qnlyrq9pshg0v0lsuudjgga4nvmjxhcvkmzer6p",
expected_display_title: "BTC Regtest",
},
// LTC P2WPKH-P2SH
Test {
mnemonic: TEST_MNEMONIC,
Expand Down
4 changes: 4 additions & 0 deletions src/rust/bitbox02-rust/src/hww/api/bitcoin/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ pub fn format_amount(
FormatUnit::Default => (8, "TBTC"),
FormatUnit::Sat => (0, "tsat"),
},
BtcCoin::Rbtc => match format_unit {
FormatUnit::Default => (8, "RBTC"),
FormatUnit::Sat => (0, "rsat"),
},
BtcCoin::Ltc => match format_unit {
FormatUnit::Default => (8, "LTC"),
_ => return Err(Error::InvalidInput),
Expand Down
5 changes: 3 additions & 2 deletions src/rust/bitbox02-rust/src/hww/api/bitcoin/multisig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub fn get_hash(
BtcCoin::Tbtc => 0x01,
BtcCoin::Ltc => 0x02,
BtcCoin::Tltc => 0x03,
BtcCoin::Rbtc => 0x04,
};
hasher.update(byte.to_le_bytes());
}
Expand Down Expand Up @@ -204,14 +205,14 @@ pub async fn confirm_extended(
ScriptType::P2wsh => bip32::XPubType::CapitalZpub,
ScriptType::P2wshP2sh => bip32::XPubType::CapitalYpub,
},
BtcCoin::Tbtc | BtcCoin::Tltc => match script_type {
BtcCoin::Tbtc | BtcCoin::Rbtc | BtcCoin::Tltc => match script_type {
ScriptType::P2wsh => bip32::XPubType::CapitalVpub,
ScriptType::P2wshP2sh => bip32::XPubType::CapitalUpub,
},
},
XPubType::AutoXpubTpub => match params.coin {
BtcCoin::Btc | BtcCoin::Ltc => bip32::XPubType::Xpub,
BtcCoin::Tbtc | BtcCoin::Tltc => bip32::XPubType::Tpub,
BtcCoin::Tbtc | BtcCoin::Rbtc | BtcCoin::Tltc => bip32::XPubType::Tpub,
},
};
let num_cosigners = multisig.xpubs.len();
Expand Down
11 changes: 11 additions & 0 deletions src/rust/bitbox02-rust/src/hww/api/bitcoin/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ const PARAMS_TBTC: Params = Params {
rbf_support: true,
taproot_support: true,
};
const PARAMS_RBTC: Params = Params {
coin: BtcCoin::Rbtc,
bip44_coin: 1 + HARDENED,
base58_version_p2pkh: 0x6f, // starts with m or n
base58_version_p2sh: 0xc4, // starts with 2
bech32_hrp: "bcrt",
name: "BTC Regtest",
rbf_support: true,
taproot_support: true,
};

const PARAMS_LTC: Params = Params {
coin: BtcCoin::Ltc,
Expand Down Expand Up @@ -88,6 +98,7 @@ pub fn get(coin: BtcCoin) -> &'static Params {
match coin {
Btc => &PARAMS_BTC,
Tbtc => &PARAMS_TBTC,
Rbtc => &PARAMS_RBTC,
Ltc => &PARAMS_LTC,
Tltc => &PARAMS_TLTC,
}
Expand Down
3 changes: 2 additions & 1 deletion src/rust/bitbox02-rust/src/hww/api/bitcoin/policies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ impl<'a> ParsedPolicy<'a> {

let output_xpub_type = match params.coin {
BtcCoin::Btc | BtcCoin::Ltc => bip32::XPubType::Xpub,
BtcCoin::Tbtc | BtcCoin::Tltc => bip32::XPubType::Tpub,
BtcCoin::Tbtc | BtcCoin::Rbtc | BtcCoin::Tltc => bip32::XPubType::Tpub,
};
let num_keys = policy.keys.len();
for (i, key) in policy.keys.iter().enumerate() {
Expand Down Expand Up @@ -513,6 +513,7 @@ pub fn get_hash(coin: BtcCoin, policy: &Policy) -> Result<Vec<u8>, ()> {
BtcCoin::Tbtc => 0x01,
BtcCoin::Ltc => 0x02,
BtcCoin::Tltc => 0x03,
BtcCoin::Rbtc => 0x04,
};
hasher.update(byte.to_le_bytes());
}
Expand Down
4 changes: 4 additions & 0 deletions src/rust/bitbox02-rust/src/shiftcrypto.bitbox02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,8 @@ pub enum BtcCoin {
Tbtc = 1,
Ltc = 2,
Tltc = 3,
/// Regtest
Rbtc = 4,
}
impl BtcCoin {
/// String value of the enum field names used in the ProtoBuf definition.
Expand All @@ -858,6 +860,7 @@ impl BtcCoin {
BtcCoin::Tbtc => "TBTC",
BtcCoin::Ltc => "LTC",
BtcCoin::Tltc => "TLTC",
BtcCoin::Rbtc => "RBTC",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
Expand All @@ -867,6 +870,7 @@ impl BtcCoin {
"TBTC" => Some(Self::Tbtc),
"LTC" => Some(Self::Ltc),
"TLTC" => Some(Self::Tltc),
"RBTC" => Some(Self::Rbtc),
_ => None,
}
}
Expand Down

0 comments on commit 373383e

Please sign in to comment.