Fix real Amber login hang: skip package-name so getPublicKey uses the intent, not the stalling ContentProvider (v1.1.9)

Root cause found in the plugin's native getPublicKey (NostrSignerPlugin.java):
when a packageName is set, it FIRST tries Amber's ContentProvider (background,
no-UI). On GrapheneOS that cross-app ContentResolver query is blocked and never
returns, so it never falls through to startActivityForResult(nostrsigner:) —
the branch that actually opens Amber's approval UI. Result: eternal
"Waiting for Amber".

Fix: getAmberPublicKeyViaPlugin no longer calls setPackageName and no longer
passes packageName; it passes only the get_public_key permission. With no
package name the plugin skips the content-resolver branch and launches the
intent directly, opening Amber's UI. Amber returns both pubkey and its package,
so later signing still works. Paired with the auto-injected <queries> manifest
block so the OS can resolve the intent in the first place.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
shakespeare.diy 2026-08-27 14:29:35 +07:00
parent 07699592da
commit 6fb7314f6c

View file

@ -147,10 +147,24 @@ async function getPlugin(): Promise<NostrSignerNative> {
* handle both hex and real npub just in case.
*/
export async function getAmberPublicKeyViaPlugin(): Promise<string> {
const plugin = await getPlugin();
// Get the raw native bridge directly. CRITICALLY we do NOT call
// setPackageName here and we do NOT pass packageName to getPublicKey.
//
// WHY: the native getPublicKey first tries Amber's ContentProvider (a
// background, no-UI query) whenever a packageName is known. On GrapheneOS that
// cross-app ContentResolver query is blocked/stalls and never returns cleanly,
// so the code never falls through to the intent that actually opens Amber's
// approval screen → eternal "Waiting for Amber". By omitting packageName, the
// plugin skips the content-resolver branch and goes STRAIGHT to
// startActivityForResult(nostrsigner:) which launches Amber's UI. Amber returns
// both the pubkey AND its package, so subsequent signing still works.
const plugin = getNativeSigner();
if (!plugin) {
throw new Error('Amber signing is only available in the SkateSpots Android app.');
}
const result = await withTimeout(
plugin.getPublicKey({ packageName: AMBER_PACKAGE }),
plugin.getPublicKey({ permissions: JSON.stringify([{ type: 'get_public_key' }]) }),
'login',
);