Skip to content

Building TWA

Generate your Android APK after initial setup.

Rebuild APK

After initial setup, use the build script for subsequent builds:

bash
cd twa
./scripts/build-twa.sh

This generates:

  • app-release-signed.apk - For direct installation and dApp Store

What the Build Script Does

  1. Validates twa-manifest.json exists
  2. Checks keystore is present
  3. Runs Bubblewrap build
  4. Copies CustomLauncherActivity.java to Android project
  5. Updates package name in activity file
  6. Builds signed APK

Password Handling

Set environment variables to avoid password prompts:

bash
export BUBBLEWRAP_KEYSTORE_PASSWORD="your-password"
export BUBBLEWRAP_KEY_PASSWORD="your-password"
./scripts/build-twa.sh

Or enter passwords when prompted during build.

Testing the APK

Install via ADB

bash
adb install app-release-signed.apk

Install via File Transfer

  1. Connect phone via USB
  2. Enable "File Transfer" mode
  3. Copy app-release-signed.apk to phone
  4. Open file manager and install

Test Checklist

  • [ ] App opens without URL bar (frameless mode)
  • [ ] PWA loads correctly
  • [ ] MWA wallet connection works
  • [ ] Navigation functions properly
  • [ ] Splash screen displays and fades

Version Updates

For app updates, edit twa-manifest.json:

json
{
  "appVersionCode": 2,
  "appVersionName": "1.1.0"
}

Rules:

  • appVersionCode must always increase (1, 2, 3...)
  • appVersionCode cannot be reused
  • Then run ./scripts/build-twa.sh

Build Options

Skip PWA Validation

If your manifest has minor issues:

bash
# The build script uses this by default
bubblewrap build --skipPwaValidation

Clean Build

If you encounter issues:

bash
rm -rf app build .gradle
./scripts/build-twa.sh

CI/CD Build

For automated builds (GitHub Actions):

yaml
name: Build TWA

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Install Bubblewrap
        run: npm install -g @bubblewrap/cli

      - name: Decode Keystore
        run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > twa/android.keystore

      - name: Build TWA
        working-directory: twa
        run: ./scripts/build-twa.sh
        env:
          BUBBLEWRAP_KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
          BUBBLEWRAP_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}

      - name: Upload APK
        uses: actions/upload-artifact@v4
        with:
          name: app-release
          path: twa/app-release-signed.apk

Required Secrets

SecretHow to Generate
KEYSTORE_BASE64base64 -i android.keystore
KEYSTORE_PASSWORDYour keystore password
KEY_PASSWORDYour key alias password

Build Output

Successful build shows:

Building the Android App...
  - Generated Android APK at ./app-release-signed.apk

Next Steps

  1. Verify frameless mode
  2. Publish to dApp Store

Released under the MIT License.