Documentation Index
Fetch the complete documentation index at: https://mintlify.com/sovranBitcoin/sovran/llms.txt
Use this file to discover all available pages before exploring further.
Expo Router Overview
Sovran uses Expo Router for navigation, which provides file-based routing similar to Next.js. Routes are defined by the file structure in theapp/ directory.
Navigation Hierarchy
The app follows a three-level navigation structure:Root Layout
app/_layout.tsx:1-334 Key responsibilities:- Initialize provider hierarchy (see Architecture Overview)
- Configure Stack navigator with modal presentations
- Handle theme changes via React
keyprop - Manage profile switching by remounting inner providers
Drawer Layout
app/(drawer)/_layout.tsx:1-454 The drawer provides the main app navigation with a custom drawer content component. Features:- Profile switcher at the top (switch between multiple wallets)
- User avatar and QR code (tap to view profile)
- Menu items: Feed, Wallet, Payments, Settings
- 82% screen width (max 320px)
- Slide animation with 60% black overlay
Tab Layout
app/(drawer)/(tabs)/_layout.tsx:1-166 The tabs use conditional rendering based on device capabilities:iOS 26+ with Liquid Glass
app/(drawer)/(tabs)/_layout.tsx:38-98 UsesExpo55NativeTabs for native iOS tab bar with blur effects.
Android & iOS (below version 26)
app/(drawer)/(tabs)/_layout.tsx:102-164 Fallback to standardTabs with BlurView background.
Tab structure:
- Feed (
feed/) - Social feed and stories (house icon) - Payments (
payments/) - Contacts and messages (arrow.up.arrow.down icon) - Wallet (
index/) - Balances and transactions (wallet.bifold icon) - Explore (
explore/) - AI chat, maps, pending ecash (paperplane icon)
The wallet tab is at
index/ (not wallet/) for backward compatibility with deep links.Route Groups
Expo Router uses parentheses() for route groups that don’t appear in URLs:
Flow-Based Groups
These groups represent multi-step user flows:| Group | Purpose | Screens |
|---|---|---|
(send-flow) | Send payments | currency → mintSelect → sendToken → meltQuote |
(receive-flow) | Receive payments | receive → currency → mintQuote → receiveToken |
(mint-flow) | Mint management | add → list → info → reviews → rebalancePlan |
(user-flow) | User profiles | profile → share → userMessages → thread |
(map-flow) | BTCMap integration | index (map) → detail (merchant) |
(filter-flow) | Transaction filters | filters |
(transactions-flow) | Transaction details | transactions → swap → sendToken → receiveToken |
Special Layouts
Each route group has a_layout.tsx that configures:
- Presentation style (modal, formSheet, card)
- Header options (title, background, blur)
- Gesture handling
- Animation settings
Navigation Patterns
Type-Safe Navigation
Deep Linking
app.json configures deep link schemes:useDeeplink hook:
Modal Presentations
app/_layout.tsx:216-220 Modal screens are configured inconfig/modalScreens.ts:
Route Parameters
Access route parameters usinguseLocalSearchParams:
Payment Flow Routing
The payment flows use intelligent routing based on available data: hooks/coco/useProcessPaymentString.ts:216-331 Payment request routing logic:| Mints | Amount | Valid | Flow |
|---|---|---|---|
| No | No | Any | currency.tsx (pick mint + amount) → SendTokenScreen |
| No | Yes | 1 | SendTokenScreen directly |
| No | Yes | 2+ | mintSelect.tsx → SendTokenScreen |
| Yes | No | 1 | currency.tsx (amount only) → SendTokenScreen |
| Yes | No | 2+ | currency.tsx (pick from allowed + amount) → SendTokenScreen |
| Yes | Yes | 1 | SendTokenScreen (PR mode) directly |
| Yes | Yes | 2+ | mintSelect.tsx → SendTokenScreen (PR mode) |
Screen Transitions
Sovran uses hero transitions for seamless animations between screens:Best Practices
Keep screens thin
Keep screens thin
Screens in
app/ should be orchestration-only. Move business logic to hooks/, data fetching to stores/, and UI to components/blocks/.Use replace for form flows
Use replace for form flows
When navigating from a form screen to another form screen, use
router.replace() to avoid stack buildup:Validate params early
Validate params early
Route parameters are always strings or undefined. Validate and parse them at the top of the component:
Handle back navigation
Handle back navigation
Related Documentation
State Management
Learn how Zustand stores integrate with navigation
Cashu Integration
See how payment flows interact with Coco manager