Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
85c4d20
test(bitcoin-only): exercise the 7.14.3 product
BitHighlander Aug 26, 2026
e353ce5
test(bitcoin-only): skip Maya-only memo coverage
BitHighlander Aug 26, 2026
cef50e5
test: cover signing session security boundaries
BitHighlander Aug 26, 2026
84d0213
test: cover authenticator authorization boundaries
BitHighlander Aug 26, 2026
7e39fd5
ci: checkout fork branches from current project
BitHighlander Aug 26, 2026
758f20c
ci: bind companion tests to firmware PR 604
BitHighlander Aug 26, 2026
36e052d
test: add 7.14.2 security regressions and hermetic fixtures
BitHighlander Aug 26, 2026
8b7f445
test: close 7.14.2 presign evidence gaps
BitHighlander Aug 26, 2026
90ddd76
test(ethereum): cover full-width token chain IDs
BitHighlander Aug 27, 2026
36bc792
test(ethereum): pin native pseudo-address isolation
BitHighlander Aug 27, 2026
49ccca4
Potential fix for pull request finding
BitHighlander Aug 27, 2026
0792eec
Potential fix for pull request finding
BitHighlander Aug 27, 2026
27aa8cb
Potential fix for pull request finding
BitHighlander Aug 27, 2026
35a2da6
fix: correct indentation in regression tests
BitHighlander Aug 27, 2026
92e8745
test(ethereum): require advanced mode for MakerDAO calldata
BitHighlander Aug 27, 2026
2682c66
Merge pull request #219 from keepkey/release/7.14.2-rc31-presign-tests
pastaghost Aug 27, 2026
8df52c2
Merge branch 'master' into fix/7142-makerdao-advanced-mode-tests
BitHighlander Aug 27, 2026
7c04903
test(solana): match AdvancedMode refusal
BitHighlander Aug 27, 2026
ce5c1bb
Merge pull request #221 from keepkey/fix/7142-makerdao-advanced-mode-…
pastaghost Aug 27, 2026
621c3dd
merge: carry 7.14.2 regressions into 7.14.3 companion
BitHighlander Aug 27, 2026
fc12c6d
test(fixtures): drop noncanonical unused taproot prevtx
BitHighlander Aug 27, 2026
ef41fc9
ci: install hermetic fixture network dependency
BitHighlander Aug 27, 2026
4e8f3b5
ci: exercise the 7.14.3 bitcoin-only product
BitHighlander Aug 27, 2026
9a4af72
ci: surface integration test hangs
BitHighlander Aug 27, 2026
86831be
ci: permit emulator UDP through offline gate
BitHighlander Aug 27, 2026
2771e17
fix(report): restore exact screenshot selector CLI
BitHighlander Aug 27, 2026
3ddc544
test(solana): build canonical stake authorize accounts
BitHighlander Aug 27, 2026
0014cfb
test(report): align screenshot audit with fail-closed flows
BitHighlander Aug 27, 2026
9d69038
fix(report): gate 7.15 storage tests by version
BitHighlander Aug 27, 2026
34b45fa
feat(report): accept exact evidence provenance
BitHighlander Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ jobs:
- run:
name: Clone python-keepkey (current branch)
command: |
git clone --depth 1 -b "$CIRCLE_BRANCH" https://github.com/keepkey/python-keepkey.git .pykk
# Fork-only PR branches do not exist in keepkey/python-keepkey.
# Clone the repository that triggered this CircleCI project so the
# exact CIRCLE_SHA1 under review is available and verifiable.
git clone --depth 1 -b "$CIRCLE_BRANCH" \
"https://github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}.git" .pykk
test "$(git -C .pykk rev-parse HEAD)" = "$CIRCLE_SHA1"
cd .pykk && git submodule update --init --recursive

# ────────────────────────────────────────────────────────────────
Expand All @@ -27,16 +32,32 @@ jobs:
# Move python-keepkey out of the way
mv .pykk ../

# Clone firmware repository (expects $FIRMWARE_REPO env var)
git clone --depth 1 -b master "$FIRMWARE_REPO" .
# This companion branch gates firmware PR #604, not the default
# firmware branch. Keep the target explicit and fail if it moves.
git clone --depth 1 -b release/7.14.3-bitcoin-only \
https://github.com/BitHighlander/keepkey-firmware.git .

# Initialise firmware submodules
git submodule update --init --recursive
# Match firmware CI's build set. A recursive init reaches optional
# trezor-firmware vendors that do not support shallow HTTPS clones.
git submodule update --init --depth 1 deps/crypto/trezor-firmware
git submodule update --init --depth 1 deps/device-protocol
git submodule update --init --depth 1 deps/googletest
git submodule update --init --depth 1 deps/qrenc/QR-Code-generator
git submodule update --init --depth 1 deps/sca-hardening/SecAESSTM32

# Replace the vendor copy with our PR branch python-keepkey
rm -rf deps/python-keepkey
mv ../.pykk deps/python-keepkey

