Merge branch 'master' of github.com:Coldcard/firmware
This commit is contained in:
commit
c488882862
@ -28,6 +28,7 @@ has been automated using Docker. Steps are as follows:
|
||||
|
||||
4. At the end of the process a clear confirmation message is shown, or the differences.
|
||||
5. Build products can be found `firmware/stm32/built`.
|
||||
6. If you do not trust the results of `make repro` refer to `docs/notes-on-repro.md` which breaks down the process.
|
||||
|
||||
## Long-Lived Branches
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@ Step 2: Export descriptor from Coldcard to Core
|
||||
- in Bitcoin Core, go to Windows -> Console
|
||||
- select your newly created descriptor wallet in the wallet pulldown (top left)
|
||||
- paste the `importdescriptor` command. It should respond with a success message
|
||||
- in Bitcoin Core v24.1, the console response will include `"message": "Ranged descriptors should not have a label"` and Bitcoin Core won't allow address generation. Removing the entry `"label": "Coldcard x0x0x0x0"` from the .txt file fixes this issue.
|
||||
|
||||
NOTE: If you are importing an existing wallet this way, with UTXO on the blockchain,
|
||||
you may need to rescan and/or delete "timestamp=now" from the command. If the
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
- change outputs (indicated with paths, scripts in output section) must correspond to
|
||||
the active multisig wallet, and cannot be used to describe an unrelated (multisig) wallet.
|
||||
- derivation path for each cosigner must be known and consistent with PSBT
|
||||
- fixed: XFP values (fingerprints) for each of the co-signers must be unique (limitation removed)
|
||||
- XFP values (fingerprints) MUST be unique for each of the co-signers
|
||||
|
||||
|
||||
# SIGHASH types
|
||||
|
||||
190
docs/notes-on-repro.md
Normal file
190
docs/notes-on-repro.md
Normal file
@ -0,0 +1,190 @@
|
||||
# Notes on Reproducible Builds
|
||||
|
||||
The following document aims to breakdown how reproducibility is verified in the `make repro` build step.
|
||||
|
||||
## stm32/shared.mk
|
||||
|
||||
The entrypoint makefile for repro builds.
|
||||
|
||||
### repro
|
||||
|
||||
The `repro` command in `shared.mk` is the first step in the repro build process, which triggers a docker build and run process.
|
||||
|
||||
```makefile
|
||||
repro:
|
||||
docker build -t coldcard-build - < dockerfile.build
|
||||
(cd ..; docker run $(DOCK_RUN_ARGS) sh src/stm32/repro-build.sh $(VERSION_STRING) $(MK_NUM))
|
||||
```
|
||||
|
||||
Below are interesting sections from the docker logs that give an idea as to what is going on in build process:
|
||||
|
||||
```stdout
|
||||
+ mkdir /tmp/checkout
|
||||
+ mount -t tmpfs tmpfs /tmp/checkout
|
||||
|
||||
...
|
||||
```
|
||||
We will pull the release from coldcard.com into the `/tmp/checkout` directory.
|
||||
|
||||
```
|
||||
+ git clone /work/src/.git firmware
|
||||
|
||||
...
|
||||
|
||||
+ cd firmware/external
|
||||
+ git submodule update --init
|
||||
|
||||
...
|
||||
|
||||
Successfully installed signit-1.0
|
||||
|
||||
...
|
||||
|
||||
+ cd ../stm32
|
||||
+ cd ../releases
|
||||
+ '[' -f '*-v5.0.7-mk4-coldcard.dfu' ]
|
||||
+ dd 'bs=66' 'skip=1'
|
||||
+ grep -F v5.0.7-mk4-coldcard.dfu signatures.txt
|
||||
0+1 records in
|
||||
0+1 records out
|
||||
+ PUBLISHED_BIN=2022-10-05T1724-v5.0.7-mk4-coldcard.dfu
|
||||
+ '[' -z 2022-10-05T1724-v5.0.7-mk4-coldcard.dfu ]
|
||||
+ wget -S https://coldcard.com/downloads/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu
|
||||
|
||||
...
|
||||
|
||||
'2022-10-05T1724-v5.0.7-mk4-coldcard.dfu' saved
|
||||
|
||||
...
|
||||
|
||||
+ PUBLISHED_BIN=/tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu
|
||||
|
||||
...
|
||||
|
||||
+ make -f MK4-Makefile setup
|
||||
|
||||
...
|
||||
|
||||
+ make -f MK4-Makefile firmware-signed.bin firmware-signed.dfu production.bin dev.dfu firmware.lss firmware.elf
|
||||
|
||||
...
|
||||
|
||||
signit sign -b l-port/build-COLDCARD_MK4 -m 4 5.0.7 -o firmware-signed.bin
|
||||
|
||||
...
|
||||
|
||||
signit sign -m 4 5.0.7 -r firmware-signed.bin -k 1 -o production.bin
|
||||
You don't have that key (1), so using key zero instead!
|
||||
...
|
||||
|
||||
cd ../external/micropython/ports/stm32 && make BOARD=COLDCARD_MK4 -j 4 EXCLUDE_NGU_TESTS=1 DEBUG_BUILD=0
|
||||
|
||||
...
|
||||
|
||||
../external/micropython/tools/dfu.py -b 0x08020000:dev.bin dev.dfu
|
||||
arm-none-eabi-objdump -h -S l-port/build-COLDCARD_MK4/firmware.elf > firmware.lss
|
||||
cp l-port/build-COLDCARD_MK4/firmware.elf .
|
||||
+ '[' /tmp/checkout/firmware/stm32 '!=' /work/src/stm32 ]
|
||||
+ rsync -av --ignore-missing-args firmware-signed.bin firmware-signed.dfu production.bin dev.dfu firmware.lss firmware.elf /work/built
|
||||
sending incremental file list
|
||||
dev.dfu
|
||||
firmware-signed.bin
|
||||
firmware-signed.dfu
|
||||
firmware.elf
|
||||
firmware.lss
|
||||
production.bin
|
||||
|
||||
...
|
||||
|
||||
+ make -f MK4-Makefile 'PUBLISHED_BIN=/tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu' check-repro
|
||||
|
||||
...
|
||||
|
||||
Comparing against: /tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu
|
||||
test -n "/tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu" -a -f /tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu
|
||||
rm -f -f check-fw.bin check-bootrom.bin
|
||||
signit split /tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu check-fw.bin check-bootrom.bin
|
||||
start 293 for 870400 bytes: Firmware => check-fw.bin
|
||||
start 870701 for 114688 bytes: Bootrom => check-bootrom.bin
|
||||
signit check check-fw.bin
|
||||
magic_value: 0xcc001234
|
||||
timestamp: 2022-10-05 17:24:55 UTC
|
||||
version_string: 5.0.7
|
||||
pubkey_num: 1
|
||||
firmware_length: 870400
|
||||
install_flags: 0x0 =>
|
||||
hw_compat: 0x8 => Mk4
|
||||
best_ts: b'\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
future: 0000000000000000 ... 0000000000000000
|
||||
signature: 293948e7ce4a3555 ... 766437aa65d3e88a
|
||||
sha256^2: 7f3a7c5f794ce72f68280447cddc837fa62245fdf4b795822127624f8775dca2
|
||||
ECDSA Signature: CORRECT
|
||||
signit check firmware-signed.bin
|
||||
magic_value: 0xcc001234
|
||||
timestamp: 2022-10-24 13:33:16 UTC
|
||||
version_string: 5.0.7
|
||||
pubkey_num: 0
|
||||
firmware_length: 870400
|
||||
install_flags: 0x0 =>
|
||||
hw_compat: 0x8 => Mk4
|
||||
best_ts: b'\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
future: 0000000000000000 ... 0000000000000000
|
||||
signature: deb643d0a140d89e ... c544f09cd80fa65c
|
||||
sha256^2: a46ddd6e599a49a573bf76054f438c9efe1ee031bfae74a00b0e7bbe76f516c3
|
||||
ECDSA Signature: CORRECT
|
||||
hexdump -C firmware-signed.bin | sed -e 's/^00003f[89abcdef]0 .*/(firmware signature here)/' > repro-got.txt
|
||||
hexdump -C check-fw.bin | sed -e 's/^00003f[89abcdef]0 .*/(firmware signature here)/' > repro-want.txt
|
||||
diff repro-got.txt repro-want.txt
|
||||
|
||||
SUCCESS.
|
||||
|
||||
You have built a bit-for-bit identical copy of Coldcard firmware for v5.0.7
|
||||
```
|
||||
|
||||
## check-repro
|
||||
|
||||
The `check-repro` section of the makefile contains the steps required to verify that the build artifacts are infact a bit-for-bit match to the release candidates.
|
||||
|
||||
```makefile
|
||||
check-repro: TRIM_SIG = sed -e 's/^00003f[89abcdef]0 .*/(firmware signature here)/'
|
||||
check-repro: firmware-signed.bin
|
||||
ifeq ($(PUBLISHED_BIN),)
|
||||
@echo ""
|
||||
@echo "Need published binary for: $(VERSION_STRING)"
|
||||
@echo ""
|
||||
@echo "Copy it into ../releases"
|
||||
@echo ""
|
||||
else
|
||||
@echo Comparing against: $(PUBLISHED_BIN)
|
||||
test -n "$(PUBLISHED_BIN)" -a -f $(PUBLISHED_BIN)
|
||||
$(RM) -f check-fw.bin check-bootrom.bin
|
||||
$(SIGNIT) split $(PUBLISHED_BIN) check-fw.bin check-bootrom.bin
|
||||
$(SIGNIT) check check-fw.bin
|
||||
$(SIGNIT) check firmware-signed.bin
|
||||
hexdump -C firmware-signed.bin | $(TRIM_SIG) > repro-got.txt
|
||||
hexdump -C check-fw.bin | $(TRIM_SIG) > repro-want.txt
|
||||
diff repro-got.txt repro-want.txt
|
||||
@echo ""
|
||||
@echo "SUCCESS. "
|
||||
@echo ""
|
||||
@echo "You have built a bit-for-bit identical copy of Coldcard firmware for v$(VERSION_STRING)"
|
||||
endif
|
||||
```
|
||||
|
||||
To summarize `check-repro`:
|
||||
|
||||
- At the final `check-repro` step, we have a locally built `firmware-signed.bin` and we want to check that it matches the binary release provided by Coinkite.
|
||||
|
||||
- This step verifies the signature of the binary is valid, using either the Coinkite key factory key or the "debug" key zero which is public.
|
||||
|
||||
- An identical checksum match will not be possible as is, since there is signature data embedded into into the binary, which must be removed.
|
||||
|
||||
- The specific release of the version that is being built is fetched, and placed it under /tmp/checkout/firmware/releases/*.dfu
|
||||
|
||||
- `split` (cli/signit.py: Line 153-175) is run against the release `*.dfu` resulting in a `check-fw.bin` and `check-bootrom.bin`. "This splits the DFU file into the two parts it contains: the main firmware (COLDCARD application) and the boot loader code."
|
||||
|
||||
- `check` (cli/signit.py: Line 176-241) is run against each the release `check-fw.bin` and our built `firmware-signed.bin`.
|
||||
|
||||
- a hexdump is taken of each the release `check-fw.bin` and our built `firmware-signed.bin` piped through $TRIM_SIG which removes 64 bytes of signature data and subsitutes it with a common string.
|
||||
|
||||
- Finally the diff of the two hexdumps are compared to prove reproducibility.
|
||||
@ -9,7 +9,6 @@ font_files = {
|
||||
}
|
||||
|
||||
# test with:
|
||||
#
|
||||
# ./build.py build --portable && ./testit.py --msg "hello→world←\n↳this\n•Bullet\n•Text" -f small
|
||||
#
|
||||
special_chars = dict(small=[
|
||||
@ -65,5 +64,14 @@ special_chars = dict(small=[
|
||||
|
||||
xxxxx
|
||||
'''),
|
||||
('⋯', dict(y=0), '''\
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
x x x x x
|
||||
'''),
|
||||
|
||||
])
|
||||
|
||||
@ -3,9 +3,12 @@
|
||||
- Enhancement: change Key Origin Information export format in multisig `addresses.csv` to match
|
||||
[BIP-0380](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki#key-expressions)
|
||||
`(m=0F056943)/m/48'/1'/0'/2'/0/0` --> `[0F056943/48'/1'/0'/2'/0/0]`
|
||||
- Enhancement: Address explorer UX cosmetics.
|
||||
- Change: `Unchained Capital` renamed to `Unchained`
|
||||
- Bugfix: correct `scriptPubkey` parsing for segwit v1-v16
|
||||
- Bugfix: do not infer segwit just by availability of `PSBT_IN_WITNESS_UTXO` in PSBT. Improves
|
||||
compatibility with Bitcoin Core.
|
||||
- Bugfix: do not infer segwit just by availability of `PSBT_IN_WITNESS_UTXO` in PSBT.
|
||||
- Bugfix: remove label from Bitcoin Core `importdescriptors` export as it is no longer supported
|
||||
with ranged descriptors in version `24.1`
|
||||
|
||||
## 5.1.2 - 2023-04-07
|
||||
|
||||
|
||||
@ -1251,7 +1251,7 @@ async def unchained_capital_export(*a):
|
||||
# they were using our airgapped export, and the BIP-45 path from that
|
||||
#
|
||||
ch = await ux_show_story('''\
|
||||
This saves multisig XPUB information required to setup on the Unchained Capital platform. \
|
||||
This saves multisig XPUB information required to setup on the Unchained platform. \
|
||||
''' + PICK_ACCOUNT + SENSITIVE_NOT_SECRET, escape="1")
|
||||
account_num = 0
|
||||
if ch == '1':
|
||||
@ -1262,7 +1262,7 @@ This saves multisig XPUB information required to setup on the Unchained Capital
|
||||
xfp = xfp2str(settings.get('xfp', 0))
|
||||
fname = 'unchained-%s.json' % xfp
|
||||
|
||||
await make_json_wallet('Unchained Capital',
|
||||
await make_json_wallet('Unchained',
|
||||
lambda: generate_unchained_export(account_num),
|
||||
fname)
|
||||
|
||||
|
||||
@ -18,8 +18,10 @@ from utils import addr_fmt_label
|
||||
|
||||
def truncate_address(addr):
|
||||
# Truncates address to width of screen, replacing middle chars
|
||||
# - 16 chars screen width, so show 8 prefix, dash, and 7 of end of address
|
||||
return addr[0:8] + '-' + addr[-7:]
|
||||
# - 16 chars screen width
|
||||
# - but 2 lost at left (menu arrow, corner arrow)
|
||||
# - want to show not truncated on right side
|
||||
return addr[0:5] + '⋯' + addr[-6:]
|
||||
|
||||
class KeypathMenu(MenuSystem):
|
||||
def __init__(self, path=None, nl=0):
|
||||
@ -28,14 +30,14 @@ class KeypathMenu(MenuSystem):
|
||||
if path is None:
|
||||
# Top level menu; useful shortcuts, and special case just "m"
|
||||
items = [
|
||||
MenuItem("m/..", f=self.deeper),
|
||||
MenuItem("m/49'/..", f=self.deeper),
|
||||
MenuItem("m/84'/..", f=self.deeper),
|
||||
MenuItem("m/44'/..", f=self.deeper),
|
||||
MenuItem("m/0/{idx}", menu=self.done),
|
||||
MenuItem("m/{idx}", menu=self.done),
|
||||
MenuItem("m", f=self.done),
|
||||
]
|
||||
MenuItem("m/..", f=self.deeper),
|
||||
MenuItem("m/44'/..", f=self.deeper),
|
||||
MenuItem("m/49'/..", f=self.deeper),
|
||||
MenuItem("m/84'/..", f=self.deeper),
|
||||
MenuItem("m/0/{idx}", menu=self.done),
|
||||
MenuItem("m/{idx}", menu=self.done),
|
||||
MenuItem("m", f=self.done),
|
||||
]
|
||||
else:
|
||||
# drill down one layer: (nl) is the current leaf
|
||||
# - hardened choice first
|
||||
@ -183,12 +185,12 @@ class AddressListMenu(MenuSystem):
|
||||
items = []
|
||||
for i, (address, path, addr_fmt) in enumerate(choices):
|
||||
axi = address[-4:] # last 4 address characters
|
||||
items.append(MenuItem(" "+addr_fmt_label(addr_fmt), f=self.pick_single,
|
||||
items.append(MenuItem(addr_fmt_label(addr_fmt), f=self.pick_single,
|
||||
arg=(path, addr_fmt, axi)))
|
||||
items.append(MenuItem(address, f=self.pick_single,
|
||||
items.append(MenuItem('↳'+address, f=self.pick_single,
|
||||
arg=(path, addr_fmt, axi)))
|
||||
|
||||
# some other choices
|
||||
# some other choices
|
||||
if self.account_num == 0:
|
||||
items.append(MenuItem("Applications", menu=ApplicationsMenu(self)))
|
||||
items.append(MenuItem("Account Number", f=self.change_account))
|
||||
@ -374,7 +376,7 @@ def generate_address_csv(path, addr_fmt, ms_wallet, account_num, n, start=0, cha
|
||||
if ms_wallet:
|
||||
# For multisig, include redeem script and derivation for each signer
|
||||
yield '"' + '","'.join(['Index', 'Payment Address',
|
||||
'Redeem Script (%d of %d)' % (ms_wallet.M, ms_wallet.N)]
|
||||
'Redeem Script (%d of %d)' % (ms_wallet.M, ms_wallet.N)]
|
||||
+ (['Derivation'] * ms_wallet.N)) + '"\n'
|
||||
|
||||
for (idx, derivs, addr, script) in ms_wallet.yield_addresses(start, n, change_idx=change):
|
||||
|
||||
@ -109,7 +109,6 @@ async def drv_entro_step2(_1, picked, _2):
|
||||
from glob import dis
|
||||
from files import CardSlot, CardMissingError, needs_microsd
|
||||
|
||||
the_ux.pop()
|
||||
msg = "Index Number?"
|
||||
if picked == 7:
|
||||
# Passwords
|
||||
|
||||
@ -258,7 +258,7 @@ def generate_bitcoin_core_wallet(account_num, example_addrs):
|
||||
for internal in [False, True]
|
||||
]
|
||||
# for importdescriptors
|
||||
imd_list = desc_obj.bitcoin_core_serialize(external_label="Coldcard %s" % txt_xfp)
|
||||
imd_list = desc_obj.bitcoin_core_serialize()
|
||||
return imm_list, imd_list
|
||||
|
||||
def generate_wasabi_wallet():
|
||||
|
||||
@ -163,7 +163,7 @@ WalletExportMenu = [
|
||||
MenuItem("Bitcoin Core", f=bitcoin_core_skeleton),
|
||||
MenuItem("Electrum Wallet", f=electrum_skeleton),
|
||||
MenuItem("Wasabi Wallet", f=wasabi_skeleton),
|
||||
MenuItem("Unchained Capital", f=unchained_capital_export),
|
||||
MenuItem("Unchained", f=unchained_capital_export),
|
||||
MenuItem("Lily Wallet", f=lily_skeleton),
|
||||
MenuItem("Samourai Postmix", f=samourai_post_mix_descriptor_export),
|
||||
MenuItem("Samourai Premix", f=samourai_pre_mix_descriptor_export),
|
||||
|
||||
@ -123,8 +123,7 @@ class PinAttempt:
|
||||
|
||||
|
||||
assert MAX_PIN_LEN == 32 # update FMT otherwise
|
||||
assert ustruct.calcsize(PIN_ATTEMPT_FMT_V1) == PIN_ATTEMPT_SIZE_V1, \
|
||||
ustruct.calcsize(PIN_ATTEMPT_FMT)
|
||||
assert ustruct.calcsize(PIN_ATTEMPT_FMT_V1) == PIN_ATTEMPT_SIZE_V1
|
||||
assert ustruct.calcsize(PIN_ATTEMPT_FMT_V2_ADDITIONS) == PIN_ATTEMPT_SIZE - PIN_ATTEMPT_SIZE_V1
|
||||
|
||||
# check for bricked system early
|
||||
|
||||
@ -31,12 +31,13 @@ class FontBase:
|
||||
|
||||
class FontSmall(FontBase):
|
||||
height = 14
|
||||
code_range = range(32, 8627)
|
||||
code_range = range(32, 8943)
|
||||
|
||||
_bboxes = [None, (0, -3, 7, 14, 0), (0, -3, 7, 14, 4), (0, -3, 7,
|
||||
14, 5), (0, -3, 7, 14, 7), (0, -3, 7, 14, 9), (0, -3, 7, 14, 10),
|
||||
(0, -3, 7, 14, 11), (0, -3, 7, 14, 12), (0, -3, 7, 14, 13), (0, -3,
|
||||
7, 14, 14), (0, 0, 8, 8, 8), (0, 0, 11, 9, 18), (0, 0, 14, 10, 20)]
|
||||
7, 14, 14), (0, 0, 8, 8, 8), (0, 0, 11, 8, 16), (0, 0, 11, 9, 18),
|
||||
(0, 0, 14, 10, 20)]
|
||||
|
||||
_code_points = [
|
||||
(range(32, 127), [1, 2, 14, 20, 31, 43, 55, 67, 73, 87, 101, 111, 122,
|
||||
@ -51,6 +52,7 @@ class FontSmall(FontBase):
|
||||
(range(8592, 8593), [1145]), # ←
|
||||
(range(8594, 8595), [1166]), # →
|
||||
(range(8627, 8628), [1187]), # ↳
|
||||
(range(8943, 8944), [1208]), # ⋯
|
||||
]
|
||||
|
||||
_bitmaps = b"""\
|
||||
@ -116,12 +118,13 @@ class FontSmall(FontBase):
|
||||
\x3a\x02\x02\x42\x3c\x07\x00\x00\x00\x00\x7e\x02\x04\x08\x10\x20\x7e\x09\
|
||||
\x06\x08\x08\x08\x08\x08\x30\x08\x08\x08\x08\x08\x06\x08\x10\x10\x10\x10\
|
||||
\x10\x10\x10\x10\x10\x10\x10\x10\x09\x60\x10\x10\x10\x10\x10\x0c\x10\x10\
|
||||
\x10\x10\x10\x60\x03\x00\x00\x32\x4a\x44\x0c\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x03\x80\x03\x80\x03\x80\x00\x00\x0d\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x08\x00\x18\x00\x3f\xf8\x18\x00\x08\x00\x00\x00\x0d\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x20\x00\x30\x3f\xf8\x00\x30\x00\x20\x00\x00\x0d\
|
||||
\x10\x10\x10\x60\x03\x00\x00\x32\x4a\x44\x0d\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x03\x80\x03\x80\x03\x80\x00\x00\x0e\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x08\x00\x18\x00\x3f\xf8\x18\x00\x08\x00\x00\x00\x0e\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x20\x00\x30\x3f\xf8\x00\x30\x00\x20\x00\x00\x0e\
|
||||
\x00\x00\x10\x00\x10\x00\x10\x00\x10\x20\x10\x30\x1f\xf8\x00\x30\x00\x20\
|
||||
\x00\x00\
|
||||
\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\xa0\x00\
|
||||
\x00\
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@ -133,12 +133,17 @@ def test_export_core(way, dev, use_regtest, acct_num, pick_menu_item, goto_home,
|
||||
assert expect in desc
|
||||
assert expect+f'/{n}/*' in desc
|
||||
|
||||
if n == 0:
|
||||
assert here['label'] == 'Coldcard ' + xfp
|
||||
assert 'label' not in d
|
||||
|
||||
# test against bitcoind -- needs a "descriptor native" wallet
|
||||
bitcoind_d_wallet.importdescriptors(obj)
|
||||
res = bitcoind_d_wallet.importdescriptors(obj)
|
||||
assert res[0]["success"]
|
||||
assert res[1]["success"]
|
||||
core_gen = []
|
||||
for i in range(3):
|
||||
core_gen.append(bitcoind_d_wallet.getnewaddress())
|
||||
|
||||
assert core_gen == addrs
|
||||
x = bitcoind_d_wallet.getaddressinfo(addrs[-1])
|
||||
pprint(x)
|
||||
assert x['address'] == addrs[-1]
|
||||
@ -342,19 +347,20 @@ def test_export_coldcard(way, dev, acct_num, app, pick_menu_item, goto_home, cap
|
||||
def test_export_unchained(way, dev, pick_menu_item, goto_home, cap_story, need_keypress, acct_num,
|
||||
microsd_path, nfc_read_json, virtdisk_path, testnet, enter_number,
|
||||
load_export, settings_set, use_mainnet):
|
||||
# test UX and operation of the 'unchained capital export'
|
||||
# test UX and operation of the 'unchained export'
|
||||
if not testnet:
|
||||
use_mainnet()
|
||||
goto_home()
|
||||
pick_menu_item('Advanced/Tools')
|
||||
pick_menu_item('File Management')
|
||||
pick_menu_item('Export Wallet')
|
||||
pick_menu_item('Unchained Capital')
|
||||
pick_menu_item('Unchained')
|
||||
|
||||
time.sleep(0.1)
|
||||
title, story = cap_story()
|
||||
|
||||
assert 'Unchained Capital' in story
|
||||
assert 'Unchained' in story
|
||||
assert "Capital" not in story
|
||||
assert 'Press (1) to' in story
|
||||
if acct_num is not None:
|
||||
need_keypress('1')
|
||||
@ -364,7 +370,7 @@ def test_export_unchained(way, dev, pick_menu_item, goto_home, cap_story, need_k
|
||||
acct_num = '0'
|
||||
need_keypress('y')
|
||||
|
||||
obj = load_export(way, label="Unchained Capital", is_json=True, sig_check=False)
|
||||
obj = load_export(way, label="Unchained", is_json=True, sig_check=False)
|
||||
|
||||
root = BIP32Node.from_wallet_key(simulator_fixed_xprv)
|
||||
if not testnet:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user