Skip to content

Delegate

Delegate #28

name: Flutter Integration Tests
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
jobs:
# ─────────────────────────────────────────────────────────────────────────
# Full end-to-end: onboarding → on-chain send → policy → Ark board/send/
# receive (with ark-client-sample = "Bob") → policy delete → 30s rollover →
# recovery, on an x86_64 Android emulator against the full ASP stack.
# ─────────────────────────────────────────────────────────────────────────
full:
name: Full integration test (Ark stack)
runs-on: ubuntu-latest
timeout-minutes: 50
steps:
- uses: actions/checkout@v4
with:
submodules: recursive # pulls third_party/rust-sdk (ark-client-sample)
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-wasip1,x86_64-linux-android
- name: Install protoc
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
- name: Install cargo-component
run: cargo install cargo-component
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
ffi/target
cosigner/target
cosigner-runtime/target
e2e/signer-server/target
third_party/rust-sdk/target
key: integration-rust-${{ hashFiles('**/Cargo.lock') }}
restore-keys: integration-rust-
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
# Pin to match the project's Gradle 7.6.3 / AGP setup. Newer Flutter
# ships a Gradle plugin that needs Gradle 8.3+ (filePermissions API).
flutter-version: '3.22.0'
channel: stable
cache: true
- name: Use the runner's JDK for Gradle
# gradle.properties pins org.gradle.java.home to a dev-machine path;
# strip it so Gradle uses JAVA_HOME (set by actions/setup-java above).
run: sed -i '/^org.gradle.java.home=/d' app/android/gradle.properties
- name: Build MPCWallet host binaries
run: |
cargo build --release --manifest-path cosigner-runtime/Cargo.toml
(cd cosigner && cargo component build --release)
cargo build --release --manifest-path e2e/signer-server/Cargo.toml
- name: Build FFI for Android x86_64
run: |
export PATH="$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH"
cargo build --release --manifest-path ffi/Cargo.toml --target x86_64-linux-android
mkdir -p app/android/app/src/main/jniLibs/x86_64
cp ffi/target/x86_64-linux-android/release/libmpcwallet_ffi.so \
app/android/app/src/main/jniLibs/x86_64/
- name: Build ark-client-sample (Bob)
run: cargo build --release --manifest-path third_party/rust-sdk/ark-client-sample/Cargo.toml
- name: Bring up the Ark stack (bitcoind + electrs + nbxplorer + arkd)
run: |
docker compose -f docker-compose.yml -f docker-compose.ark.yml up -d --force-recreate
echo "Waiting for services to stabilize (20s)..."
sleep 20
./scripts/bitcoin.sh init
./scripts/arkd_init.sh --fund
echo "Waiting for NBXplorer to index (10s)..."
sleep 10
- name: Set up Bob (ark-client-sample wallet + HTTP proxy on :7090)
env:
RUST_SDK_DIR: ${{ github.workspace }}/third_party/rust-sdk
BOB_DIR: /tmp/bob_ark
run: |
./scripts/bob_setup.sh
nohup python3 scripts/bob_proxy.py > /tmp/bob_proxy.log 2>&1 &
sleep 2
curl -sS http://127.0.0.1:7090/ark-address || (cat /tmp/bob_proxy.log; exit 1)
- name: Start signer-server
run: |
nohup e2e/signer-server/target/release/signer-server --port 9090 \
> /tmp/signer-server.log 2>&1 &
sleep 1
- name: Start cosigner-runtime (with ASP)
env:
ELECTRUM_URL: 127.0.0.1
ELECTRUM_PORT: '50001'
BITCOIN_RPC_USER: admin1
BITCOIN_RPC_PASSWORD: '123'
ASP_URL: http://127.0.0.1:7070
run: |
nohup cosigner-runtime/target/release/cosigner-runtime \
--wasm cosigner/target/wasm32-wasip1/release/cosigner.wasm \
--port 7074 > /tmp/cosigner-runtime.log 2>&1 &
sleep 3
curl -sS http://127.0.0.1:7074/health || curl -sS http://127.0.0.1:7074/ || true
- name: Flutter pub get
run: cd app && flutter pub get
- name: Enable KVM (emulator acceleration)
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
| sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run integration test on emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 33
arch: x86_64
target: google_apis
profile: pixel_6 # real phone screen; the default skin is a tiny 320x640
script: |
adb reverse tcp:7074 tcp:7074
adb reverse tcp:50001 tcp:50001
adb reverse tcp:18443 tcp:18443
adb reverse tcp:7090 tcp:7090
cd app && flutter test integration_test/app_test.dart --reporter expanded
- name: Dump logs on failure
if: failure()
run: |
echo "=== cosigner-runtime ==="; tail -200 /tmp/cosigner-runtime.log || true
echo "=== signer-server ==="; tail -80 /tmp/signer-server.log || true
echo "=== bob_proxy ==="; cat /tmp/bob_proxy.log || true
echo "=== arkd ==="; docker logs --tail 100 mpc_arkd || true
echo "=== arkd-wallet ==="; docker logs --tail 50 mpc_arkd_wallet || true
echo "=== nbxplorer ==="; docker logs --tail 50 mpc_nbxplorer || true
echo "=== electrs ==="; docker logs --tail 50 mpc_electrs || true
- name: Cleanup
if: always()
run: |
pkill -f cosigner-runtime || true
pkill -f signer-server || true
pkill -f bob_proxy || true
docker compose -f docker-compose.yml -f docker-compose.ark.yml down || true