# This is python-keepkey's standalone compatibility lane. Release
# OLED/PDF evidence is generated only by the exact-head firmware
# workflow, where the firmware and Python SHAs are pinned together.
# Do not inherit the firmware checkout's report/screenshot phase:
# it can describe a different (published/master) emulator and is
# therefore not release evidence for this Python PR.
cp deps/python-keepkey/.circleci/standalone-emulator-tests.sh \
scripts/emulator/python-keepkey-tests.sh

# ────────────────────────────────────────────────────────────────
# 3) Build the Docker-based emulator tests
# ────────────────────────────────────────────────────────────────
Expand Down
35 changes: 35 additions & 0 deletions .circleci/standalone-emulator-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/sh
set -e

# python-keepkey's own CI is a compatibility test against the emulator supplied
# by the firmware checkout. It deliberately does not produce OLED/PDF release
# evidence. Authoritative display evidence is generated by keepkey-firmware CI,
# which pins both repositories to exact candidate SHAs.

mkdir -p /kkemu/test-reports/python-keepkey

echo "=== Waiting for emulator ==="
for attempt in $(seq 1 20); do
if echo -n "PINGPING" | nc -u -w1 kkemu 11044 2>/dev/null | grep -q PONG; then
echo "Emulator ready (attempt $attempt)"
break
fi
if [ "$attempt" -eq 20 ]; then
echo "Emulator did not become ready"
echo "1" > /kkemu/test-reports/python-keepkey/status
exit 1
fi
sleep 2
done

cd /kkemu/deps/python-keepkey/tests
set +e
KK_TRANSPORT_MAIN=kkemu:11044 \
KK_TRANSPORT_DEBUG=kkemu:11045 \
pytest -v --tb=short \
--junitxml=/kkemu/test-reports/python-keepkey/junit.xml
pytest_status=$?
set -e

echo "$pytest_status" > /kkemu/test-reports/python-keepkey/status
exit "$pytest_status"
62 changes: 51 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# KeepKey python-keepkey CI
#
# Pulls the published emulator image (kktech/kkemu) from DockerHub
# and runs the full python integration test suite against it.
# Builds the 7.14.3 Bitcoin-only emulator from the fork release branch and
# runs the full Python integration suite against that exact product variant.
#
# Stage 1: GATE (seconds)
# └─ lint Python syntax + deterministic protocol contract tests
Expand Down Expand Up @@ -42,7 +42,7 @@ jobs:

- name: Install contract-test dependencies
run: |
pip install "protobuf>=3.20,<4" mnemonic ecdsa pytest
pip install "protobuf>=3.20,<4" mnemonic ecdsa pytest requests

- name: Run deterministic Zcash PCZT contract tests
env:
Expand All @@ -52,6 +52,9 @@ jobs:
tests/test_msg_zcash_sign_pczt.py \
tests/test_zcash_seed_fingerprint_helper.py

- name: Verify offline transaction fixture manifest
run: python tests/tx_fixture_manifest.py --check

- name: Lint summary
run: |
echo "## 🔑 KeepKey python-keepkey — Lint" >> "$GITHUB_STEP_SUMMARY"
Expand All @@ -60,9 +63,13 @@ jobs:
echo "|-------|--------|" >> "$GITHUB_STEP_SUMMARY"
echo "| Syntax | ✅ PASS |" >> "$GITHUB_STEP_SUMMARY"
echo "| Zcash PCZT contract | ✅ PASS |" >> "$GITHUB_STEP_SUMMARY"
echo "| Offline fixture integrity | ✅ PASS |" >> "$GITHUB_STEP_SUMMARY"
FIXTURE_SHA=$(sha256sum tests/txcache/manifest.json | cut -d' ' -f1)
echo "" >> "$GITHUB_STEP_SUMMARY"
printf 'Fixture manifest SHA-256: `%s`\n' "$FIXTURE_SHA" >> "$GITHUB_STEP_SUMMARY"

# ═══════════════════════════════════════════════════════════
# STAGE 2: TEST — pull published emulator, run pytest
# STAGE 2: TEST — build Bitcoin-only emulator, run pytest
# ═══════════════════════════════════════════════════════════

integration:
Expand All @@ -88,13 +95,14 @@ jobs:
submodules: recursive
path: python-keepkey

# python-keepkey is a SUBMODULE of the firmware repo, so the firmware is
# where the emulator lives. alpha is the fork's integration branch.
# This PR targets the 7.14.3 test line and is pinned by firmware PR #604.
# Build that product branch so the tests and firmware under review stay
# on the same compatibility surface.
- name: Checkout firmware
uses: actions/checkout@v4
with:
repository: BitHighlander/keepkey-firmware
ref: alpha
ref: release/7.14.3-bitcoin-only
path: keepkey-firmware

