Some checks failed
CI / Typecheck & Lint (pull_request) Failing after 0s
Implements mobile Nostr identity management per issue #29. Android — NIP-55 Amber integration: - Opens com.greenart7c3.nostrsigner via `nostrsigner:` URI scheme to retrieve the user's public key without exposing it to the app. - Listens for the `mobile://nostr-callback` deep link response and stores the resulting npub in Expo SecureStore. - Falls back to Play Store install prompt when Amber is not installed. iOS / manual fallback: - NostrConnectModal accepts an nsec1 paste-in, validates bech32, derives the pubkey via nostr-tools getPublicKey, and stores the key only in Expo SecureStore — never in AsyncStorage, Redux, or logs. Both platforms: - Truncated npub and signer type (Amber / nsec) shown in Settings. - "Disconnect Nostr" wipes all keys from SecureStore and resets state. - Identity persists across restarts via SecureStore. Supporting changes: - NostrContext: new React context for identity lifecycle. - NostrConnectModal: platform-aware bottom-sheet modal for connect flow. - TimmyContext: added apiBaseUrl/setApiBaseUrl/isConnected; URL persisted in AsyncStorage and restored on mount; circular dep broken via refs. - constants/colors: added field, textInverted, destructive, link colours. - constants/storage-keys: added SERVER_URL_KEY. - app.json: added Android intent filter for mobile://nostr-callback. - package.json: added nostr-tools and expo-secure-store dependencies. Fixes #29 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
62 lines
1.3 KiB
JSON
62 lines
1.3 KiB
JSON
{
|
|
"expo": {
|
|
"name": "Timmy Mobile",
|
|
"slug": "mobile",
|
|
"version": "1.0.0",
|
|
"orientation": "portrait",
|
|
"icon": "./assets/images/icon.png",
|
|
"scheme": "mobile",
|
|
"userInterfaceStyle": "dark",
|
|
"newArchEnabled": true,
|
|
"splash": {
|
|
"image": "./assets/images/splash-icon.png",
|
|
"resizeMode": "contain",
|
|
"backgroundColor": "#0A0A12"
|
|
},
|
|
"ios": {
|
|
"supportsTablet": false
|
|
},
|
|
"android": {
|
|
"adaptiveIcon": {
|
|
"foregroundImage": "./assets/images/icon.png",
|
|
"backgroundColor": "#0A0A12"
|
|
},
|
|
"intentFilters": [
|
|
{
|
|
"action": "VIEW",
|
|
"autoVerify": false,
|
|
"data": [
|
|
{
|
|
"scheme": "mobile",
|
|
"host": "nostr-callback"
|
|
}
|
|
],
|
|
"category": ["BROWSABLE", "DEFAULT"]
|
|
}
|
|
]
|
|
},
|
|
"web": {
|
|
"favicon": "./assets/images/icon.png",
|
|
"backgroundColor": "#0A0A12"
|
|
},
|
|
"plugins": [
|
|
[
|
|
"expo-router",
|
|
{
|
|
"origin": "https://replit.com/"
|
|
}
|
|
],
|
|
"expo-font",
|
|
"expo-web-browser"
|
|
],
|
|
"extra": {
|
|
"apiDomain": "${EXPO_PUBLIC_DOMAIN}",
|
|
"gitCommitHash": "${EXPO_PUBLIC_GIT_SHA}"
|
|
},
|
|
"experiments": {
|
|
"typedRoutes": true,
|
|
"reactCompiler": true
|
|
}
|
|
}
|
|
}
|