feat: integrate internal Rust bridge, remove cdk_flutter dependency (Phase 2)

This commit is contained in:
Forte11Cuba
2026-03-28 15:04:54 -06:00
parent 01ea5be578
commit 989b710cd8
15 changed files with 38 additions and 60 deletions
+3 -3
View File
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:cdk_flutter/cdk_flutter.dart' hide WalletProvider; import 'src/rust/frb_generated.dart';
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import 'core/theme/app_theme.dart'; import 'core/theme/app_theme.dart';
import 'providers/wallet_provider.dart'; import 'providers/wallet_provider.dart';
@@ -15,8 +15,8 @@ import 'screens/1_splash/splash_screen.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
// Inicializar CDK Flutter (Cashu SDK) // Inicializar bridge Rust interno (Cashu SDK)
await CdkFlutter.init(); await RustLib.init();
// Configurar orientación y estilo de barra de estado // Configurar orientación y estilo de barra de estado
SystemChrome.setPreferredOrientations([ SystemChrome.setPreferredOrientations([
+1 -1
View File
@@ -11,7 +11,7 @@ import 'dart:convert';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:bip32/bip32.dart' as bip32; import 'package:bip32/bip32.dart' as bip32;
import 'package:cdk_flutter/cdk_flutter.dart' as cdk; import '../src/rust/api/keys.dart' as cdk;
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import '../models/p2pk_key.dart'; import '../models/p2pk_key.dart';
+12 -31
View File
@@ -3,8 +3,10 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:cbor/cbor.dart'; import 'package:cbor/cbor.dart';
import 'package:cdk_flutter/cdk_flutter.dart'; import '../src/rust/api/wallet.dart';
import 'package:http/http.dart' as http; import '../src/rust/api/token.dart';
import '../src/rust/api/mint_info.dart';
import '../src/rust/api/keys.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@@ -177,15 +179,11 @@ class WalletProvider extends ChangeNotifier {
// ============================================================ // ============================================================
/// Verifica si podemos alcanzar un mint específico. /// Verifica si podemos alcanzar un mint específico.
/// Hace ping HTTP GET a {mintUrl}/v1/info con timeout de 3 segundos. /// Usa función Rust que hace GET a {mintUrl}/v1/info.
/// Retorna true si responde 200, false en cualquier otro caso. /// Retorna true si responde 200, false en cualquier otro caso.
Future<bool> canReachMint(String mintUrl) async { Future<bool> canReachMint(String mintUrl) async {
try { try {
final uri = Uri.parse('$mintUrl/v1/info'); return await pingMint(mintUrl: mintUrl);
final response = await http.get(uri).timeout(
const Duration(seconds: 3),
);
return response.statusCode == 200;
} catch (e) { } catch (e) {
debugPrint('Ping to mint failed: $e'); debugPrint('Ping to mint failed: $e');
return false; return false;
@@ -409,7 +407,7 @@ class WalletProvider extends ChangeNotifier {
/// Usa mintInfo.nuts.nut04 (MintMethodSettings) para obtener las unidades. /// Usa mintInfo.nuts.nut04 (MintMethodSettings) para obtener las unidades.
Future<List<String>> _detectAndAddMint(String mintUrl) async { Future<List<String>> _detectAndAddMint(String mintUrl) async {
try { try {
// Obtener info del mint (función global de cdk_flutter) // Obtener info del mint (función del bridge Rust)
final mintInfo = await getMintInfo(mintUrl: mintUrl); final mintInfo = await getMintInfo(mintUrl: mintUrl);
// Extraer unidades de nut04 (mint methods) // Extraer unidades de nut04 (mint methods)
@@ -446,31 +444,14 @@ class WalletProvider extends ChangeNotifier {
} }
/// Obtiene los keysets de un mint y los agrega al caché _keysetUnits. /// Obtiene los keysets de un mint y los agrega al caché _keysetUnits.
/// Llama a GET {mintUrl}/v1/keysets para obtener el mapping keyset_id → unit. /// Usa función Rust que llama a GET {mintUrl}/v1/keysets.
Future<void> _fetchKeysets(String mintUrl) async { Future<void> _fetchKeysets(String mintUrl) async {
try { try {
final response = await http.get( final keysets = await fetchKeysets(mintUrl: mintUrl);
Uri.parse('$mintUrl/v1/keysets'), for (final ks in keysets) {
headers: {'Content-Type': 'application/json'}, _keysetUnits[ks.id] = ks.unit;
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as Map<String, dynamic>;
final keysets = data['keysets'] as List<dynamic>?;
if (keysets != null) {
for (final ks in keysets) {
final id = ks['id'] as String?;
final unit = ks['unit'] as String?;
if (id != null && unit != null) {
_keysetUnits[id] = unit;
}
}
debugPrint('Keysets cargados para $mintUrl: ${keysets.length}');
}
} else {
debugPrint('Error HTTP ${response.statusCode} al obtener keysets de $mintUrl');
} }
debugPrint('Keysets cargados para $mintUrl: ${keysets.length}');
} catch (e) { } catch (e) {
debugPrint('Error obteniendo keysets de $mintUrl: $e'); debugPrint('Error obteniendo keysets de $mintUrl: $e');
// No lanzamos excepción, el caché simplemente no tendrá estos keysets // No lanzamos excepción, el caché simplemente no tendrá estos keysets
@@ -64,7 +64,7 @@ class _RestoreWalletScreenState extends State<RestoreWalletScreen> {
final p2pkProvider = context.read<P2PKProvider>(); final p2pkProvider = context.read<P2PKProvider>();
// Inicializar wallet primero (valida el mnemonic internamente). // Inicializar wallet primero (valida el mnemonic internamente).
// Si es inválido, cdk_flutter lanzará una excepción antes de persistir. // Si es inválido, el bridge Rust lanzará una excepción antes de persistir.
await walletProvider.initialize(mnemonic); await walletProvider.initialize(mnemonic);
// Solo guardar mnemonic si initialize() pasó sin error // Solo guardar mnemonic si initialize() pasó sin error
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
import 'package:cdk_flutter/cdk_flutter.dart' as cdk; import '../../src/rust/api/token.dart' as cdk;
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import '../../core/constants/colors.dart'; import '../../core/constants/colors.dart';
import '../../core/constants/dimensions.dart'; import '../../core/constants/dimensions.dart';
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
import 'package:cdk_flutter/cdk_flutter.dart' hide WalletProvider; import '../../src/rust/api/wallet.dart';
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import '../../core/constants/colors.dart'; import '../../core/constants/colors.dart';
import '../../core/constants/dimensions.dart'; import '../../core/constants/dimensions.dart';
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
import 'package:cdk_flutter/cdk_flutter.dart' hide WalletProvider; import '../../src/rust/api/wallet.dart';
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import '../../core/constants/colors.dart'; import '../../core/constants/colors.dart';
import '../../core/constants/dimensions.dart'; import '../../core/constants/dimensions.dart';
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
import 'package:cdk_flutter/cdk_flutter.dart' show MintInfo, ContactInfo; import '../../src/rust/api/mint_info.dart' show MintInfo, ContactInfo;
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import '../../core/constants/colors.dart'; import '../../core/constants/colors.dart';
import '../../core/utils/formatters.dart'; import '../../core/utils/formatters.dart';
+2 -2
View File
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:cdk_flutter/cdk_flutter.dart' show MintInfo; import '../../src/rust/api/mint_info.dart' show MintInfo;
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import '../../core/constants/colors.dart'; import '../../core/constants/colors.dart';
import '../../core/constants/dimensions.dart'; import '../../core/constants/dimensions.dart';
@@ -623,7 +623,7 @@ class _AddMintDialogState extends State<_AddMintDialog> {
}); });
try { try {
// Intentar agregar el mint (cdk_flutter validará la conexión) // Intentar agregar el mint (el bridge Rust validará la conexión)
await widget.walletProvider.addMint(url); await widget.walletProvider.addMint(url);
if (mounted) { if (mounted) {
+2 -2
View File
@@ -5,8 +5,8 @@ import 'package:provider/provider.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:cdk_flutter/cdk_flutter.dart' as cdk; import '../../src/rust/api/token.dart' as cdk;
import 'package:cdk_flutter/cdk_flutter.dart' show Transaction, TransactionDirection, TransactionStatus; import '../../src/rust/api/wallet.dart' show Transaction, TransactionDirection, TransactionStatus;
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import '../../core/constants/colors.dart'; import '../../core/constants/colors.dart';
import '../../core/constants/dimensions.dart'; import '../../core/constants/dimensions.dart';
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:lucide_icons/lucide_icons.dart'; import 'package:lucide_icons/lucide_icons.dart';
import 'package:elcaju/l10n/app_localizations.dart'; import 'package:elcaju/l10n/app_localizations.dart';
import 'package:cdk_flutter/cdk_flutter.dart'; import '../../src/rust/api/token.dart';
import '../../core/constants/colors.dart'; import '../../core/constants/colors.dart';
import '../../core/utils/incoming_data_parser.dart'; import '../../core/utils/incoming_data_parser.dart';
+1 -1
View File
@@ -8,7 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
cdk_flutter rust_builder
) )
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)
+7 -9
View File
@@ -161,15 +161,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.5" version: "6.3.5"
cdk_flutter:
dependency: "direct main"
description:
path: "."
ref: HEAD
resolved-ref: "7fb8580530d963c9ff09f23e55a1e56bccd8676b"
url: "https://github.com/cashubtc/cdk_flutter.git"
source: git
version: "0.1.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
@@ -814,6 +805,13 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.0" version: "4.1.0"
rust_builder:
dependency: "direct main"
description:
path: rust_builder
relative: true
source: path
version: "0.1.0"
share_plus: share_plus:
dependency: "direct main" dependency: "direct main"
description: description:
+3 -4
View File
@@ -15,10 +15,9 @@ dependencies:
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
# CDK Flutter (Cashu backend) # Internal Rust bridge (Cashu backend via cdk)
cdk_flutter: rust_builder:
git: path: rust_builder
url: https://github.com/cashubtc/cdk_flutter.git
# State Management # State Management
provider: ^6.1.2 provider: ^6.1.2
+1 -1
View File
@@ -9,7 +9,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
cdk_flutter rust_builder
) )
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)