# NOT `submodules: recursive`. trezor-firmware carries a micropython
Expand All @@ -121,7 +129,8 @@ jobs:
timeout-minutes: 20
working-directory: keepkey-firmware
run: |
docker build -t kkemu-ci -f scripts/emulator/Dockerfile .
docker build --build-arg coinsupport=-DKK_BITCOIN_ONLY=ON \
-t kkemu-ci -f scripts/emulator/Dockerfile .

- name: Start the emulator
run: |
Expand All @@ -140,20 +149,27 @@ jobs:
pip install --upgrade pip
pip install "protobuf>=3.20,<4"
pip install -e .
pip install pytest semver rlp requests eth-keys pycryptodome
pip install pytest pytest-timeout semver rlp requests eth-keys pycryptodome

- name: Wait for emulator
run: |
echo "Waiting for emulator bridge on port 5000..."
ready=false
for i in $(seq 1 30); do
if curl -sf -X POST http://localhost:5000/exchange/main \
-H 'Content-Type: application/json' \
-d '{"data":""}' > /dev/null 2>&1; then
echo "Emulator ready after ${i}s"
ready=true
break
fi
sleep 1
done
[ "$ready" = true ] || {
docker logs kkemu
echo "FATAL: emulator bridge did not become ready" >&2
exit 1
}

# "The emulator answered a ping" is not "the emulator is the right
# firmware". CI ran a 7.16-era suite against a 7.10.0 image for five
Expand All @@ -167,8 +183,9 @@ jobs:
env:
KK_TRANSPORT_MAIN: "127.0.0.1:11044"
KK_TRANSPORT_DEBUG: "127.0.0.1:11045"
KK_MIN_FW: "7.15.0"
KK_MIN_FW: "7.14.3"
KK_UDP_TIMEOUT: "20"
KK_EXPECTED_VARIANT: "EmulatorBTC"
working-directory: keepkey-firmware/deps/python-keepkey/tests
run: |
python - <<'PY'
Expand All @@ -190,6 +207,10 @@ jobs:
sys.exit('FATAL: the emulator image predates the tests that run '
'against it. Republish kktech/kkemu from current '
'firmware and pin the new digest above.')
if f.firmware_variant != os.environ['KK_EXPECTED_VARIANT']:
sys.exit('FATAL: expected %s, got firmware variant %r' %
(os.environ['KK_EXPECTED_VARIANT'],
f.firmware_variant))
PY

# Step-level timeout, deliberately: a JOB-level timeout ends the job as
Expand All @@ -200,6 +221,7 @@ jobs:
KK_TRANSPORT_MAIN: "127.0.0.1:11044"
KK_TRANSPORT_DEBUG: "127.0.0.1:11045"
PYTHONPATH: "${{ github.workspace }}/keepkey-firmware/deps/python-keepkey"
PYTHONUNBUFFERED: "1"
# A crashed emulator now raises instead of blocking in recv() forever.
KK_UDP_TIMEOUT: "45"
run: |
Expand All @@ -209,15 +231,33 @@ jobs:
# firmware and they resolve; run them standalone and they fail
# claiming the sources are missing.
cd keepkey-firmware/deps/python-keepkey/tests
pytest -v --junitxml=junit.xml 2>&1 | tee pytest-output.txt
python tx_fixture_manifest.py --check
# Docker DNATs localhost-published packets before the filter OUTPUT
# chain, so they no longer have `lo` as their output interface. Keep
# only the emulator's two UDP ports reachable through the offline
# gate; every other new non-loopback connection remains rejected.
sudo iptables -I OUTPUT 1 ! -o lo -m conntrack --ctstate NEW -j REJECT
sudo iptables -I OUTPUT 1 -p udp -m multiport --dports 11044,11045 -j ACCEPT
cleanup_network_gate() {
sudo iptables -D OUTPUT -p udp -m multiport --dports 11044,11045 -j ACCEPT
sudo iptables -D OUTPUT ! -o lo -m conntrack --ctstate NEW -j REJECT
}
trap cleanup_network_gate EXIT
pytest -vv -s --timeout=60 --timeout-method=signal --maxfail=1 --junitxml=junit.xml 2>&1 | tee pytest-output.txt
echo "${PIPESTATUS[0]}" > status

- name: Test summary
if: always()
run: |
XML="keepkey-firmware/deps/python-keepkey/tests/junit.xml"
MANIFEST="keepkey-firmware/deps/python-keepkey/tests/txcache/manifest.json"
echo "## 🔑 KeepKey python-keepkey — Integration Tests" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
if [ -f "$MANIFEST" ]; then
FIXTURE_SHA=$(sha256sum "$MANIFEST" | cut -d' ' -f1)
printf 'Fixture manifest SHA-256: `%s`\n' "$FIXTURE_SHA" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
fi

if [ ! -f "$XML" ]; then
echo "❌ **No test results found** — suite may have crashed before completion." >> "$GITHUB_STEP_SUMMARY"
Expand Down
Loading
Loading