feat(demo): funded-wallet restore + build-arg fixes

Adds DEMO_WALLET_SEED/DEMO_WALLET_HEIGHT support so a demo build restores a
fixed (throwaway, funded) Wownero wallet instead of creating a fresh one, via
WalletRestoreViewModel.create. Balance lives on-chain against the seed, so it
survives any emulator wipe and is reproducible.

Three real bugs fixed on the way:
- build-apk.sh built the --dart-define args as a word-split string; the 16-word
  seed's internal spaces split into separate argv tokens and flutter treated a
  seed word as a build target ("Target file '<word>' not found"). Now a bash
  array keeps each --dart-define one token.
- WalletRestoreViewModel.getCredentials reads name/passphrase from the options
  MAP (not the vm field) and casts name as non-null String, so the restore
  options must include 'name' and 'passphrase'.
- forward DEMO_WALLET_SEED/HEIGHT into the build container; source demo.env.

Verified end to end: demo build restores the wallet, its address matches the
funded one exactly (QR-decoded), it syncs at height 861800, and the dashboard
shows the real 13.37 WOW balance + tx history. Send shows Max 13.37.

The seed lives only in gitignored tools/demo/demo.env (never committed).
docs/internal-notes.md (gitignored) documents the FailedDecryption gotcha.
This commit is contained in:
jwinterm
2026-08-03 13:53:13 -04:00
parent 4dd15704b0
commit 2afcf010e1
3 changed files with 62 additions and 6 deletions
+23 -6
View File
@@ -19,6 +19,10 @@
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# Pull in local capture config (DEMO_WALLET_SEED/HEIGHT/PIN). Gitignored.
_DEMO_ENV="$(dirname "${BASH_SOURCE[0]}")/demo.env"
if [[ -f "$_DEMO_ENV" ]]; then set -a; . "$_DEMO_ENV"; set +a; fi
IMAGE="${CI_IMAGE:-ghcr.io/cake-tech/cake_wallet:debian13-flutter3.32.0-ndkr28-go1.24.1-ruststablenightly}"
BUILD_MODE="${BUILD_MODE:-debug}"
ABI="${ABI:-x86_64}"
@@ -47,6 +51,8 @@ docker run --rm \
-e TARGET_PLATFORM="$TARGET_PLATFORM" \
-e DEMO="${DEMO:-0}" \
-e DEMO_PIN="${DEMO_PIN:-0801}" \
-e DEMO_WALLET_SEED="${DEMO_WALLET_SEED:-}" \
-e DEMO_WALLET_HEIGHT="${DEMO_WALLET_HEIGHT:-0}" \
-e HOST_UID="$HOST_UID" \
-e HOST_GID="$HOST_GID" \
"$IMAGE" bash -c '
@@ -214,17 +220,28 @@ step "compile svg assets"
./compile_graphics.sh
step "build apk ($BUILD_MODE / ${TARGET_PLATFORM:-universal})"
EXTRA=""
[[ -n "$TARGET_PLATFORM" ]] && EXTRA="--target-platform=$TARGET_PLATFORM"
# DEMO=1 bakes in DEMO_MODE so the app boots straight to an unlocked demo
# wallet (kDebugMode-gated, impossible in release). Lets capture skip the
# onboarding/PIN flow entirely.
DEMO_DEFINES=""
# Use an ARRAY, not a string: the seed contains spaces (16 words), so a
# word-split string turns "--dart-define=DEMO_WALLET_SEED=word1 word2 ..."
# into separate argv tokens and flutter treats "unlock" as a target file
# ("Target file 'unlock' not found."). Array elements preserve the spaces.
DEMO_DEFINES=()
if [[ "${DEMO:-0}" == "1" ]]; then
DEMO_DEFINES="--dart-define=DEMO_MODE=true --dart-define=DEMO_PIN=${DEMO_PIN:-0801}"
echo "DEMO_MODE baked in"
DEMO_DEFINES+=(--dart-define=DEMO_MODE=true "--dart-define=DEMO_PIN=${DEMO_PIN:-0801}")
if [[ -n "${DEMO_WALLET_SEED:-}" ]]; then
DEMO_DEFINES+=("--dart-define=DEMO_WALLET_SEED=${DEMO_WALLET_SEED}")
DEMO_DEFINES+=("--dart-define=DEMO_WALLET_HEIGHT=${DEMO_WALLET_HEIGHT:-0}")
echo "DEMO_MODE baked in (restore from seed, height ${DEMO_WALLET_HEIGHT:-0})"
else
echo "DEMO_MODE baked in (fresh wallet)"
fi
fi
flutter build apk --dart-define-from-file=env.json --$BUILD_MODE $EXTRA $DEMO_DEFINES
EXTRA_ARGS=()
[[ -n "$TARGET_PLATFORM" ]] && EXTRA_ARGS+=("--target-platform=$TARGET_PLATFORM")
flutter build apk --dart-define-from-file=env.json --$BUILD_MODE \
"${EXTRA_ARGS[@]}" "${DEMO_DEFINES[@]+"${DEMO_DEFINES[@]}"}"
echo
echo "==> artifacts:"