testing library

Test-support library for hosts embedding the wallet UI: the fakes needed to pump wallet surfaces in widget tests without the native library — FakeWalletSession (a scripted WalletSession) and the fake onboarding seams (provisioner / store / screen-security). DELIBERATELY free of any flutter_test import, so depending on it never constrains a consumer's test-framework solve; import it from test code only.

Classes

FakeOnboardingStore
An in-memory OnboardingStore. Backs the backup-confirmed flag; can be made to throw on persist to exercise the gate-stays-closed path. Seedable so a "previous launch" state (a confirmed or unconfirmed prior wallet) is set up.
FakeRevealAuthorizer
A recording WalletRevealAuthorizer for host-VM tests — proves the reveal re-auth seam from the outside: the backup screen must route every reveal through authorizeReveal and MUST NOT read the recovery words when re-auth is denied or faults (pair with FakeWalletProvisioner's revealCount).
FakeScreenSecurity
A host-VM fake ScreenSecurity — counts the backup screen's protection requests so a widget test can assert it engages on show and releases on dispose. isScreenshotBlockSupported is configurable so a test can drive both the Android (block) and the elsewhere (advise-a-private-setting) copy.
FakeSendAuthorizer
A recording WalletSendAuthorizer for host-VM tests — proves the seam's contract from the outside: every money-committing action routes through authorizeSpend EXACTLY ONCE (see intents), and a denial (denyAll) reaches the controller BEFORE any bridge call (pair with the fake session's call counters).
FakeWalletProvisioner
A host-VM fake WalletProvisioner — no native library, no device. Drives the OnboardingController state machine deterministically: configure what is on disk, make any step succeed or throw a TYPED failure, and count calls.
FakeWalletSession
A host-VM fake for WalletSession — no native library, no device. It mirrors the real watchSyncStatus contract (CURRENT status emitted on subscribe) and gives tests direct handles to drive the live stream (push / error / complete) and to count subscribes, cancels, snapshots, and start/stop calls.
FakeWalletSettingsStore
An in-memory WalletSettingsStore for tests — scripted reads (parkable via readGate to pin the loading-window rules) and recorded writes (so a test proves persist-then-publish and the failed-write honesty).
TestLifecycleNotifier
A controllable appLifecycleProvider override for DETERMINISTIC lifecycle tests. Overriding the provider bypasses the platform binding entirely — no handleAppLifecycleStateChanged transition-legality, no AppLifecycleListener coalescing across pump boundaries (both of which make binding-driven hides flaky and unable to distinguish "this state is not a trigger" from "the event never fired"). emit drives the state directly so a ref.listen fires for exactly the state asked for. Subclasses the real AppLifecycleNotifier (so it matches the provider's overrideWith type) but overrides build to NOT register the platform AppLifecycleListener — the binding plays no part.

Properties

defaultSendProposalBinding → Uint8List
The deterministic FR-17 spend-binding nonce sendProposalFixture (and via it shieldProposalFixture) defaults to — distinct from defaultSwapQuoteBinding so a test that mixes a proposal and a quote can tell whose bytes reached a seam.
final
defaultSwapQuoteBinding → Uint8List
The deterministic FR-17 spend-binding nonce swapQuoteFixture defaults to — distinct from defaultSendProposalBinding so a test that mixes a proposal and a quote can tell whose bytes reached a seam.
final
testBip39Wordlist → Bip39Wordlist
A tiny BIP39 wordlist fixture for the restore widget tests — just the words the tests use (sorted, lowercase, like the real bundled asset). The restore field's live validity/autocomplete reads this; the SDK is still the real gate. Restore harnesses override bip39WordlistProvider with this so validity is deterministic (every test word reads valid → the count-only gate applies).
final

Functions

balanceFixture({int spendableZat = 0, int pendingIncomingZat = 0, int pendingChangeZat = 0, int transparentZat = 0, int totalZat = 0}) → BalanceSnapshot
ephemeralSweepSummaryFixture({int scanned = 1, int swept = 1, int recoveredZat = 250000, int failed = 0, int truncated = 0}) → EphemeralSweepSummary
A neutral EphemeralSweepSummary for recovery-sheet tests (2e-2b-v-2). Defaults to a clean funded recovery (one address swept, nothing failed or truncated); override to model partial faults / a heavy-wallet truncation.
inFlightSendFixture({int amountZat = 80000, int createdAt = 1700000000}) → InFlightSend
An in-flight two-step row (#309) — first leg broadcast, send not complete; drives the durable "on its way — don't send it again" cue.
parkedSendFixture({int id = 7, ParkedSendKind kind = ParkedSendKind.twoStep, int amountZat = 70000, int createdAt = 1700000000, bool paused = false, bool sending = false, Uint8List? binding, SigningBlock? signingBlock}) → ParkedSend
A neutral ParkedSend for "saved & pending" surface tests (2e-2b-v-3) — amount-only, with an id + enqueue timestamp the cancel flow passes back. Defaults to the two-step (one-time-address) kind, the surface's original shape; pass ParkedSendKind.singleStep for a plainly-queued offline send (#331 — the same surface carries both).
sendProposalFixture({int proposalId = 1, int totalZat = 100500, int feeZat = 500, int changeZat = 0, bool hasTransparentRecipient = false, bool isShield = false, bool isTwoStepTex = false, List<ProposalStep>? steps, LargeSendReason? largeSend, bool selfSend = false, int? singleRecipientZat = 100000, Uint8List? binding}) → SendProposal
A neutral SendProposal for tests — override only what a case cares about. Defaults to a single shielded (Orchard) recipient (no de-shield disclosure).
shieldProposalFixture({int proposalId = 42, int totalZat = 500000, int feeZat = 15000}) → SendProposal
A neutral SHIELD SendProposal for Recv-3 tests — isShield == true, NO transparent recipient (privacy-positive), gross/fee/net consistent (changeZat == totalZat - feeZat), the lone output in the shielded pool.
swapQuoteFixture({String id = 'swap-1', String depositAddress = 'tdeposit', String? depositMemo, int expiresAt = 2000000000, String amountIn = '0.5', String minAmountOut = '49.5', int zecSideZat = 50000000, String? refundTo, bool deshields = true, bool endsShielded = false, bool providerLegsTransparent = true, List<DisclosureItem> providerSees = const [DisclosureItem.amounts, DisclosureItem.destinationAddress], Uint8List? binding}) → SwapQuote
A neutral SwapQuote for tests — override only what a case cares about. Defaults to an OutOfZec-shaped quote (a de-shielding deposit) so the disclosure carries the privacy-critical flags a swap review must render.
swapRecordFixture({String id = 'swap-record-1', SwapRecordDirection direction = SwapRecordDirection.outOfZec, int createdAt = 1700000000, int? depositDeadline = 4100000000, int expiresAt = 4100172800, SwapOutcome? outcome}) → SwapRecord
A durable in-flight swap row (W-swap-5, #366) — drives the wallet-screen swap home + the guard-fault "view swap" re-attach. Defaults to OutOfZec (the armed-deposit shape the hardware photo showed invisible).
swapTokenListFixture({List<SwapToken>? tokens, bool fresh = true}) → SwapTokenList
A neutral SwapTokenList for IntoZec picker tests — two plausible source assets, fresh by default. Override fresh: false to model serve-stale, or tokens: const [] (fresh) to model the honest "no assets available" state.
txSummaryFixture({String txidHex = 'aa00000000000000000000000000000000000000000000000000000000000000', int? minedHeight = 100, TxStatus status = const TxStatus.confirmed(depth: 5), int netAmountZat = 250000, int? feeZat, bool hasMemo = true, bool hasTransparentOutput = false, int? timestamp = 1700000000}) → TxSummary
A neutral TxSummary history row for tests (FR-1) — override only what a case cares about. Defaults to a confirmed incoming tx with a memo.
walletStateFixture({SyncStatus syncStatus = const SyncStatus.idle(), TorState tor = const TorState.off(), BalanceSnapshot? balance, int? tip, SyncStamp? lastSynced, bool everSynced = false, bool rescanRebuilding = false, int seq = 0}) → WalletState
A complete, neutral WalletState for tests — override only what a case cares about. PlatformInt64 is int on the host VM (web is out of scope for this SDK), so plain int literals construct the money fields.