#!/usr/bin/env node /** * Inject the Amber (NIP-55) block into the Android manifest. * * WHY THIS EXISTS * ─────────────── * On Android 11+ (and GrapheneOS enforces this strictly), an app can only see * or launch another app if it declares a matching entry. Without it, * the nostrsigner intent that opens Amber is SILENTLY blocked by the OS and the * native signer call hangs forever — the classic "Waiting for Amber…" bug. * * Capacitor regenerates android/app/src/main/AndroidManifest.xml on `cap add` * and can touch it on sync, so hand-editing is fragile. This script is * idempotent and runs automatically as part of the android build, guaranteeing * the block is always present in the APK we ship. * * If android/ hasn't been generated yet (fresh checkout), it exits quietly. */ import { readFileSync, writeFileSync, existsSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; const root = join(dirname(fileURLToPath(import.meta.url)), '..'); const manifestPath = join(root, 'android', 'app', 'src', 'main', 'AndroidManifest.xml'); if (!existsSync(manifestPath)) { console.log('[inject-amber-queries] android/ not generated yet — skipping.'); process.exit(0); } let manifest = readFileSync(manifestPath, 'utf8'); if (manifest.includes('android:scheme="nostrsigner"')) { console.log('[inject-amber-queries] already present — nothing to do.'); process.exit(0); } const queriesBlock = ` `; // Insert right before the closing tag. if (!manifest.includes('')) { console.error('[inject-amber-queries] No closing tag found — aborting.'); process.exit(1); } manifest = manifest.replace('', `${queriesBlock}`); writeFileSync(manifestPath, manifest); console.log('[inject-amber-queries] ✓ Injected Amber block into AndroidManifest.xml');