diff --git a/docs/dynamic-app-icons-investigation.md b/docs/dynamic-app-icons-investigation.md
new file mode 100644
index 0000000000..1459ca0ea6
--- /dev/null
+++ b/docs/dynamic-app-icons-investigation.md
@@ -0,0 +1,598 @@
+# Dynamic App Icons Investigation
+
+## Overview
+
+This document investigates how to implement customizable app icons that can be changed from within the app on both iOS and Android platforms. This feature allows users to choose between multiple icon variants without requiring an app update.
+
+## Platform-Specific Implementation
+
+### iOS Implementation
+
+#### Native iOS API
+
+iOS provides native support for alternate app icons through the `UIApplication.setAlternateIconName()` API (available since iOS 10.3).
+
+**Key Requirements:**
+
+- Icons must be included in the app bundle at build time
+- Icons need to be declared in `Info.plist` under `CFBundleAlternateIcons`
+- Each alternate icon requires a complete icon set (all required sizes)
+- User permission is required (iOS shows a confirmation dialog)
+
+**Implementation Steps:**
+
+1. **Prepare Icon Assets:**
+
+ - Create icon sets in Xcode's Asset Catalog (`Assets.xcassets`)
+ - Each alternate icon needs its own App Icon set (e.g., `AppIconRed`, `AppIconBlue`)
+ - Include all required sizes (1024x1024 for modern Xcode, or full set for older versions)
+
+2. **Configure Info.plist:**
+
+ ```xml
+ CFBundleIcons
+
+ CFBundlePrimaryIcon
+
+ CFBundleIconFiles
+
+ AppIcon
+
+
+ CFBundleAlternateIcons
+
+ red
+
+ CFBundleIconFiles
+
+ AppIconRed
+
+ UIPrerenderedIcon
+
+
+ blue
+
+ CFBundleIconFiles
+
+ AppIconBlue
+
+ UIPrerenderedIcon
+
+
+
+
+ ```
+
+3. **Swift/Objective-C Code:**
+
+ ```swift
+ // Check if alternate icons are supported
+ guard UIApplication.shared.supportsAlternateIcons else {
+ return
+ }
+
+ // Set alternate icon
+ UIApplication.shared.setAlternateIconName("red") { error in
+ if let error = error {
+ print("Error: \(error.localizedDescription)")
+ } else {
+ print("Icon changed successfully")
+ }
+ }
+
+ // Reset to default
+ UIApplication.shared.setAlternateIconName(nil) { error in
+ // Handle error
+ }
+ ```
+
+**Limitations:**
+
+- Icons must be bundled with the app (cannot be downloaded dynamically)
+- User sees a confirmation dialog before icon changes
+- Limited number of alternate icons (practical limit ~10-20)
+- Requires app restart on first change (subsequent changes are instant)
+
+### Android Implementation
+
+#### Activity Alias Method
+
+Android uses `activity-alias` entries in `AndroidManifest.xml` to provide multiple launcher icons. Only one alias can be enabled at a time.
+
+**Key Requirements:**
+
+- Each icon variant needs its own `activity-alias` entry
+- Icons must be included in the app bundle at build time
+- Only one alias can be enabled at a time
+- Uses `PackageManager.setComponentEnabledSetting()` to switch
+
+**Implementation Steps:**
+
+1. **Prepare Icon Assets:**
+
+ - Create icon resources in `res/mipmap-*` directories
+ - For adaptive icons, provide foreground and background layers
+ - Include all density variants (mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi)
+
+2. **Configure AndroidManifest.xml:**
+
+ ```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+3. **Kotlin/Java Code:**
+
+ ```kotlin
+ fun setAppIcon(context: Context, aliasName: String) {
+ val packageManager = context.packageManager
+
+ // List of all icon aliases
+ val aliases = listOf(
+ "com.emurgo.yoroi.DefaultIconAlias",
+ "com.emurgo.yoroi.RedIconAlias",
+ "com.emurgo.yoroi.BlueIconAlias"
+ )
+
+ // Disable all aliases first
+ for (alias in aliases) {
+ val componentName = ComponentName(context, alias)
+ val enabled = alias == aliasName
+ packageManager.setComponentEnabledSetting(
+ componentName,
+ if (enabled) {
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ } else {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ },
+ PackageManager.DONT_KILL_APP
+ )
+ }
+ }
+
+ // Usage
+ setAppIcon(context, "com.emurgo.yoroi.RedIconAlias")
+ ```
+
+**Limitations:**
+
+- Icons must be bundled with the app (cannot be downloaded dynamically)
+- First icon change may cause app restart
+- Some launchers cache icons, requiring device/launcher restart
+- Only one alias can be enabled at a time
+- Requires careful management to prevent multiple icons appearing
+
+## React Native/Expo Libraries
+
+### 1. `expo-alternate-app-icons` ⭐ Recommended
+
+- **Platform Support:** iOS and Android
+- **Expo Compatibility:** Full Expo SDK support
+- **Maintenance:** Active
+- **Features:**
+ - Simple API
+ - Supports both platforms
+ - Well-documented
+
+**Installation:**
+
+```bash
+npx expo install expo-alternate-app-icons
+```
+
+**Configuration (app.json):**
+
+```json
+{
+ "expo": {
+ "plugins": [
+ [
+ "expo-alternate-app-icons",
+ {
+ "icons": {
+ "red": {
+ "ios": "./assets/icons/ios-red.png",
+ "android": "./assets/icons/android-red.png"
+ },
+ "blue": {
+ "ios": "./assets/icons/ios-blue.png",
+ "android": "./assets/icons/android-blue.png"
+ }
+ }
+ }
+ ]
+ ]
+ }
+}
+```
+
+**Usage:**
+
+```typescript
+import {
+ getAlternateAppIcon,
+ setAlternateAppIcon,
+} from 'expo-alternate-app-icons'
+
+// Set icon
+await setAlternateAppIcon('red')
+
+// Get current icon
+const currentIcon = await getAlternateAppIcon()
+
+// Reset to default
+await setAlternateAppIcon(null)
+```
+
+### 2. `@howincodes/expo-dynamic-app-icon`
+
+- **Platform Support:** iOS and Android
+- **Expo Compatibility:** Full Expo SDK support
+- **Features:**
+ - Supports round icons
+ - Dynamic icon variants for iOS (light/dark/tinted)
+ - More configuration options
+
+**Installation:**
+
+```bash
+npx expo install @howincodes/expo-dynamic-app-icon
+```
+
+**Configuration:**
+
+```json
+{
+ "expo": {
+ "plugins": [
+ [
+ "@howincodes/expo-dynamic-app-icon",
+ {
+ "red": {
+ "ios": "./assets/icons/ios-red.png",
+ "android": "./assets/icons/android-red.png"
+ },
+ "blue": {
+ "ios": "./assets/icons/ios-blue.png",
+ "android": "./assets/icons/android-blue.png"
+ }
+ }
+ ]
+ ]
+ }
+}
+```
+
+**Usage:**
+
+```typescript
+import ExpoDynamicAppIcon from '@howincodes/expo-dynamic-app-icon'
+
+await ExpoDynamicAppIcon.setAppIcon('red')
+await ExpoDynamicAppIcon.resetAppIcon()
+```
+
+### 3. `@variant-systems/expo-dynamic-app-icon`
+
+- **Platform Support:** iOS, Android, Web (no-op)
+- **Expo Compatibility:** Expo SDK 52+
+- **Features:**
+ - Modern implementation
+ - Web support (no-op)
+
+**Installation:**
+
+```bash
+npx expo install @variant-systems/expo-dynamic-app-icon
+```
+
+### 4. `react-native-dynamic-app-icon` (iOS Only)
+
+- **Platform Support:** iOS only
+- **Expo Compatibility:** Requires custom native code
+- **Note:** Not recommended for Expo projects
+
+## Implementation Considerations
+
+### Icon Asset Requirements
+
+**iOS:**
+
+- Single 1024x1024 PNG (Xcode 13+)
+- Or full icon set: 20pt@2x, 20pt@3x, 29pt@2x, 29pt@3x, 40pt@2x, 40pt@3x, 60pt@2x, 60pt@3x, 1024x1024
+- No transparency
+- Square format
+
+**Android:**
+
+- Adaptive icon: foreground (108x108dp) + background (108x108dp)
+- Or legacy icon: mdpi (48x48), hdpi (72x72), xhdpi (96x96), xxhdpi (144x144), xxxhdpi (192x192)
+- Round icon variants for round launchers
+
+### User Experience Considerations
+
+1. **First Change Behavior:**
+
+ - iOS: Shows confirmation dialog, may restart app
+ - Android: May restart app on first change
+
+2. **Subsequent Changes:**
+
+ - iOS: Instant, no restart needed
+ - Android: Usually instant, but launcher caching may delay
+
+3. **Icon Persistence:**
+
+ - Both platforms persist icon choice across app restarts
+ - Need to store preference in app state (AsyncStorage/MMKV)
+
+4. **Error Handling:**
+ - Handle cases where icon change fails
+ - Provide fallback to default icon
+ - Show user feedback during icon change
+
+### Storage Strategy
+
+Store the selected icon preference:
+
+```typescript
+import * as SecureStore from 'expo-secure-store'
+
+const ICON_PREFERENCE_KEY = 'app_icon_preference'
+
+// Save preference
+await SecureStore.setItemAsync(ICON_PREFERENCE_KEY, 'red')
+
+// Load preference on app start
+const savedIcon = await SecureStore.getItemAsync(ICON_PREFERENCE_KEY)
+if (savedIcon) {
+ await setAlternateAppIcon(savedIcon)
+}
+```
+
+## Recommended Implementation Plan
+
+### Phase 1: Setup
+
+1. Choose library: `expo-alternate-app-icons` (simplest, well-maintained)
+2. Design/create icon variants (3-5 options initially)
+3. Prepare icon assets for both platforms
+
+### Phase 2: Configuration
+
+1. Install library: `npx expo install expo-alternate-app-icons`
+2. Add plugin configuration to `app.json`/`app.config.js`
+3. Add icon assets to `assets/icons/` directory
+4. Run `npx expo prebuild` to generate native code
+
+### Phase 3: Implementation
+
+1. Create icon selection UI component
+2. Implement icon change logic with error handling
+3. Add preference persistence (SecureStore)
+4. Restore icon preference on app launch
+
+### Phase 4: Testing
+
+1. Test on iOS devices (simulator + physical device)
+2. Test on Android devices (multiple launchers)
+3. Test icon persistence across app restarts
+4. Test error scenarios
+
+## Example Implementation
+
+```typescript
+// src/services/appIconService.ts
+import {
+ getAlternateAppIcon,
+ setAlternateAppIcon,
+} from 'expo-alternate-app-icons'
+import * as SecureStore from 'expo-secure-store'
+
+const ICON_PREFERENCE_KEY = 'app_icon_preference'
+
+export const AVAILABLE_ICONS = [
+ {id: null, name: 'Default', icon: require('../../assets/icons/default.png')},
+ {id: 'red', name: 'Red', icon: require('../../assets/icons/red.png')},
+ {id: 'blue', name: 'Blue', icon: require('../../assets/icons/blue.png')},
+ {id: 'green', name: 'Green', icon: require('../../assets/icons/green.png')},
+] as const
+
+export type AppIconId = (typeof AVAILABLE_ICONS)[number]['id']
+
+export async function changeAppIcon(iconId: AppIconId): Promise {
+ try {
+ await setAlternateAppIcon(iconId)
+ await SecureStore.setItemAsync(ICON_PREFERENCE_KEY, iconId || '')
+ } catch (error) {
+ console.error('Failed to change app icon:', error)
+ throw error
+ }
+}
+
+export async function getCurrentAppIcon(): Promise {
+ try {
+ const currentIcon = await getAlternateAppIcon()
+ return currentIcon as AppIconId
+ } catch (error) {
+ console.error('Failed to get current app icon:', error)
+ return null
+ }
+}
+
+export async function restoreAppIconPreference(): Promise {
+ try {
+ const savedIcon = await SecureStore.getItemAsync(ICON_PREFERENCE_KEY)
+ if (savedIcon) {
+ await setAlternateAppIcon(savedIcon as AppIconId)
+ }
+ } catch (error) {
+ console.error('Failed to restore app icon preference:', error)
+ }
+}
+```
+
+```typescript
+// src/features/Settings/ui/components/AppIconSelector.tsx
+import React, { useState, useEffect } from 'react';
+import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
+import { changeAppIcon, getCurrentAppIcon, AVAILABLE_ICONS, AppIconId } from '@/services/appIconService';
+
+export const AppIconSelector: React.FC = () => {
+ const [currentIcon, setCurrentIcon] = useState(null);
+ const [isChanging, setIsChanging] = useState(false);
+
+ useEffect(() => {
+ loadCurrentIcon();
+ }, []);
+
+ const loadCurrentIcon = async () => {
+ const icon = await getCurrentAppIcon();
+ setCurrentIcon(icon);
+ };
+
+ const handleIconChange = async (iconId: AppIconId) => {
+ if (iconId === currentIcon || isChanging) return;
+
+ setIsChanging(true);
+ try {
+ await changeAppIcon(iconId);
+ setCurrentIcon(iconId);
+ } catch (error) {
+ console.error('Failed to change icon:', error);
+ // Show error toast
+ } finally {
+ setIsChanging(false);
+ }
+ };
+
+ return (
+
+ Choose App Icon
+
+ {AVAILABLE_ICONS.map((icon) => (
+ handleIconChange(icon.id)}
+ disabled={isChanging}
+ >
+
+ {/* Render icon preview */}
+
+ {icon.name}
+
+ ))}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ padding: 16,
+ },
+ title: {
+ fontSize: 18,
+ fontWeight: 'bold',
+ marginBottom: 16,
+ },
+ iconGrid: {
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ gap: 16,
+ },
+ iconOption: {
+ alignItems: 'center',
+ padding: 12,
+ borderRadius: 8,
+ borderWidth: 2,
+ borderColor: 'transparent',
+ },
+ iconOptionSelected: {
+ borderColor: '#007AFF',
+ },
+ iconOptionDisabled: {
+ opacity: 0.5,
+ },
+ iconPreview: {
+ width: 64,
+ height: 64,
+ borderRadius: 12,
+ marginBottom: 8,
+ },
+ iconName: {
+ fontSize: 14,
+ },
+});
+```
+
+## Resources
+
+- [expo-alternate-app-icons GitHub](https://github.com/pchalupa/expo-alternate-app-icons)
+- [iOS Alternate App Icons Documentation](https://developer.apple.com/documentation/uikit/uiapplication/2806818-setalternateiconname)
+- [Android Activity Alias Documentation](https://developer.android.com/guide/topics/manifest/activity-alias-element)
+- [Expo Config Plugins](https://docs.expo.dev/config-plugins/introduction/)
+
+## Conclusion
+
+Dynamic app icons are feasible on both iOS and Android, but require:
+
+- Icons to be bundled at build time
+- Native configuration in both platforms
+- Careful UX consideration for first-time changes
+- Preference persistence for user choice
+
+The recommended approach is to use `expo-alternate-app-icons` for a clean, cross-platform solution that integrates well with the Expo workflow.
diff --git a/docs/extension-greenfield-migration-plan.md b/docs/extension-greenfield-migration-plan.md
new file mode 100644
index 0000000000..68d8b77048
--- /dev/null
+++ b/docs/extension-greenfield-migration-plan.md
@@ -0,0 +1,662 @@
+# Extension Greenfield Migration Plan
+
+## Executive Summary
+
+This document outlines a comprehensive plan to create a new browser extension project within the Yoroi monorepo, extracting shared non-UI code from the mobile app into reusable packages. The new extension will be built from the ground up using modern technologies (Vite, TypeScript, React Query 5) and will incrementally port features from the legacy `yoroi-frontend` repository.
+
+## Current State
+
+### Mobile App (`mobile/`)
+- **Status**: Modern, well-architected, TypeScript-first
+- **Patterns**: Superior architecture with clear separation of concerns
+- **Features**: More complete feature set, recently refactored
+- **Structure**:
+ - `src/features/WalletManager/` - Core wallet management logic
+ - `src/wallets/cardano/` - Cardano wallet implementation
+ - `src/kernel/` - Core infrastructure (storage, logger, etc.)
+ - `packages/` - Shared packages already extracted
+
+### Legacy Extension (`yoroi-frontend`)
+- **Status**: Separate repository, older patterns
+- **Issues**:
+ - Limited code sharing with mobile
+ - Different dependencies and React APIs
+ - Platform-specific UI and storage implementations
+ - Slower development due to duplication
+
+### Monorepo Structure
+```
+yoroi/
+├── mobile/ # React Native mobile app
+├── extension/ # NEW: Browser extension (to be created)
+└── packages/ # Shared packages
+ ├── types/ # Already exists
+ ├── common/ # Already exists (in mobile/packages/common)
+ ├── wallet-manager/ # To be extracted
+ ├── cardano-wallet/ # To be extracted
+ └── providers/ # To be extracted
+```
+
+## Goals
+
+1. **Create new extension project** in monorepo using modern tooling
+2. **Extract shared non-UI code** from mobile into reusable packages
+3. **Build extension incrementally** by porting features from legacy repo
+4. **Maximize code reuse** between mobile and extension
+5. **Adopt TypeScript fully** across all packages
+6. **Use latest React Query** (v5) for data fetching
+7. **Leverage existing packages** (@yoroi/types, @yoroi/common, etc.)
+
+## Phase 1: Monorepo Setup and Package Extraction
+
+### 1.1 Root Monorepo Configuration
+
+**Tasks:**
+- [ ] Create root `package.json` with workspaces configuration
+- [ ] Set up `tsconfig.base.json` with shared TypeScript config
+- [ ] Configure path aliases for `@yoroi/*` packages
+- [ ] Set up build tooling (Turbo or similar) for parallel builds
+
+**Files to Create:**
+```
+yoroi/
+├── package.json # Root workspace config
+├── tsconfig.base.json # Base TypeScript config
+└── turbo.json # Optional: Turbo build config
+```
+
+**Key Configuration:**
+```json
+{
+ "name": "yoroi-monorepo",
+ "private": true,
+ "workspaces": [
+ "mobile",
+ "extension",
+ "packages/*"
+ ],
+ "scripts": {
+ "install:all": "npm install",
+ "build:all": "turbo run build",
+ "lint:all": "turbo run lint"
+ }
+}
+```
+
+### 1.2 Platform-Specific Storage Adapters
+
+**Challenge**: Mobile uses AsyncStorage/MMKV, extension needs Chrome Storage API
+
+**Solution**: Create platform-agnostic storage interface with adapters
+
+**Tasks:**
+- [ ] Extract `App.Storage` interface from `@yoroi/types`
+- [ ] Create `mountChromeStorage` adapter in `@yoroi/common`
+- [ ] Create `BrowserKeychain` adapter (using localStorage or Chrome Storage)
+- [ ] Ensure adapters match existing `App.Storage` interface
+
+**Files to Create/Modify:**
+```
+mobile/packages/common/storage/adapters/
+├── chrome-storage.ts # NEW: Chrome Storage adapter
+└── browser-keychain.ts # NEW: Browser keychain adapter
+```
+
+**Implementation Notes:**
+- `mountChromeStorage` should implement the same interface as `mountAsyncStorage`
+- Use `chrome.storage.local` API for persistence
+- Browser keychain can use `chrome.storage.local` with encryption or localStorage as fallback
+- Export from `@yoroi/common` for use in extension
+
+### 1.3 Extract Wallet Manager Package
+
+**Source**: `mobile/src/features/WalletManager/`
+
+**Target**: `packages/wallet-manager/`
+
+**Tasks:**
+- [ ] Copy wallet-manager core files to `packages/wallet-manager/src/`
+- [ ] Create `package.json` with dependencies
+- [ ] Create `tsconfig.json` extending base config
+- [ ] Replace mobile-specific imports with `@yoroi/*` packages
+- [ ] Extract `KeychainManager` interface for dependency injection
+- [ ] Extract `Logger` interface for dependency injection
+- [ ] Extract `EncryptedStorageFactory` interface
+- [ ] Update `WalletManagerOptions` to accept injected dependencies
+
+**Key Files to Extract:**
+```
+packages/wallet-manager/src/
+├── wallet-manager.ts # Core makeWalletManager function
+├── state/
+│ └── wallet-manager-state.ts
+├── sync/
+│ ├── sync-manager.ts
+│ ├── sync-strategies.ts
+│ └── sync-state.ts
+├── creation/
+│ └── wallet-creation.ts
+├── lifecycle/
+│ └── wallet-lifecycle.ts
+├── network-manager/
+│ └── get-wallet-factory.ts
+└── common/
+ ├── types.ts
+ ├── constants.ts
+ ├── keychain-manager.ts # NEW: Interface
+ ├── logger.ts # NEW: Interface
+ ├── encrypted-storage.ts # NEW: Interface
+ └── validators/
+```
+
+**Dependency Injection Pattern:**
+```typescript
+export type WalletManagerOptions = {
+ keychainManager?: KeychainManager
+ networkManagers: Record
+ rootStorage: App.Storage
+ logger?: Logger
+ encryptedStorageFactory?: EncryptedStorageFactory
+ cardanoWalletFactory?: (params: {
+ network: Chain.SupportedNetworks
+ implementation: Wallet.Implementation
+ }) => WalletFactory
+ // ... other dependencies
+}
+```
+
+**Import Replacements:**
+- `~/kernel/storage/Keychain` → `KeychainManager` interface (injected)
+- `~/kernel/logger/logger` → `Logger` interface (injected)
+- `~/kernel/storage/EncryptedStorage` → `EncryptedStorageFactory` (injected)
+- `~/wallets/cardano/*` → `@yoroi/cardano-wallet` (to be extracted)
+- `~/kernel/storage/storages` → `App.Storage` from options
+- `@yoroi/types` → Keep as is
+- `@yoroi/common` → Keep as is
+
+### 1.4 Extract Cardano Wallet Package
+
+**Source**: `mobile/src/wallets/cardano/`
+
+**Target**: `packages/cardano-wallet/`
+
+**Tasks:**
+- [ ] Copy cardano wallet files to `packages/cardano-wallet/src/`
+- [ ] Create `package.json` with dependencies
+- [ ] Create `tsconfig.json` extending base config
+- [ ] Extract `YoroiWallet` type and `CardanoTypes`
+- [ ] Extract `makeCardanoWallet` factory function
+- [ ] Extract key manager, account manager, API modules
+- [ ] Replace mobile-specific imports
+
+**Key Files to Extract:**
+```
+packages/cardano-wallet/src/
+├── cardano-wallet.ts # makeCardanoWallet factory
+├── types.ts # YoroiWallet, WalletEvent, etc.
+├── key-manager/
+│ └── key-manager.ts
+├── account-manager/
+│ ├── derive-address-from-xpub.ts
+│ └── account-manager.ts
+├── api/
+│ └── ... # API-related modules
+└── utils/
+ └── ... # Utility functions
+```
+
+**Dependencies:**
+- `@yoroi/types` - For Chain, Wallet, Network types
+- `@yoroi/common` - For storage, logger interfaces
+- `@yoroi/blockchains` - For cardanoConfig
+- `@emurgo/cip4-js` - For wallet checksum
+- `@emurgo/cross-csl-core` - For Cardano serialization
+
+### 1.5 Extract Providers Package
+
+**Source**: `mobile/src/features/WalletManager/context/`
+
+**Target**: `packages/providers/`
+
+**Tasks:**
+- [ ] Copy `WalletManagerProvider.tsx` to `packages/providers/src/`
+- [ ] Copy `wallet-manager-state.ts` (React state management)
+- [ ] Update imports to use `@yoroi/wallet-manager`
+- [ ] Create `package.json` with React as peer dependency
+- [ ] Export provider and hooks
+
+**Files:**
+```
+packages/providers/src/
+├── WalletManagerProvider.tsx
+├── wallet-manager-state.ts
+└── index.ts
+```
+
+**Exports:**
+```typescript
+export { WalletManagerProvider } from './WalletManagerProvider'
+export { useWalletManager } from './WalletManagerProvider'
+export type { WalletManagerState } from './wallet-manager-state'
+```
+
+## Phase 2: Extension Project Setup
+
+### 2.1 Initialize Extension Project
+
+**Tasks:**
+- [ ] Create `extension/` directory structure
+- [ ] Initialize with Vite and React
+- [ ] Configure TypeScript
+- [ ] Set up Chrome extension manifest
+- [ ] Configure build for extension (popup, background, content scripts)
+
+**Project Structure:**
+```
+extension/
+├── package.json
+├── tsconfig.json
+├── vite.config.ts
+├── src/
+│ ├── manifest.json
+│ ├── popup/
+│ │ ├── index.html
+│ │ └── index.tsx
+│ ├── background/
+│ │ └── index.ts
+│ ├── content/
+│ │ └── index.ts
+│ ├── kernel/
+│ │ ├── query-client.ts
+│ │ ├── storage/
+│ │ │ └── storages.ts
+│ │ ├── wallet-manager.ts
+│ │ └── platform/
+│ │ └── index.ts
+│ ├── navigation/
+│ │ ├── routes.tsx
+│ │ └── AppNavigator.tsx
+│ └── App.tsx
+└── .gitignore
+```
+
+### 2.2 Extension Configuration Files
+
+**package.json:**
+```json
+{
+ "name": "@yoroi/extension",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite build --watch",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@tanstack/react-query": "^5.0.0",
+ "@yoroi/types": "workspace:*",
+ "@yoroi/common": "workspace:*",
+ "@yoroi/wallet-manager": "workspace:*",
+ "@yoroi/cardano-wallet": "workspace:*",
+ "@yoroi/providers": "workspace:*",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.20.0",
+ "rxjs": "^7.8.1"
+ },
+ "devDependencies": {
+ "@types/chrome": "^0.0.251",
+ "@types/react": "^18.2.0",
+ "@types/react-dom": "^18.2.0",
+ "@vitejs/plugin-react": "^4.2.0",
+ "typescript": "^5.3.0",
+ "vite": "^5.0.0",
+ "vite-plugin-web-extension": "^4.0.0"
+ }
+}
+```
+
+**vite.config.ts:**
+```typescript
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import { webExtension } from 'vite-plugin-web-extension'
+import path from 'path'
+
+export default defineConfig({
+ plugins: [
+ react(),
+ webExtension({
+ manifest: './src/manifest.json',
+ }),
+ ],
+ resolve: {
+ alias: {
+ '@yoroi/types': path.resolve(__dirname, '../packages/types/src'),
+ '@yoroi/common': path.resolve(__dirname, '../packages/common/src'),
+ '@yoroi/wallet-manager': path.resolve(__dirname, '../packages/wallet-manager/src'),
+ '@yoroi/cardano-wallet': path.resolve(__dirname, '../packages/cardano-wallet/src'),
+ '@yoroi/providers': path.resolve(__dirname, '../packages/providers/src'),
+ },
+ },
+})
+```
+
+**manifest.json:**
+```json
+{
+ "manifest_version": 3,
+ "name": "Yoroi Wallet",
+ "version": "0.1.0",
+ "description": "Cardano wallet extension",
+ "permissions": [
+ "storage",
+ "alarms"
+ ],
+ "action": {
+ "default_popup": "popup/index.html"
+ },
+ "background": {
+ "service_worker": "background/index.js"
+ },
+ "content_scripts": [
+ {
+ "matches": [""],
+ "js": ["content/index.js"]
+ }
+ ]
+}
+```
+
+### 2.3 Extension Infrastructure Setup
+
+**Tasks:**
+- [ ] Set up React Query 5 with Chrome Storage persistence
+- [ ] Create storage instances using Chrome Storage adapter
+- [ ] Initialize wallet manager with browser-specific dependencies
+- [ ] Set up React Router for navigation
+- [ ] Create platform abstraction layer
+
+**kernel/query-client.ts:**
+```typescript
+import { QueryClient } from '@tanstack/react-query'
+import { persistQueryClient } from '@tanstack/react-query-persist-client'
+import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'
+
+export const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ staleTime: 1000 * 60 * 5, // 5 minutes
+ gcTime: 1000 * 60 * 30, // 30 minutes
+ },
+ },
+})
+
+// Persist to Chrome Storage
+const persister = createSyncStoragePersister({
+ storage: {
+ getItem: (key) => chrome.storage.local.get(key).then(r => r[key] ?? null),
+ setItem: (key, value) => chrome.storage.local.set({ [key]: value }),
+ removeItem: (key) => chrome.storage.local.remove(key),
+ },
+})
+
+persistQueryClient({
+ queryClient,
+ persister,
+})
+```
+
+**kernel/storage/storages.ts:**
+```typescript
+import { mountChromeStorage } from '@yoroi/common'
+import { BrowserKeychain } from '@yoroi/common'
+
+export const rootStorage = mountChromeStorage({ path: '' })
+export const keychainManager = BrowserKeychain
+```
+
+**kernel/wallet-manager.ts:**
+```typescript
+import { makeWalletManager } from '@yoroi/wallet-manager'
+import { makeCardanoWallet } from '@yoroi/cardano-wallet'
+import { networkManagers } from '@yoroi/blockchains'
+import { rootStorage, keychainManager } from './storage/storages'
+import { logger } from './logger' // Browser-specific logger
+import { makeWalletEncryptedStorage } from './storage/encrypted-storage'
+
+export const walletManager = makeWalletManager({
+ networkManagers,
+ rootStorage,
+ keychainManager,
+ logger,
+ encryptedStorageFactory: makeWalletEncryptedStorage,
+ cardanoWalletFactory: ({ network, implementation }) => {
+ return makeCardanoWallet(
+ networkManagers[network],
+ implementation
+ )
+ },
+})
+```
+
+### 2.4 Extension App Structure
+
+**App.tsx:**
+```typescript
+import { QueryClientProvider } from '@tanstack/react-query'
+import { WalletManagerProvider } from '@yoroi/providers'
+import { queryClient } from './kernel/query-client'
+import { walletManager } from './kernel/wallet-manager'
+import { AppNavigator } from './navigation/AppNavigator'
+
+export function App() {
+ return (
+
+
+
+
+
+ )
+}
+```
+
+## Phase 3: Feature Migration Strategy
+
+### 3.1 Migration Order
+
+**Priority 1: Core Infrastructure**
+1. Authentication flow
+2. Wallet creation/import
+3. Wallet selection/switching
+4. Basic balance display
+
+**Priority 2: Core Wallet Features**
+5. Send transaction
+6. Receive addresses
+7. Transaction history
+8. Staking (delegation)
+
+**Priority 3: Advanced Features**
+9. DApp connector (CIP-30)
+10. Swap functionality
+11. Governance voting
+12. Hardware wallet support
+
+### 3.2 Migration Process for Each Feature
+
+**Step 1: Analyze Legacy Implementation**
+- [ ] Review feature in `yoroi-frontend`
+- [ ] Identify dependencies and data flow
+- [ ] Map to mobile app equivalent (if exists)
+- [ ] Document differences and platform-specific code
+
+**Step 2: Port UI Components**
+- [ ] Create new React components in `extension/src/features/[feature]/`
+- [ ] Use modern React patterns (hooks, functional components)
+- [ ] Adapt UI for browser extension constraints (popup size, etc.)
+- [ ] Use shared theme/styling from `@yoroi/theme` if applicable
+
+**Step 3: Integrate Shared Logic**
+- [ ] Use `@yoroi/wallet-manager` for wallet operations
+- [ ] Use `@yoroi/cardano-wallet` for Cardano-specific logic
+- [ ] Use React Query 5 for data fetching
+- [ ] Use shared types from `@yoroi/types`
+
+**Step 4: Test and Refine**
+- [ ] Test feature in extension context
+- [ ] Verify data persistence with Chrome Storage
+- [ ] Test cross-tab synchronization
+- [ ] Performance optimization
+
+### 3.3 Example: Authentication Feature Migration
+
+**Legacy Location**: `yoroi-frontend/src/features/auth/`
+
+**New Location**: `extension/src/features/auth/`
+
+**Components to Create:**
+```
+extension/src/features/auth/
+├── components/
+│ ├── LoginScreen.tsx
+│ ├── PinInput.tsx
+│ └── BiometricPrompt.tsx
+├── hooks/
+│ └── useAuth.ts
+└── utils/
+ └── auth-helpers.ts
+```
+
+**Integration Points:**
+- Use `walletManager` from `@yoroi/providers` to access wallets
+- Use `keychainManager` for secure key storage
+- Use React Query for auth state management
+- Persist auth state in Chrome Storage
+
+## Phase 4: Challenges and Solutions
+
+### Challenge 1: Storage API Differences
+
+**Problem**: Mobile uses AsyncStorage/MMKV, extension needs Chrome Storage
+
+**Solution**:
+- Created `mountChromeStorage` adapter implementing `App.Storage` interface
+- Both platforms use same interface, different implementations
+- Storage paths and structure remain consistent
+
+### Challenge 2: Keychain/Biometric Auth
+
+**Problem**: Mobile has native biometric auth, browser doesn't
+
+**Solution**:
+- Create `BrowserKeychain` adapter using Chrome Storage with encryption
+- For sensitive operations, prompt for password instead of biometric
+- Can use WebAuthn API for future biometric support
+
+### Challenge 3: Background Processing
+
+**Problem**: Mobile can run background tasks, extension has service worker limitations
+
+**Solution**:
+- Use Chrome Alarms API for periodic tasks (sync, etc.)
+- Use service worker for background processing
+- Leverage React Query's background refetch capabilities
+
+### Challenge 4: Navigation Differences
+
+**Problem**: Mobile uses React Navigation, extension needs different navigation
+
+**Solution**:
+- Use React Router for extension navigation
+- Create popup-specific navigation patterns
+- Handle deep linking differently (Chrome extension URLs)
+
+### Challenge 5: State Synchronization Across Tabs
+
+**Problem**: Extension can have multiple tabs/windows open
+
+**Solution**:
+- Use Chrome Storage events for cross-tab communication
+- Use React Query's persistence and synchronization
+- Implement custom event system for wallet state updates
+
+### Challenge 6: Dependencies and Build Size
+
+**Problem**: Extension has stricter size constraints than mobile
+
+**Solution**:
+- Use Vite for optimal bundling and tree-shaking
+- Lazy load features where possible
+- Split code for popup, background, and content scripts
+- Monitor bundle size and optimize dependencies
+
+## Phase 5: Testing Strategy
+
+### 5.1 Unit Tests
+- [ ] Test extracted packages independently
+- [ ] Mock platform-specific adapters
+- [ ] Test wallet manager logic
+- [ ] Test cardano wallet operations
+
+### 5.2 Integration Tests
+- [ ] Test extension with real Chrome Storage
+- [ ] Test wallet creation and loading
+- [ ] Test transaction building and signing
+- [ ] Test cross-tab synchronization
+
+### 5.3 E2E Tests
+- [ ] Use Playwright or similar for extension testing
+- [ ] Test complete user flows
+- [ ] Test with real Cardano testnet
+- [ ] Test error scenarios and edge cases
+
+## Phase 6: Documentation
+
+### 6.1 Package Documentation
+- [ ] Document `@yoroi/wallet-manager` API
+- [ ] Document `@yoroi/cardano-wallet` API
+- [ ] Document `@yoroi/providers` usage
+- [ ] Create migration guides for each package
+
+### 6.2 Extension Documentation
+- [ ] Document extension architecture
+- [ ] Document feature migration process
+- [ ] Create developer setup guide
+- [ ] Document build and deployment process
+
+## Success Criteria
+
+1. ✅ New extension project created and building successfully
+2. ✅ Wallet manager package extracted and working in both mobile and extension
+3. ✅ Cardano wallet package extracted and shared
+4. ✅ First feature (authentication) migrated and working
+5. ✅ Extension can create and load wallets
+6. ✅ Extension can display balances and transaction history
+7. ✅ Extension can send transactions
+8. ✅ All shared packages have TypeScript types
+9. ✅ Tests passing for extracted packages
+10. ✅ Documentation complete
+
+## Timeline Estimate
+
+- **Phase 1**: 2-3 weeks (Package extraction)
+- **Phase 2**: 1 week (Extension setup)
+- **Phase 3**: 8-12 weeks (Feature migration, incremental)
+- **Phase 4**: Ongoing (Address challenges as they arise)
+- **Phase 5**: Ongoing (Testing throughout)
+- **Phase 6**: Ongoing (Documentation throughout)
+
+**Total**: ~3-4 months for core functionality, ongoing for full feature parity
+
+## Notes
+
+- This is a greenfield approach to avoid conflicts from refactoring legacy extension in place
+- Features will be migrated incrementally, allowing for testing and refinement
+- Mobile app remains the source of truth for patterns and best practices
+- Extension will eventually replace legacy `yoroi-frontend` repository
+- All packages should be platform-agnostic where possible
+- Use dependency injection for platform-specific code
+
diff --git a/docs/multi-chain-integration-plan.md b/docs/multi-chain-integration-plan.md
new file mode 100644
index 0000000000..a526513660
--- /dev/null
+++ b/docs/multi-chain-integration-plan.md
@@ -0,0 +1,1203 @@
+# Multi-Chain Integration Plan for Yoroi
+
+## Executive Summary
+
+This plan outlines the integration of Bitcoin and Midnight blockchains into Yoroi wallet. The current architecture is Cardano-centric and requires significant refactoring to support multiple blockchains. The plan covers blockchain abstraction, API layer updates, transaction handling, wallet management, UI changes, hardware wallet support, deep links, dApp connectors, notifications, and all supporting infrastructure.
+
+**Key Principles**:
+- Maintain backward compatibility with existing Cardano wallets
+- Single mnemonic supports all blockchains (different key derivation)
+- Gradual rollout with feature flags
+- Blockchain-agnostic architecture where possible
+
+## Key Reuse Strategy
+
+**Same Mnemonic, Different Keys**: All three blockchains can use the same BIP39 mnemonic seed, but derive different keys due to:
+- **Cardano**: Uses Ed25519 curve with coin type 1815 (CIP-1852: `m/1852'/1815'/0'`)
+- **Bitcoin**: Uses secp256k1 curve with coin type 0 (`m/84'/0'/0'/0/X` for SegWit)
+- **Midnight**: Uses secp256k1 curve (same as Bitcoin) but different coin type and role structure (`m/${PURPOSE}'/${COIN_TYPE}'/${account}'/${role}/${index}`)
+
+**Implications**:
+- ✅ Single mnemonic can generate wallets for all three blockchains
+- ✅ Bitcoin and Midnight share the same cryptographic curve (secp256k1) but use different derivation paths
+- ❌ Cardano uses a different curve (Ed25519), so keys cannot be directly shared
+- ✅ Wallet can derive keys for each blockchain independently from the same seed
+- ✅ Multi-chain wallet architecture: one mnemonic → multiple blockchain accounts
+
+**Architecture**:
+```
+Single Mnemonic (BIP39)
+├── Cardano Account (Ed25519, m/1852'/1815'/0')
+│ ├── Payment Key
+│ └── Staking Key
+├── Bitcoin Account (secp256k1, m/84'/0'/0'/0/X)
+│ └── SegWit Address
+└── Midnight Account (secp256k1, custom path)
+ └── ZSwap Address
+```
+
+**Implementation Notes**:
+- Wallet storage schema must track which blockchains are enabled per wallet
+- Key derivation happens on-demand per blockchain
+- Address generation is blockchain-specific
+- Existing Cardano-only wallets can add Bitcoin/Midnight later via migration
+
+## Hardware Wallet Support
+
+**Current State**: Yoroi supports Ledger Nano S/X for Cardano using `@cardano-foundation/ledgerjs-hw-app-cardano` (version 7.1.4). Uses `@ledgerhq/react-native-hid` and `@ledgerhq/react-native-hw-transport-ble` for transport.
+
+**Multi-Chain Hardware Wallet Strategy**:
+- **Same Device, Different Apps**: Ledger/Trezor devices can have multiple apps installed
+ - Cardano app for Cardano transactions (existing)
+ - Bitcoin app for Bitcoin transactions (to be added)
+ - (Future: Midnight app if available)
+- **Key Derivation**: Hardware wallets use BIP32/BIP44, same mnemonic → same root seed
+- **App Switching**: Users must open correct app on device (Cardano ↔ Bitcoin)
+- **Transport Layer**: Same USB/BLE connection, different app protocols
+
+**Implementation Requirements**:
+- Add `@ledgerhq/hw-app-btc` package for Ledger Bitcoin support
+- Add Trezor Connect SDK for Trezor Bitcoin support
+- Create unified hardware wallet connection manager (`mobile/src/features/HW/multi-chain-hw-manager.ts`)
+- Detect which app is open on device
+- Guide users to switch apps when needed
+- Blockchain-specific transaction signing flows
+- Store device info per blockchain
+
+**Key Files to Update**:
+- `mobile/src/wallets/cardano/hw/hw.ts` - Extend for Bitcoin
+- `mobile/src/wallets/hw/hw.ts` - Add blockchain parameter
+- `mobile/src/features/ReviewTx/common/ConfirmRawTxWithHw.tsx` - Make blockchain-aware
+- `mobile/packages/tx/ledger/` - Add Bitcoin ledger signing
+
+**Midnight Hardware Wallet**: Research needed - may not be available initially. Check Midnight SDK documentation for hardware wallet support.
+
+## Current State Analysis
+
+### Yoroi Blockchains Package (`mobile/packages/blockchains/`)
+- **Current Structure**: Cardano-only implementation
+ - `cardano/constants.ts` - Cardano-specific constants (eras, epochs, protocol params)
+ - `networks/network-configs.ts` - Hardcoded Cardano networks (Mainnet, Preprod, Preview)
+ - `networks/network-manager.ts` - Cardano-specific API maker
+ - `addresses/` - BIP32 derivation config (blockchain-agnostic)
+
+### Key Dependencies
+- `@yoroi/types` - `Chain.SupportedNetworks` currently only includes Cardano networks
+- `@yoroi/api` - `CardanoApi.cardanoApiMaker` is Cardano-specific
+- `@yoroi/tx` - Uses CSL (Cardano Serialization Library) for transaction building
+- `@yoroi/portfolio` - Token management is blockchain-agnostic but only used for Cardano
+- `@yoroi/explorers` - Explorer manager exists but only configured for Cardano
+- `@yoroi/dapp-connector` - CIP-30 connector for Cardano dApps
+- `@yoroi/links` - Cardano link parser (`web+cardano://`)
+
+### Bitcoin Implementation (from mesh/ctrl-mobile)
+- **Location**: `mesh/packages/bitcoin/`, `ctrl-mobile/src/modules/wallet/controllers/bitcoin.controller.ts`
+- **Key Components**:
+ - Providers: BlockstreamProvider, MaestroProvider (implements `IBitcoinProvider`)
+ - Wallet: EmbeddedWallet (uses BIP32/BIP39, supports P2PKH/P2WPKH/P2TR)
+ - UTXO model similar to Cardano
+ - Transaction building uses `@scure/btc-signer` or `bitcoinjs-lib`
+ - Fee estimation in sat/vB (different from Cardano)
+ - Message signing: ECDSA and BIP322 (BIP322 needs implementation)
+ - Links: BIP 21 standard (`bitcoin://` scheme)
+
+### Midnight Implementation (from midnight/mesh)
+- **Location**: `midnight/packages/mesh-midnight-core/`, `midnight/packages/mesh-midnight-wallet/`
+- **Key Components**:
+ - Providers: PublicDataProvider, PrivateStateProvider, ZKConfigProvider, ProofProvider
+ - Wallet: EmbeddedWallet using `@midnight-ntwrk/wallet-sdk-hd`
+ - Compact contracts (different from Cardano Plutus)
+ - ZK proof generation required for transactions
+ - Currently testnet only
+ - Links: Research needed - may need custom scheme
+
+## Implementation Plan
+
+### Phase 1: Type System & Blockchain Abstraction
+
+#### 1.1 Extend Type Definitions (`mobile/packages/types/`)
+- **File**: `chain/network.ts`
+ - Add `Bitcoin` and `Midnight` to `NetworkBlockchains` enum:
+ ```typescript
+ export enum NetworkBlockchains {
+ Cardano = 'cardano',
+ Bitcoin = 'bitcoin',
+ Midnight = 'midnight',
+ }
+ ```
+ - Extend `ChainSupportedNetworks` to include:
+ - Bitcoin: `bitcoin-mainnet`, `bitcoin-testnet`
+ - Midnight: `midnight-testnet` (mainnet when available)
+ - Create union type `Chain.SupportedNetworks` that includes all blockchain networks
+
+- **File**: `network/manager.ts`
+ - Refactor `NetworkConfig` to be blockchain-agnostic using discriminated unions:
+ ```typescript
+ type NetworkConfigBase = {
+ network: ChainSupportedNetworks
+ blockchain: NetworkBlockchains
+ isMainnet: boolean
+ primaryTokenInfo: PortfolioTokenInfo
+ name: string
+ chainId: number
+ legacyApiBaseUrl?: string
+ }
+
+ type NetworkConfigCardano = NetworkConfigBase & {
+ blockchain: NetworkBlockchains.Cardano
+ eras: ReadonlyArray
+ protocolMagic: number
+ epoch: Readonly<{
+ info: (date: Date) => Readonly
+ progress: (date: Date) => Readonly
+ }>
+ }
+
+ type NetworkConfigBitcoin = NetworkConfigBase & {
+ blockchain: NetworkBlockchains.Bitcoin
+ feeRate: { fast: number; medium: number; slow: number } // sat/vB
+ networkParams: BitcoinNetworkParams
+ }
+
+ type NetworkConfigMidnight = NetworkConfigBase & {
+ blockchain: NetworkBlockchains.Midnight
+ testnetConfig: MidnightTestnetConfig
+ providerUrls: MidnightProviderUrls
+ }
+
+ type NetworkConfig = NetworkConfigCardano | NetworkConfigBitcoin | NetworkConfigMidnight
+ ```
+
+- **File**: `api/` (new blockchain-agnostic API types)
+ - Create base `Api.Blockchain` interface
+ - Extend with `Api.Cardano`, `Api.Bitcoin`, `Api.Midnight`
+ - Each blockchain API should provide:
+ - `getUtxoData()` (or equivalent)
+ - `getBestBlock()` (or equivalent)
+ - `submitTransaction()`
+ - Blockchain-specific methods
+
+#### 1.2 Blockchain Registry (`mobile/packages/blockchains/blockchain-registry.ts`)
+- Create registry mapping blockchain types to implementations
+- Define blockchain capabilities:
+ ```typescript
+ type BlockchainCapabilities = {
+ isUTXO: boolean
+ supportsStaking: boolean
+ supportsSmartContracts: boolean
+ requiresZKProofs: boolean
+ coinType: number
+ derivationPath: string
+ curve: 'ed25519' | 'secp256k1'
+ }
+ ```
+- Store blockchain metadata (coin type, derivation paths, etc.)
+
+### Phase 2: Blockchain-Specific Implementations
+
+#### 2.1 Bitcoin Implementation (`mobile/packages/blockchains/bitcoin/`)
+
+**2.1.1 Constants** (`bitcoin/constants.ts`)
+- Network configurations:
+ ```typescript
+ export const bitcoinMainnetConfig = {
+ network: bitcoin.networks.bitcoin,
+ coinType: 0,
+ hrp: 'bc',
+ messagePrefix: '\x18Bitcoin Signed Message:\n',
+ }
+
+ export const bitcoinTestnetConfig = {
+ network: bitcoin.networks.testnet,
+ coinType: 1,
+ hrp: 'tb',
+ messagePrefix: '\x18Bitcoin Signed Message:\n',
+ }
+ ```
+- Fee rate configurations (sat/vB):
+ ```typescript
+ export const feeRates = {
+ mainnet: { fast: 10, medium: 5, slow: 1 },
+ testnet: { fast: 5, medium: 2, slow: 1 },
+ }
+ ```
+- Address type constants (P2PKH, P2WPKH, P2TR)
+- BIP32 coin type (0 for mainnet, 1 for testnet)
+
+**2.1.2 Providers** (`bitcoin/providers/`)
+- Port `BlockstreamProvider` from `mesh/packages/bitcoin/src/providers/blockstream.ts`
+- Port `MaestroProvider` from mesh if available
+- Create provider interface matching `IBitcoinProvider`:
+ ```typescript
+ interface IBitcoinProvider {
+ fetchAddress(address: string): Promise
+ fetchAddressUTxOs(address: string): Promise
+ fetchFeeEstimates(blocks: number): Promise
+ submitTx(tx: string): Promise
+ fetchTransactionStatus(txid: string): Promise
+ }
+ ```
+- Implement provider factory pattern
+
+**2.1.3 Wallet** (`bitcoin/wallet/`)
+- Port `EmbeddedWallet` from `mesh/packages/bitcoin/src/wallets/embedded/index.ts`
+- Adapt to Yoroi's wallet interface
+- Support multiple address types (segwit, legacy, taproot)
+- Implement key derivation using BIP32/BIP39
+- Key methods:
+ - `getAddresses()` - Get payment/ordinals addresses
+ - `getUTxOs()` - Fetch UTXOs
+ - `signMessage()` - Sign messages (ECDSA/BIP322)
+ - `signPsbt()` - Sign PSBT transactions
+ - `sendTransfer()` - Send Bitcoin transactions
+
+**2.1.4 Network Config** (`bitcoin/network-config.ts`)
+- Define Bitcoin network configs:
+ ```typescript
+ bitcoin-mainnet: {
+ blockchain: NetworkBlockchains.Bitcoin,
+ network: 'bitcoin-mainnet',
+ isMainnet: true,
+ primaryTokenInfo: { ticker: 'BTC', decimals: 8, name: 'Bitcoin', symbol: '₿' },
+ feeRate: { fast: 10, medium: 5, slow: 1 }, // sat/vB
+ chainId: 0,
+ ...
+ }
+ ```
+
+#### 2.2 Midnight Implementation (`mobile/packages/blockchains/midnight/`)
+
+**2.2.1 Constants** (`midnight/constants.ts`)
+- Testnet configuration
+- Provider URLs (from Midnight SDK)
+- Contract deployment configs
+- ZK proof configuration
+
+**2.2.2 Providers** (`midnight/providers/`)
+- Port provider wrappers from `midnight/packages/mesh-midnight-core/src/providers-wrappers/`
+- Implement `PublicDataProvider`, `PrivateStateProvider`, `ZKConfigProvider`, `ProofProvider`
+- Create provider factory
+- Key providers:
+ - `indexerPublicDataProvider` - Query public chain data
+ - `levelPrivateStateProvider` - Manage private state
+ - `fetchZkConfigProvider` - ZK configuration
+ - `httpClientProofProvider` - Generate ZK proofs
+
+**2.2.3 Wallet** (`midnight/wallet/`)
+- Port `EmbeddedWallet` from `midnight/packages/mesh-midnight-wallet/src/embedded/embedded-wallet.ts`
+- Integrate HD wallet using `@midnight-ntwrk/wallet-sdk-hd`
+- Support ZK proof generation
+- Key methods:
+ - `getAddresses()` - Get ZSwap addresses
+ - `getBalance()` - Query balance (requires ZK proof)
+ - `balanceAndProveTransaction()` - Balance + generate proof
+ - `submitTransaction()` - Submit with ZK proof
+
+**2.2.4 Network Config** (`midnight/network-config.ts`)
+- Define Midnight testnet config
+- Prepare for mainnet when available
+- Store provider URLs and configuration
+
+### Phase 3: API Layer Refactoring
+
+#### 3.1 Abstract API Maker (`mobile/packages/api/blockchain-api-maker.ts`)
+- Create factory function that returns blockchain-specific API makers:
+ ```typescript
+ export const blockchainApiMaker = ({
+ blockchain,
+ network,
+ }: {
+ blockchain: NetworkBlockchains
+ network: ChainSupportedNetworks
+ }) => {
+ switch (blockchain) {
+ case NetworkBlockchains.Cardano:
+ return CardanoApi.cardanoApiMaker({ network })
+ case NetworkBlockchains.Bitcoin:
+ return BitcoinApi.bitcoinApiMaker({ network })
+ case NetworkBlockchains.Midnight:
+ return MidnightApi.midnightApiMaker({ network })
+ }
+ }
+ ```
+
+#### 3.2 Bitcoin API (`mobile/packages/api/bitcoin/`)
+- **File**: `api/bitcoin-api-maker.ts`
+ - Implement `Api.Bitcoin.Api` interface
+ - Methods:
+ - `getUtxoData(address: string)` - Fetch UTXOs from provider
+ - `getBestBlock()` - Get latest block height
+ - `getFeeEstimates()` - Get fee rates in sat/vB
+ - `submitTransaction(txHex: string)` - Submit transaction
+ - `getAddressInfo(address: string)` - Get address balance/transactions
+
+- **File**: `api/utxo-data.ts`
+ - Fetch UTXOs from provider (Blockstream/Maestro)
+ - Transform to Yoroi UTXO format:
+ ```typescript
+ type BitcoinUtxo = {
+ txid: string
+ vout: number
+ value: number // satoshis
+ status: { confirmed: boolean; block_height?: number }
+ }
+ ```
+
+- **File**: `api/fee-estimates.ts`
+ - Fetch fee estimates from provider
+ - Return in sat/vB format
+ - Support multiple confirmation targets (1, 3, 6 blocks)
+
+#### 3.3 Midnight API (`mobile/packages/api/midnight/`)
+- **File**: `api/midnight-api-maker.ts`
+ - Implement `Api.Midnight.Api` interface
+ - Methods:
+ - `getContractState(address: ContractAddress)` - Query contract state
+ - `getZSwapState()` - Get ZSwap chain state
+ - `submitTransaction(tx: Transaction)` - Submit with ZK proof
+ - `watchForTxData(txId: TransactionId)` - Watch transaction status
+ - `generateZKProof(tx: Transaction)` - Generate ZK proof
+
+- **File**: `api/contract-state.ts`
+ - Query contract states using PublicDataProvider
+ - Handle private state queries
+ - Watch for state changes
+
+### Phase 4: Network Manager Refactoring
+
+#### 4.1 Update Network Configs (`mobile/packages/blockchains/networks/network-configs.ts`)
+- Add Bitcoin and Midnight network configs
+- Refactor to use blockchain-specific configs
+- Update `buildNetworkManagers` to handle multiple blockchains
+- Example Bitcoin config:
+ ```typescript
+ [Chain.Network.BitcoinMainnet]: {
+ blockchain: NetworkBlockchains.Bitcoin,
+ network: Chain.Network.BitcoinMainnet,
+ isMainnet: true,
+ name: 'Bitcoin Mainnet',
+ primaryTokenInfo: { ticker: 'BTC', decimals: 8, ... },
+ chainId: 0,
+ feeRate: { fast: 10, medium: 5, slow: 1 },
+ networkParams: bitcoinMainnetConfig,
+ }
+ ```
+
+#### 4.2 Update Network Manager (`mobile/packages/blockchains/networks/network-manager.ts`)
+- Refactor `buildNetworkManagers` to:
+ - Accept blockchain-specific API makers
+ - Create appropriate API instances per blockchain
+ - Handle blockchain-specific storage needs
+ - Support blockchain-specific explorers
+- Update signature:
+ ```typescript
+ export function buildNetworkManagers({
+ tokenManagers,
+ apiMaker = blockchainApiMaker, // Changed from CardanoApi.cardanoApiMaker
+ }: {
+ tokenManagers: TokenManagerByNetwork
+ apiMaker?: ({blockchain, network}: {blockchain: NetworkBlockchains, network: Chain.SupportedNetworks}) => Api.Blockchain.Api
+ })
+ ```
+
+#### 4.3 Blockchain-Specific Helpers
+- **Cardano**: Keep existing epoch/era helpers
+- **Bitcoin**: Add fee estimation helpers, block time helpers
+- **Midnight**: Add contract state helpers, ZK proof helpers
+
+### Phase 5: Transaction Building & Signing
+
+#### 5.1 Abstract Transaction Builder (`mobile/packages/tx/blockchain-tx-builder.ts`)
+- Create blockchain-agnostic transaction builder interface:
+ ```typescript
+ interface BlockchainTxBuilder {
+ buildTransaction(state: TransactionBuilderState): Promise
+ signTransaction(unsignedTx: UnsignedTransaction, keys: SigningKeys): Promise
+ }
+ ```
+- Factory pattern to get blockchain-specific builders
+
+#### 5.2 Bitcoin Transaction Builder (`mobile/packages/tx/bitcoin/`)
+- **File**: `bitcoin-tx-builder.ts`
+ - Port transaction building logic from `ctrl-mobile/src/modules/wallet/controllers/bitcoin.controller.ts`
+ - Use `@scure/btc-signer` for transaction building
+ - Support UTXO selection
+ - Fee calculation in sat/vB
+ - Support multiple address types (P2PKH, P2WPKH, P2TR)
+ - Key methods:
+ - `buildTransaction(inputs, outputs, feeRate)` - Build unsigned transaction
+ - `estimateFee(inputs, outputs)` - Estimate transaction fee
+ - `selectUtxos(amount, utxos)` - UTXO selection algorithm
+
+- **File**: `bitcoin-signer.ts`
+ - Sign transactions with private keys
+ - Support hardware wallet signing (Ledger/Trezor)
+ - PSBT support for complex transactions
+
+#### 5.3 Midnight Transaction Builder (`mobile/packages/tx/midnight/`)
+- **File**: `midnight-tx-builder.ts`
+ - Build transactions using Midnight SDK
+ - Integrate ZK proof generation
+ - Handle contract interactions
+ - Support private state updates
+ - Key methods:
+ - `buildTransaction(contractCall, privateState)` - Build transaction
+ - `generateZKProof(tx)` - Generate ZK proof using ProofProvider
+ - `balanceTransaction(tx, newCoins)` - Balance transaction
+
+- **File**: `midnight-signer.ts`
+ - Sign transactions
+ - Generate ZK proofs using ProofProvider
+ - Handle proof generation errors
+
+#### 5.4 Update Transaction Package (`mobile/packages/tx/`)
+- Keep Cardano transaction builder as-is
+- Add blockchain parameter to transaction building functions
+- Create unified transaction interface that works across blockchains
+- Update `UnsignedTransaction` type to be blockchain-agnostic:
+ ```typescript
+ type UnsignedTransaction = {
+ blockchain: NetworkBlockchains
+ inputs: TransactionInput[]
+ outputs: TransactionOutput[]
+ fee: string
+ cbor?: string // Cardano-specific
+ hex?: string // Bitcoin-specific
+ tx?: Transaction // Midnight-specific
+ }
+ ```
+
+### Phase 6: Wallet Management Updates
+
+#### 6.1 Wallet Creation (`mobile/src/features/WalletManager/`)
+- **File**: `wallet-manager.ts`
+ - Update `createWalletMnemonic` to support blockchain selection:
+ ```typescript
+ createWalletMnemonic(params: {
+ name: string
+ mnemonic: string
+ password: string
+ blockchains: NetworkBlockchains[] // New: which blockchains to enable
+ implementation: Wallet.Implementation
+ addressMode: Wallet.AddressMode
+ accountVisual: number
+ })
+ ```
+ - Add blockchain-specific derivation paths
+ - Support multi-chain wallets (single mnemonic, multiple blockchains)
+ - Store enabled blockchains in wallet metadata
+
+- **File**: `wallet-creation/`
+ - Add blockchain selection UI
+ - Show blockchain-specific options:
+ - Bitcoin: Address type selection (SegWit/Legacy/Taproot)
+ - Midnight: Testnet warning
+ - Multi-chain wallet creation option
+ - Single mnemonic → multiple blockchain accounts
+
+#### 6.2 Wallet Storage (`mobile/src/wallets/`)
+- **File**: `wallet-storage.ts`
+ - Update wallet storage schema to include blockchain type:
+ ```typescript
+ type WalletMeta = {
+ id: string
+ name: string
+ enabledBlockchains: NetworkBlockchains[] // New
+ // ... existing fields
+ }
+ ```
+ - Store blockchain-specific data (addresses, keys per blockchain)
+ - Support multiple accounts per blockchain
+ - Migration: Add `enabledBlockchains: ['cardano']` to existing wallets
+
+#### 6.3 Address Management
+- **File**: `addresses/bitcoin-address-manager.ts`
+ - Generate Bitcoin addresses (P2PKH, P2WPKH, P2TR)
+ - Manage address derivation paths
+ - Support address reuse policies
+ - Key methods:
+ - `generateAddress(derivationPath, addressType)` - Generate address
+ - `validateAddress(address)` - Validate Bitcoin address format
+ - `getAddressType(address)` - Detect address type
+
+- **File**: `addresses/midnight-address-manager.ts`
+ - Generate Midnight addresses
+ - Manage contract addresses
+ - Handle ZSwap addresses
+ - Key methods:
+ - `generateZSwapAddress(account, role, index)` - Generate ZSwap address
+ - `generateContractAddress(contractId)` - Generate contract address
+
+### Phase 7: Portfolio & Balance Management
+
+#### 7.1 Multi-Chain Balance (`mobile/packages/portfolio/`)
+- **File**: `balance-manager.ts`
+ - Update to handle multiple blockchains
+ - Aggregate balances across blockchains
+ - Blockchain-specific balance calculations
+ - Update signature to accept blockchain parameter:
+ ```typescript
+ syncBalances({
+ blockchain: NetworkBlockchains,
+ primaryStated,
+ secondaryBalances,
+ })
+ ```
+
+#### 7.2 Token Management
+- Bitcoin: Native BTC only (no tokens initially)
+- Midnight: Support native tokens and contract tokens
+- Update token discovery to be blockchain-aware
+- Token storage per blockchain
+
+### Phase 8: Explorer Integration
+
+#### 8.1 Bitcoin Explorers (`mobile/packages/explorers/bitcoin/`)
+- Add Blockstream explorer:
+ ```typescript
+ blockstream: {
+ mainnet: 'https://blockstream.info',
+ testnet: 'https://blockstream.info/testnet',
+ txPath: '/tx/',
+ addressPath: '/address/',
+ }
+ ```
+- Add blockchain.com explorer
+- Support transaction and address viewing
+- Update explorer manager to include Bitcoin explorers
+
+#### 8.2 Midnight Explorers (`mobile/packages/explorers/midnight/`)
+- Add Midnight testnet explorer
+- Support contract state viewing
+- Transaction status tracking
+- Update explorer manager to include Midnight explorers
+
+#### 8.3 Update Explorer Manager (`mobile/packages/explorers/explorer-manager.ts`)
+- Add Bitcoin and Midnight explorers
+- Make explorer selection blockchain-aware
+- Update `explorerManager` to support all blockchains
+
+### Phase 9: UI Updates
+
+#### 9.1 Network Selection (`mobile/src/features/NetworkSelection/`)
+- Add blockchain selection to network picker
+- Show available networks per blockchain
+- Handle network switching across blockchains
+- UI: Dropdown or tabs for blockchain selection
+
+#### 9.2 Wallet Creation Flow (`mobile/src/features/SetupWallet/`)
+- Add blockchain selection step
+- Show blockchain-specific options:
+ - Bitcoin: Address type selection (SegWit/Legacy/Taproot)
+ - Midnight: Testnet warning
+- Multi-chain wallet creation option
+- Single mnemonic → multiple blockchain accounts
+- UI: Checkboxes for blockchain selection
+
+#### 9.3 Transaction UI (`mobile/src/features/Transfer/`)
+- **File**: `send-form.tsx`
+ - Blockchain-aware form validation
+ - Blockchain-specific fee display:
+ - Bitcoin: Show fee rate (sat/vB) and total fee (BTC)
+ - Midnight: Show ZK proof status
+ - Address format validation per blockchain
+ - Update address input to validate based on selected blockchain
+
+- **File**: `transaction-review.tsx`
+ - Show blockchain-specific transaction details
+ - Bitcoin: Show inputs/outputs, fee rate, address types
+ - Midnight: Show contract interactions, ZK proof status
+ - Update review screen to display blockchain-specific info
+
+#### 9.4 Balance Display (`mobile/src/features/Portfolio/`)
+- Show balances per blockchain
+- Aggregate total value (if exchange rates available)
+- Blockchain-specific token lists
+- UI: Tabs or sections per blockchain
+
+#### 9.5 Transaction History (`mobile/src/features/Transactions/`)
+- Filter by blockchain
+- Blockchain-specific transaction details
+- Explorer links per blockchain
+- Update transaction list to show blockchain indicator
+
+#### 9.6 Hardware Wallet UI (`mobile/src/features/HW/`)
+- **File**: `multi-chain-hw-manager.tsx`
+ - Multi-chain hardware wallet connection manager
+ - Detect which app is open on device
+ - Guide users to switch apps when needed
+ - Unified connection/disconnection UI
+
+- **File**: `hw-app-detector.ts`
+ - Detect which hardware wallet app is open
+ - Prompt user to switch apps if needed
+ - Show clear error messages
+
+### Phase 10: Deep Links & QR Codes
+
+#### 10.1 Bitcoin Links (`mobile/packages/links/bitcoin/`)
+- **File**: `bitcoin-module.ts`
+ - Implement BIP 21 parser (`bitcoin://` scheme)
+ - Parse format: `bitcoin:[?amount=][&label=