#!/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'); let changed = false; // Insert right before the closing tag. if (!manifest.includes('')) { console.error('[inject-amber-queries] No closing tag found — aborting.'); process.exit(1); } // ── 1. Amber block ──────────────────────────────────────────────── if (!manifest.includes('android:scheme="nostrsigner"')) { const queriesBlock = ` `; manifest = manifest.replace('', `${queriesBlock}`); changed = true; console.log('[inject-amber-queries] ✓ Injected Amber block.'); } else { console.log('[inject-amber-queries] already present.'); } // ── 2. Location permissions ─────────────────────────────────────────────────── // The native Geolocation plugin can't prompt for / obtain a fix without these. // Missing permissions is why "Near Me" reports denied even after the user // thinks they granted it. const locationPerms = ` `; if (!manifest.includes('ACCESS_FINE_LOCATION')) { manifest = manifest.replace('', `${locationPerms}`); changed = true; console.log('[inject-amber-queries] ✓ Injected location permissions.'); } else { console.log('[inject-amber-queries] location permissions already present.'); } if (changed) { writeFileSync(manifestPath, manifest); console.log('[inject-amber-queries] AndroidManifest.xml updated.'); } else { console.log('[inject-amber-queries] nothing to do.'); }