feat: mobile Nostr identity — Amber NIP-55 + nsec fallback (Fixes #29)
- Add NostrIdentityContext with SecureStore-backed nsec storage and pure-JS bech32/secp256k1 for nsec→npub derivation; private key never enters React state or logs - Android: NIP-55 Amber deep-link integration (get_public_key + sign_event) with install-prompt fallback to Play Store when Amber is absent; Android queries manifest entry for com.greenart7c3.nostrsigner - iOS/both: manual nsec entry stored exclusively in expo-secure-store - Settings tab (gear icon) added to both NativeTabLayout and ClassicTabLayout showing: connected npub (truncated), signing method badge, Disconnect button (with confirmation + SecureStore wipe) - Root layout wrapped with NostrIdentityProvider - app.json: add expo-secure-store plugin + Android intentFilters for mobile://amber-callback deep-link return path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import { SafeAreaProvider } from "react-native-safe-area-context";
|
||||
|
||||
import { ErrorBoundary } from "@/components/ErrorBoundary";
|
||||
import { TimmyProvider } from "@/context/TimmyContext";
|
||||
import { NostrIdentityProvider } from "@/context/NostrIdentityContext";
|
||||
import { ONBOARDING_COMPLETED_KEY } from "@/constants/storage-keys";
|
||||
|
||||
SplashScreen.preventAutoHideAsync();
|
||||
@@ -76,9 +77,11 @@ export default function RootLayout() {
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||
<KeyboardProvider>
|
||||
<TimmyProvider>
|
||||
<RootLayoutNav />
|
||||
</TimmyProvider>
|
||||
<NostrIdentityProvider>
|
||||
<TimmyProvider>
|
||||
<RootLayoutNav />
|
||||
</TimmyProvider>
|
||||
</NostrIdentityProvider>
|
||||
</KeyboardProvider>
|
||||
</GestureHandlerRootView>
|
||||
</QueryClientProvider>
|
||||
|
||||
Reference in New Issue
Block a user