From 55856e2935a615c8a583312182d93fffc23b04d7 Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Thu, 18 Jun 2026 22:56:28 +0700 Subject: [PATCH] fix: use clipboard mode for Amber login in Capacitor APK Capacitor native apps fail with "malformed nostrsigner request" when using callbackUrl because Amber treats custom URI schemes as invalid. Fix: detect window.Capacitor.isNativePlatform() and use the no-callback clipboard flow (openAmberForLoginNoCallback) instead of the callbackUrl flow. Amber copies the pubkey to clipboard, app reads it on visibilitychange when user returns. Co-authored-by: shakespeare.diy --- src/components/auth/LoginDialog.tsx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/components/auth/LoginDialog.tsx b/src/components/auth/LoginDialog.tsx index 353c599..0c706fa 100644 --- a/src/components/auth/LoginDialog.tsx +++ b/src/components/auth/LoginDialog.tsx @@ -90,18 +90,16 @@ const LoginDialog: React.FC = ({ isOpen, onClose, onLogin, onS setAmberStep('waiting'); setErrors(prev => ({ ...prev, amber: undefined })); - // Detect if running as installed PWA (standalone) — window.matchMedia - // returns true when launched from home screen on Android/iOS + // Detect if running as Capacitor native app or installed PWA (standalone) + const isCapacitor = !!(window as unknown as { Capacitor?: { isNativePlatform?: () => boolean } }).Capacitor?.isNativePlatform?.(); const isPWA = window.matchMedia('(display-mode: standalone)').matches || ('standalone' in window.navigator && (window.navigator as { standalone?: boolean }).standalone === true); - if (isPWA) { - // ── PWA / Capacitor mode ─────────────────────────────────────────────── - // When installed to home screen or running as a Capacitor APK, the app - // is single-tab. Use openAmberForLogin() which handles Capacitor WebViews - // correctly via window.open(_system) instead of window.location.href. - // Amber copies the pubkey to clipboard when there's no callback. - // When the user comes back, visibilitychange fires and we read the clipboard. + if (isCapacitor || isPWA) { + // ── Capacitor APK / PWA mode ─────────────────────────────────────────── + // In Capacitor, callbackUrl flows don't work — Amber treats the custom + // scheme as a malformed request. Use no-callback mode: Amber copies the + // pubkey to clipboard, we read it when the app regains focus. openAmberForLoginNoCallback(); // When user returns to the PWA after approving in Amber, auto-read clipboard