Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
190 commits
Select commit Hold shift + click to select a range
fabb1fe
fix: skip loading state on account page reload, enable prerelease ver…
hhanh00 Jul 21, 2026
4fd9c66
feat: re-enable ZSA support (#1164)
hhanh00 Jul 22, 2026
38a3838
feat: ZSA circuit separation — use vanilla PK for O2O, ZSA PK for iss…
hhanh00 Jul 23, 2026
9a6d304
feat: ZSA prover uses ORCHARD_ZSA_PK for all Nu7 txs, add pczt_replay…
hhanh00 Jul 24, 2026
314c281
feat: TransactionData.orchard_bundle uses OrchardBundle enum, ZSA PCZ…
hhanh00 Jul 25, 2026
69560cd
test: add block-mining wait loop after broadcast
hhanh00 Jul 25, 2026
0f75d5a
feat: TransactionData.orchard_bundle -> OrchardBundle enum, ZSA PCZT …
hhanh00 Jul 25, 2026
acc746e
test: add test_zsa_issuance — issue 1M ZSA units, finalize, verify in…
hhanh00 Jul 25, 2026
4514704
chore: replace path overrides with git revs for ZSA deps
hhanh00 Jul 25, 2026
28e2fca
test: add test_zsa_transfer — issue ZSA, then transfer to recipient
hhanh00 Jul 25, 2026
7af5c16
test: wait for 5 blocks after issuance in test_zsa_transfer
hhanh00 Jul 25, 2026
2aebcf5
feat: log per-pool spend/output counts before build_for_pczt
hhanh00 Jul 25, 2026
e959af7
chore: bump lrz rev for fee debug logging, add per-pool counts to plan
hhanh00 Jul 25, 2026
3391069
test: wait for 3 blocks instead of 5 after issuance
hhanh00 Jul 25, 2026
e1b8868
feat: PCZT-DUMP with enc_ciphertext length, per-pool counts, block-wa…
hhanh00 Jul 26, 2026
95c171b
chore: replace path overrides with git pinned revs for ZSA deps
hhanh00 Jul 26, 2026
850ad82
fix: complete ZSA PCZT transaction support
hhanh00 Jul 26, 2026
818efa9
chore: remove temporary ZSA diagnostics
hhanh00 Jul 26, 2026
42ed01c
fix: auto-pin db to coin=3 when filename contains 'zsa'
hhanh00 Jul 26, 2026
484563c
fix: remove cargo config
hhanh00 Jul 26, 2026
b42acbb
fix: improve error handling and diagnostics - fix IRW detection
hhanh00 Jul 26, 2026
329a1cf
fix: always select notes for privacy, with fee as tie-breaker
hhanh00 Jul 26, 2026
bebc3a5
fix: finalize new ZSA issuance
hhanh00 Jul 26, 2026
a611410
fix: retain ZSA notes below ZEC dust threshold
hhanh00 Jul 26, 2026
6550ad7
fix: hide ZSA reissuance flow
hhanh00 Jul 26, 2026
90a0286
fix: correct ZSA action fees and transaction summaries
hhanh00 Jul 27, 2026
dc85dc9
chore: remove stale code and debug test
hhanh00 Jul 27, 2026
c4b1cef
chore: update build number / release
hhanh00 Jul 27, 2026
158a330
chore(main): release zkool 6.25.0 (#1175)
hhanh00 Jul 27, 2026
fba04ef
chore: add entry for NSLocationWhenInUseUsageDescription
hhanh00 Jul 28, 2026
7059ac7
fix: ZSA dependency compatibility - Use production versions of lrz
hhanh00 Jul 28, 2026
a914344
fix: restore Ledger build compatibility
hhanh00 Jul 28, 2026
d6a7f4f
chore: update build number
hhanh00 Jul 28, 2026
973f86e
chore(main): release zkool 6.25.1 (#1178)
hhanh00 Jul 28, 2026
ecb0a61
feat: add toggle all notes button to invert lock state of every note
hhanh00 Jul 29, 2026
531e4d8
feat: add dust filter toggle for notes (hide ZEC notes <= 5000 zats)
hhanh00 Jul 29, 2026
b785872
feat: add group by pool toggle for notes view
hhanh00 Jul 29, 2026
3e63ea7
feat: add lock/unlock all button per pool section header
hhanh00 Jul 29, 2026
d025a94
feat: skip migration step when no new blocks since last broadcast
hhanh00 Jul 29, 2026
70ea752
chore: remove unused imports and variables
hhanh00 Jul 29, 2026
20707e0
chore: bump zebra and zkool versions in CI
hhanh00 Jul 29, 2026
11fe166
fix: add cancellation support for note migration
hhanh00 Jul 30, 2026
961a8a8
fix: confirm before leaving active migration
hhanh00 Jul 30, 2026
09ac425
fix: address review comments
hhanh00 Jul 30, 2026
e448ff4
feat: improve migration flow
hhanh00 Jul 30, 2026
412c1fa
chore: code reformatting only
hhanh00 Jul 30, 2026
71bab2b
feat: enhance migration with streaming and progress tracking
hhanh00 Jul 30, 2026
9759d6a
chore: update dependencies
hhanh00 Jul 30, 2026
85d17a1
fix: add error log printer utility
hhanh00 Jul 30, 2026
b28998e
feat: identify migration txs in history
hhanh00 Jul 30, 2026
995dd4d
chore: format generated Rust bindings
hhanh00 Jul 31, 2026
d4aae4d
feat: add one-shot Orchard migration
hhanh00 Jul 31, 2026
b004567
chore(main): release zkool 6.26.0 (#1186)
hhanh00 Jul 31, 2026
cef5160
fix: ironwood tx detection in mempool
hhanh00 Aug 1, 2026
ce74c2f
fix: refresh mempool keys after new blocks
hhanh00 Aug 1, 2026
2d6bdbe
chore(main): release zkool 6.26.1 (#1187)
hhanh00 Aug 2, 2026
aba4f30
fix: send to TEX (ZIP 320) addresses
hhanh00 Aug 12, 2026
ca49412
fix: honour RUST_LOG in zkool_graphql (#1190)
mladenmarkov Aug 13, 2026
b59f958
feat: Zcash voting (ZIP 262) delegation and vote casting (#1198)
hhanh00 Aug 14, 2026
59a5ed8
feat: add nym mixnet as transport (#1195)
rachyandco Aug 14, 2026
a83f655
fix: fix ios build
hhanh00 Aug 15, 2026
267b070
chore(main): release zkool 6.27.0 (#1200)
hhanh00 Aug 15, 2026
1e5564c
feat: shielded voting UI (ZIP 262)
hhanh00 Aug 15, 2026
1573230
ci: run rust tests on PRs and pushes to main
hhanh00 Aug 15, 2026
da834b2
refactor: pass memo explicitly to plugin process_memo
hhanh00 Aug 15, 2026
a58529d
fix: decode trailing escaped spaces in OA1 records
hhanh00 Aug 15, 2026
e2fb677
fix: save settings on nav away; resolve voting config from form value
hhanh00 Aug 15, 2026
6c8c98b
fix: surface voting config resolve errors instead of swallowing them
hhanh00 Aug 15, 2026
2e6f796
fix: persist ballot intents at cast time; parse option index
hhanh00 Aug 15, 2026
e5d0bad
chore: bump zcash_voting to async vote-tree transport rev
hhanh00 Aug 16, 2026
8da55a1
test: add unit tests for the coin voting module
hhanh00 Aug 16, 2026
0a7472c
feat: show voting power on voting confirmation and status pages
hhanh00 Aug 16, 2026
c48cf9e
fix: bundle sapling params in desktop and graphql builds
hhanh00 Aug 16, 2026
ed4b752
fix: run fresh voting submissions end-to-end (delegate + vote)
hhanh00 Aug 16, 2026
63acacb
fix: use app lightwalletd URL for fresh delegation prepare
hhanh00 Aug 16, 2026
c343a71
fix: exclude post-snapshot notes from delegation prepare
hhanh00 Aug 16, 2026
06ff09c
fix: auto-create the voting hotkey at delegation time
hhanh00 Aug 16, 2026
80a073b
fix: make delegation confirmation real and recoverable
hhanh00 Aug 17, 2026
c497c05
fix: use the async PIR client for delegation proving
hhanh00 Aug 17, 2026
f991e8c
feat: show friendly round titles and option labels in the voting UI
hhanh00 Aug 17, 2026
ab74456
fix: run the PIR connect inside the prove thread
hhanh00 Aug 17, 2026
57357ef
fix: parse the chain's string block heights; prove with voting-circui…
hhanh00 Aug 17, 2026
7e2a4d6
fix: cast one proposal at a time so the vote VAN chains
hhanh00 Aug 17, 2026
4ead4da
fix: fall back to the configured vote servers for helper shares
hhanh00 Aug 17, 2026
1129f34
fix: honest done label when only time-scheduled steps remain
hhanh00 Aug 17, 2026
5db3025
feat: show per-vote on-chain evidence on the done and confirmation sc…
hhanh00 Aug 17, 2026
ab4c990
chore: pin dependency patches to pushed git revs
hhanh00 Aug 17, 2026
52f3c86
feat: show proposal title and selection in the ballot evidence
hhanh00 Aug 17, 2026
4fcaa22
fix: render option labels with vote-sdk ids, not 1-based positions
hhanh00 Aug 17, 2026
8811c97
fix: key ballot evidence proposals by id, not list position
hhanh00 Aug 17, 2026
87c6be3
fix: resolve share-window timing from the chain round status
hhanh00 Aug 17, 2026
c61dd21
fix: submit helper shares from the confirmed votes' payloads
hhanh00 Aug 17, 2026
0054892
chore: regenerate FRB bindings for the share payload/plan FRBs
hhanh00 Aug 17, 2026
dfd5db0
fix: parse vote-sdk tally entries per-entry decision and amount
hhanh00 Aug 17, 2026
e15bafc
feat: show proposal titles and option labels in the tally results
hhanh00 Aug 17, 2026
7b97c6a
fix: tally entries without a decision key are decision 0, not a total
hhanh00 Aug 17, 2026
fb449a8
feat: results page title shows the round title
hhanh00 Aug 17, 2026
ca013ad
fix: don't re-send recorded shares; refresh status after tracking
hhanh00 Aug 17, 2026
8404323
feat: gate voting round actions on chain status; zero tally for votel…
hhanh00 Aug 17, 2026
3fdeea0
fix(ledger): transparent-only signing + NU6.3 v5 workaround for hardw…
bu5hm4nn Aug 17, 2026
f46f650
fix: support flutter 3.47 (intl 0.20.3); fixed 6.2.0 rename scale→dec…
hhanh00 Aug 18, 2026
c791f7f
fix: pass one connection through voting DB reads; stop pool stalls on…
hhanh00 Aug 18, 2026
ca86e2c
feat: ballot page AppBar shows the round title
hhanh00 Aug 18, 2026
f056f50
fix: batch-load voting sessions on one pool connection; keep the pool…
hhanh00 Aug 18, 2026
aca790c
fix: build with Flutter 3.47.0
hhanh00 Aug 18, 2026
891ff2d
fix: bump Kotlin to 2.2.20 for Flutter 3.47.0 Android build
hhanh00 Aug 18, 2026
85442d2
chore: update CONTRIBUTING file
hhanh00 Aug 18, 2026
4728be6
add ironwood pool to diversifier index resolve/backfill (#1213)
macintoshhelper Aug 18, 2026
f22a316
fix: drop redundant pool predicate from diversifier index backfill
hhanh00 Aug 18, 2026
ba14db4
fix: stop ref use after unmount when closing Folders page (issue 1203)
hhanh00 Aug 18, 2026
f291d65
fix(voting): keep back navigation to account after vote submission
hhanh00 Aug 18, 2026
bed8131
fix(settings): keep transport selector within screen width (FittedBox…
hhanh00 Aug 19, 2026
a7b4238
ci: bump CI Flutter version to 3.47.1
hhanh00 Aug 19, 2026
1a9bc99
fix(voting): default vote node URL to the vote chain server when unset
hhanh00 Aug 20, 2026
e8e9f22
fix(account): derive sapling address on file import and fail fast on …
hhanh00 Aug 20, 2026
ad7ad08
feat(voting): resumable recovery across network, server, and client f…
hhanh00 Aug 22, 2026
294e71f
fix(voting): recovery edge cases found in live testing
hhanh00 Aug 22, 2026
299232f
chore: update build number
hhanh00 Aug 23, 2026
99734a4
chore(main): release zkool 6.28.0 (#1223)
hhanh00 Aug 23, 2026
9dd6cb2
chore: update ios provisioning profile
hhanh00 Aug 23, 2026
2b59628
fix(voting): remove sticky last-working server from share failover
hhanh00 Aug 26, 2026
070ec89
fix(nym): make large syncs over the mixnet reliable (#1219)
rachyandco Aug 26, 2026
1752e9d
fix(proxy): pass SOCKS5 credentials from proxy URL to tokio-socks
hhanh00 Aug 27, 2026
545cf9b
chore(main): release zkool 6.28.1 (#1227)
hhanh00 Aug 27, 2026
277929a
feat(vault): sign out of Google when Cloud Vault is turned off
hhanh00 Aug 27, 2026
deff307
fix(frost): report DKG round 0 and broadcast statuses in the UI (#1230)
hhanh00 Aug 27, 2026
6ef0e7a
test(dkg): add Flutter UI DKG integration test
hhanh00 Aug 27, 2026
381bb1d
fix(pay): serialize PCZTs with bincode standard() for interop
hhanh00 Aug 27, 2026
f7d18ac
test(frost): add Flutter UI FROST signing integration test
hhanh00 Aug 27, 2026
11a66aa
docs(skills): cover the FROST signing UI test, rename to frost-ui-tests
hhanh00 Aug 28, 2026
f44c220
fix(sync): guard fetch_tx_details with the SYNCING lock
hhanh00 Aug 28, 2026
0d0bbe3
fix(frost): sync inside doDkg/doSign and hold off autosync
hhanh00 Aug 28, 2026
f80f27a
fix(frost): lock spent notes at broadcast to stop duplicate-nullifier…
hhanh00 Aug 29, 2026
ef4db48
fix(migrate): stop migration stalling on Orchard totals of 0.005-0.00…
hhanh00 Aug 30, 2026
d6ec0b5
chore(pay): demote the extracted transaction hex to debug
hhanh00 Aug 30, 2026
3745ec8
test(migrate): cover Orchard->Ironwood migration end-to-end on regtest
hhanh00 Aug 30, 2026
623ded0
feat(frost): drive DKG and signing from autosync instead of self-sync…
hhanh00 Aug 31, 2026
e41ac43
test(pay): add unit tests for plan_transaction coin selection (#1238)
hhanh00 Sep 1, 2026
afd46d2
chore(main): release zkool 6.29.0 (#1239)
hhanh00 Sep 1, 2026
7639054
feat(account): collapse pool balances on tap, persisted in DB settings
hhanh00 Sep 1, 2026
694a5c2
fix(vote): show ballot proposals immediately instead of after the vot…
hhanh00 Sep 2, 2026
059e980
fix: scope witness consistency check to synced accounts
hhanh00 Sep 3, 2026
abc24fc
test: add speculos-based Ledger emulator setup
hhanh00 Sep 3, 2026
2d893b9
ci: add manual-only Ledger emulator workflow
hhanh00 Sep 3, 2026
c2e22d1
ci: install protobuf-compiler for ledger tests
hhanh00 Sep 3, 2026
1588b96
feat: support multiple Ledger app types (Official, Zondax) (#1242)
hhanh00 Sep 4, 2026
26d4668
ci: take ledger emulator seed from SEED secret
hhanh00 Sep 4, 2026
ae6de55
feat: import Official Ledger UFVK from the device
hhanh00 Sep 4, 2026
121b51d
fix: build v6 for Official Ledger accounts and open the APDU HID inte…
hhanh00 Sep 4, 2026
6b353cf
chore: drop per-tx mempool debug log
hhanh00 Sep 4, 2026
1128d2c
ci: bump CI Flutter version to 3.47.2
hhanh00 Sep 4, 2026
e6e462c
feat: sign v6 transactions with the Official Ledger app
hhanh00 Sep 4, 2026
cd79c02
fix: force internal change for Official Ledger accounts
hhanh00 Sep 4, 2026
1e03b2f
fix: derive shielded output addresses in the transaction plan
hhanh00 Sep 4, 2026
599c223
fix: make app error messages selectable
hhanh00 Sep 4, 2026
f37e1b6
fix: lock Use Internal Change per Ledger app and avoid empty pools se…
hhanh00 Sep 4, 2026
f792285
feat: create Ledger accounts and sign via zkool_graphql
hhanh00 Sep 5, 2026
883dd62
ci: run the Official Ledger emulator tests
hhanh00 Sep 5, 2026
6e757f8
fix: pass the account id explicitly when signing on the server
hhanh00 Sep 5, 2026
eb3d89d
fix: tag the transparent change output with its derivation
hhanh00 Sep 5, 2026
5ff1ec6
test: gate Ledger tests on the app home screen
hhanh00 Sep 5, 2026
cc51e2f
fix: keep transparent change addresses paired with external addresses
hhanh00 Sep 5, 2026
ad51493
feat: gate the Nym transport behind a cargo feature
hhanh00 Sep 5, 2026
1749b86
fix: advance account dindex after the transparent scan
hhanh00 Sep 5, 2026
b09842e
fix: stop the transparent scan only after consecutive unused addresses
hhanh00 Sep 5, 2026
c6572f3
fix: include Ironwood in Unshield All
hhanh00 Sep 5, 2026
0fefa11
fix: restart autoSync immediately when the interval becomes positive
hhanh00 Sep 5, 2026
f2005e9
fix: select and sync a newly restored account
hhanh00 Sep 8, 2026
d7c455d
chore(main): release zkool 6.30.0 (#1249)
hhanh00 Sep 12, 2026
625f3d2
chore: restore prerelease rc config for release-please
hhanh00 Sep 14, 2026
2a7c90c
cake wallet patch
MrCyjaneK May 16, 2026
c8f1282
pay: add prove_and_finalize for externally signed PCZTs
Aug 5, 2026
b17dcd5
pay: identify transparent inputs the way an external signer expects
Aug 7, 2026
be2d46b
pay: claim shielded spends for an external signer
Aug 7, 2026
586e5f1
Translate PCZTs across the Keystone wire dialect
Aug 7, 2026
cb978e3
Take only the signatures out of a Keystone's reply
Aug 8, 2026
0904fc4
Expose the fee already recorded for a transaction
Aug 8, 2026
6393cb9
Name the recipient of every transparent output
Aug 8, 2026
1035f37
keystone: batch PCZT signing (zcash-sign-batch / zcash-batch-sig-result)
Aug 9, 2026
f32739f
keystone batch: strip spend-auth sigs from the request
Aug 9, 2026
b637fb0
ledger: drive the Official Zcash app from Flutter over any transport
Sep 16, 2026
5cefa04
cargokit: stop injecting the zcash_unstable=nu7 cfg
Sep 16, 2026
ac32ca1
tests: drop the PCZT cross-version probe and encoding dump
Sep 16, 2026
2e6291d
Record cyjan-2026-08-08 as merged
Sep 16, 2026
0c0c9b3
keystone_wire: speak the upgraded pczt encoding to Keystone and Cupcake
Sep 16, 2026
2c79200
ledger: send the PCZT's own header fields, stop on an empty key chunk
Sep 16, 2026
aeb698d
ledger: report "Confirm on your Ledger" once the device can show its …
Sep 16, 2026
d34590e
ledger: show the account address on the device so the imported key ca…
Sep 17, 2026
67a2513
ledger: report signing only once the device has returned a signature
Sep 17, 2026
8083636
ledger: say "Confirm on your Ledger" before the final packet, not aft…
Sep 17, 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
15 changes: 15 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' | { read -r cmd; case \"$cmd\" in *\"git commit\"*|*\"git push\"*) echo '{\"continue\":false,\"stopReason\":\"git commit/push requires explicit user instruction — use \\\"commit\\\" or \\\"push\\\" to proceed\"}';; *) echo '{\"continue\":true}'; esac; }"
}
]
}
]
}
}
222 changes: 222 additions & 0 deletions .claude/skills/frost-ui-tests/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
---
name: frost-ui-tests
description: "Run the Flutter-UI FROST integration tests (tests/test_dkg_ui.py for DKG, tests/test_frost_ui.py for signing) on a local zebra regtest chain, and optionally screen-record the app window. Use when asked to run, debug, or re-record either UI test, or to bring up the local regtest + lightwalletd + zkool_graphql stack they need."
---

# Flutter UI FROST integration tests

Two tests run the **real Flutter app** as one FROST participant while the others
are headless `zkool_graphql` instances:

| test | what it covers | runtime (warm) |
|---|---|---|
| `tests/tests/test_dkg_ui.py` | 3-of-3 DKG through `/dkg1 → /dkg2 → /dkg3` | ~3.5 min |
| `tests/tests/test_frost_ui.py` | DKG, then signing through `/frost1 → /frost2`, asserting the receiver is actually paid | ~5.5 min |

The Dart halves live in `integration_test/`, sharing `support.dart` (rendezvous,
pumping helpers, wallet setup, and `driveDkg` — signing needs a shared key
before it can start).

`test_dkg.py` / `test_frost.py` are the all-headless equivalents; run those
first to prove the stack before blaming the UI tests.

In both, the app is participant #1 and pytest owns everything else: the chain,
the funding wallet, and the peers. It spawns `flutter test` as a subprocess and
the two sides exchange values through JSON files in the app's documents
directory. In the signing test participant #2 coordinates, so the app exercises
the plain-signer path.

## Prerequisites

Binaries not in the repo (this machine has them under `~/projects/tools/bin`):

```bash
export PATH="$HOME/projects/tools/bin:$PATH" # zebrad, lightwalletd
```

Build the GraphQL server used for the peers (release; ~25 min from cold):

```bash
cd rust
cargo build --release --bin zkool_graphql --features=graphql,bundled-sapling-params
```

macOS: the app must have been launched at least once so its sandbox container
exists at `~/Library/Containers/cc.methyl.zkool/Data/Documents`.

## 1. Bring up the regtest chain

Blocks are **not** mined automatically — `misc/zebra.toml` sets only
`miner_address`, zebra's internal miner is off. Every block comes from an
explicit `generate` RPC call.

```bash
cd ~/projects/zkool2
export PATH="$HOME/projects/tools/bin:$PATH"

# Full reset (chain + all test data)
pkill -9 zkool_graphql; pkill lightwalletd; pkill zebrad
rm -rf ~/Library/Caches/zebra ./data ./regtest.db
rm -f ~/Library/Containers/cc.methyl.zkool/Data/Documents/regtest_dkg_ui.db
rm -f ~/Library/Containers/cc.methyl.zkool/Data/Documents/regtest_frost_ui.db
rm -rf ~/Library/Containers/cc.methyl.zkool/Data/Documents/dkg_ui_rendezvous

# zebra.toml needs a miner address (local edit, do not commit)
sed -i '' 's#miner_address = ""#miner_address = "tmQ1BiNRfsvT6eMkJ5n7nMZsbz1PGwCs1Zs"#' misc/zebra.toml

nohup zebrad -c misc/zebra.toml start > zebrad.log 2>&1 &
until curl -sf -m 3 --data-binary '{"jsonrpc":"1.0","id":"p","method":"getinfo","params":[]}' \
-H 'content-type: application/json' http://127.0.0.1:18232/ >/dev/null; do sleep 2; done

mkdir -p ./data/regtest
nohup lightwalletd --no-tls-very-insecure --data-dir=./data/regtest \
--grpc-bind-addr=127.0.0.1:8137 --zcash-conf-path=./misc/zebra.conf \
--log-file=/dev/stdout > lightwalletd.log 2>&1 &
until nc -z -w 2 localhost 8137; do sleep 2; done

# Mine past NU6.3 / Ironwood, which activates at height 250 on regtest
curl -s --data-binary '{"jsonrpc":"1.0","id":"g","method":"generate","params":[350]}' \
-H 'Content-type: application/json' http://127.0.0.1:18232/ | jq '.result|length'
```

## 2. Fund the SEED wallet

`example/sh/regtest_setup.sh` does chain bring-up *and* funding in one go. If the
chain is already up, run only the funding half: start `zkool_graphql` on :8000
against `regtest.db`, create the `miner` (MINER_SEED) and `wallet` (SEED)
accounts at birth 1, sync both, take the miner's notes with
`height < tip-100`, pay the total to `DESTINATION_ADDRESS` with
`recipientPaysFee: true, confirmations: 100`, mine 10, sync, and check
`balanceByAccount.ironwood > 0` (expect ~62.5).

Seeds and the destination UA are inlined at the top of `example/sh/regtest_setup.sh`.

## 3. Run the test

```bash
cd tests
export SEED="invite couch cloud pave stuff cabbage usual rigid dragon warm cable price fame warfare next swallow worth opera suggest flame patch undo position arctic"
.venv/bin/python -m pytest tests/test_dkg_ui.py -v -s # DKG only
.venv/bin/python -m pytest tests/test_frost_ui.py -v -s # DKG + signing
```

Expect ~3.5 min warm; the first run adds a macOS debug build of the app plus the
Rust staticlib. Logs: `/tmp/dkg_ui_flutter.log` (Flutter side, dumped by pytest on
failure) and `/tmp/graphql_8002.log` / `/tmp/graphql_8003.log` (peers).

Watch progress without touching the app's database:

```bash
sed 's/\x1b\[[0-9;]*m//g' /tmp/dkg_ui_flutter.log | grep -a "dkg-ui] status"
```

Expected DKG sequence:

```
Broadcasting participant keys
Waiting for other participants to send their keys
Broadcasting round 1 packages
Waiting for other participants to send their round 1 packages
Broadcasting round 2 packages
The shared address is: uregtest1...
```

`test_frost_ui.py` continues past that into the signing rounds. Participant #2
coordinates, so the app is a plain signer:

```
Sending our commitments to the coordinator
Waiting for the signing package from the coordinator
Sending our signature share to the coordinator
Signing completed
```

It ends by polling the receiver's balance until it reads `0.05000000`, i.e. the
multisig actually spent — not just UI states. The `flutter test` log for signing
is `/tmp/frost_ui_flutter.log`.

## Things that will bite you

- **Never query the app's SQLite file while the test runs.** It is in rollback-journal
mode, and a concurrent reader causes `database is locked` errors inside the app.
- **The db filename must contain `regtest`** — that substring is what selects
`Network::Regtest` (`rust/src/api/coin.rs:266`). Without it the app runs mainnet
parameters.
- **The macOS app is sandboxed** and cannot read or write `/tmp`; the rendezvous dir
and the UI participant's db must live in the container's Documents directory.
- **Do not `osascript -e 'tell application "zkool" to activate'`** — it launches
`/Applications/zkool.app` (the real mainnet wallet), which shares the bundle id
and container with the Debug build and breaks the run (`flutter test` exits 79).
Raise the test app by process only: `tell application "System Events" to set
frontmost of process "zkool" to true`, which needs Accessibility for Terminal.
- **Mining is on demand**, driven by `demand_miner()` in `tests/tests/dkg.py`: it
polls `getrawmempool` and mines one block whenever a transaction is waiting, with
a 60s idle fallback. Do not go back to a fixed-interval miner — it makes the run
non-deterministic.
- **The app polls every 30s** (`Timer.periodic` in `DKGPage3`, `lib/pages/dkg.dart`)
while the peers advance on every block, so the app is usually a round behind. The
test waits up to `PEER_COMPLETION_TIMEOUT` (600s) for the peers to finish *after*
the app is done — without that wait the test fails with "No FROST account for
participant 2".
- **Never use `pumpAndSettle`** on the DKG or signing routes; DKGPage3 and
FrostPage2 both run a 30s timer and the synchronizer keeps frames scheduled, so
the tree never settles. Use the `pumpUntil` / `pumpFor` helpers.
- **Leave the DKG page with `go`, not `push`.** DKGPage3 cancels its timer only in
`dispose`, so a page left mounted keeps calling `doDkg` and throws
`get_funding_account: no rows` as soon as the selected account moves to the
FROST account. This is why the signing test does `appRouter.go("/accounts")`
after the DKG finishes.
- **A PCZT must be byte-identical for every signer**, and it crosses the
app/zkool_graphql boundary in the signing test. That only works because both
now use bincode `standard()` — the app used `legacy()` until
`fix(pay): serialize PCZTs with bincode standard() for interop`. If a signing
test starts failing at `unpackTransaction`, check that first.
- **FrostPage1 reads `frostParams` off the *current* account**, so the FROST
account has to be selected (`coinContext.setAccount` plus
`selectedAccountIdProvider`) before navigating to `/frost1`, and the PCZT is
passed as the route `extra`.
- **FrostPage2 renders its status in a plain `Text`**, not the `CopyableText`
DKGPage3 uses, so the two tests read the status differently.

## Screen-recording the run (macOS)

Requires Accessibility for Terminal (System Settings → Privacy & Security →
Accessibility) so the window can be raised. A local, uncommitted block in
`macos/Runner/MainFlutterWindow.swift` forces the window to 1100x820 and sets
`isRestorable = false`; it must run **after** `super.awakeFromNib()`, or macOS
state restoration reapplies the old near-fullscreen frame.

```bash
# once the app is up
osascript -e 'tell application "System Events" to set frontmost of process "zkool" to true'
osascript -e 'tell application "System Events" to tell process "zkool" to get {position, size} of front window'
# -> e.g. 305, 75, 1100, 850 (points, not pixels)

screencapture -v -R305,75,1100,850 /tmp/rec.mp4 & # region capture: app window only
# re-raise every few seconds while the run proceeds, then:
kill -INT <screencapture pid> # SIGINT finalizes the mp4

ffmpeg -i /tmp/rec.mp4 -vf "scale=1100:-2,fps=12" -c:v libx264 -crf 30 \
-pix_fmt yuv420p /tmp/dkg_ui.mp4
```

Trim the tail: when the test ends the app closes and the recorded region exposes
whatever was behind it. The Dart test holds the finished screen for 6s
(`pumpFor`) so the Finalize step and shared address are visible.

## Teardown

```bash
pkill -f zkool_graphql; pkill lightwalletd; pkill zebrad
rm -rf ~/Library/Caches/zebra ./data ./regtest.db
git checkout misc/zebra.toml # drops the local miner_address edit
```

## CI

`.github/workflows/wallet.yml` runs on `ubuntu-latest` and includes neither
test. Porting it needs a desktop Flutter build plus a display (`-d linux` under
`xvfb-run`, GTK dev packages) on top of the existing regtest stack.
`app_documents_dir()` and `flutter_device()` in `tests/tests/dkg.py` are already
platform-switched for this, but the Linux path is **untested** — only macOS has
been verified.
2 changes: 1 addition & 1 deletion .github/actions/linux/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ runs:
- name: Build
shell: bash
run: |
./misc/mkcargokit_options.sh ledger > rust/cargokit.yaml
./misc/mkcargokit_options.sh "ledger,bundled-sapling-params" > rust/cargokit.yaml
fastforge package --platform=linux --targets=deb,appimage
- name: Build Flatpak
if: ${{ inputs.arch == 'x86_64' && github.event_name != 'pull_request' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/mac/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ runs:
- name: Build
shell: bash
run: |
./misc/mkcargokit_options.sh ledger > rust/cargokit.yaml
./misc/mkcargokit_options.sh "ledger,bundled-sapling-params" > rust/cargokit.yaml
flutter build macos
- name: Notarization
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/windows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ runs:
export PUB_CACHE="$RUNNER_TEMP/.pub-cache"
dart pub global activate fastforge
echo "$RUNNER_TEMP/.pub-cache/bin" >> $GITHUB_PATH
./misc/mkcargokit_options.sh ledger > rust/cargokit.yaml
./misc/mkcargokit_options.sh "ledger,bundled-sapling-params" > rust/cargokit.yaml
- name: Build
shell: powershell
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/actions/zebra/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ runs:
with:
path: |
./tools/bin
key: ${{ runner.os }}-zebra-lwd-6.0.0-rc.0
key: ${{ runner.os }}-zebra-lwd-6.2.1

- name: Install zebra & zaino
if: steps.cache-zebra.outputs.cache-hit != 'true'
shell: bash
run: |
sudo apt update && sudo apt install -y libclang-dev clang
rm -rf ./tools
cargo install --git https://github.com/ZcashFoundation/zebra --tag v6.0.0-rc.0 --features=internal-miner --root ./tools zebrad
cargo install --git https://github.com/ZcashFoundation/zebra --tag v6.2.1 --features=internal-miner --root ./tools zebrad
git clone https://github.com/zecrocks/lightwalletd.git
cd lightwalletd
git checkout 9b69519c57785e04e92a16365483f869dd878700
Expand All @@ -34,14 +34,14 @@ runs:
- name: Install zkool
if: steps.cache-zebra.outputs.cache-hit != 'true'
shell: bash
run: cargo install --git https://github.com/hhanh00/zkool2 --tag zkool-v6.24.0-rc.21 --features=graphql --root ./tools --force --bin zkool_graphql
run: cargo install --git https://github.com/hhanh00/zkool2 --tag zkool-v6.25.1 --features=graphql --root ./tools --force --bin zkool_graphql

- name: Save cache
if: steps.cache-zebra.outputs.cache-hit != 'true'
uses: actions/cache/save@v5
with:
path: ./tools/bin
key: ${{ runner.os }}-zebra-lwd-6.0.0-rc.0
key: ${{ runner.os }}-zebra-lwd-6.2.1

- name: Install config
if: github.repository != 'hhanh00/zkool2'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-graphql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
sudo apt-get update
sudo apt-get install -y pkg-config libudev-dev
cd rust
cargo build --release --bin zkool_graphql --features=graphql
cargo build --release --bin zkool_graphql --no-default-features --features=graphql,bundled-sapling-params
- name: Create Release
if: startsWith(github.ref_name, 'zkool-v')
uses: softprops/action-gh-release@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- os: windows-latest
target: windows
env:
FLUTTER_VERSION: 3.44.2
FLUTTER_VERSION: 3.47.2
permissions:
id-token: write
attestations: write
Expand Down
Loading