import 'dart:convert'; import 'dart:typed_data'; import 'package:durt/durt.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'data/models/cesium_card.dart'; import 'data/models/credit_card_themes.dart'; import 'g1/g1_helper.dart'; import 'ui/logger.dart'; class SharedPreferencesHelper { factory SharedPreferencesHelper() { return _instance; } SharedPreferencesHelper._internal() { SharedPreferences.getInstance().then((SharedPreferences value) { _prefs = value; }); } List<CesiumCard> cesiumCards = <CesiumCard>[]; static final SharedPreferencesHelper _instance = SharedPreferencesHelper._internal(); late SharedPreferences _prefs; static const String _seedKey = 'seed'; static const String _pubKey = 'pub'; Future<void> init() async { _prefs = await SharedPreferences.getInstance(); final String? json = _prefs.getString('cesiumCards'); if (json != null) { final List<dynamic> list = jsonDecode(json) as List<dynamic>; cesiumCards = list .map((dynamic e) => CesiumCard.fromJson(e as Map<String, dynamic>)) .toList(); } // Migrate the current pair if exists await migrateCurrentPair(); } Future<void> migrateCurrentPair() async { if (_prefs.containsKey(_seedKey) && _prefs.containsKey(_pubKey) && cesiumCards.isEmpty) { final String seed = _prefs.getString(_seedKey)!; final String pubKey = _prefs.getString(_pubKey)!; final CesiumCard card = buildCesiumCard(seed: seed, pubKey: pubKey); addCesiumCard(card); // Let's do this later // await _prefs.remove(_seedKey); // await _prefs.remove(_pubKey); setCurrentWalletIndex(0); } } CesiumCard buildCesiumCard({required String seed, required String pubKey}) { return CesiumCard( seed: seed, pubKey: pubKey, theme: CreditCardThemes.theme1, name: dotenv.env['CARD_TEXT'] ?? tr('g1_wallet')); } void addCesiumCard(CesiumCard cesiumCard) { cesiumCards.add(cesiumCard); saveCesiumCards(); } void removeCesiumCard(int index) { // Don't allow the last card to be removed if (cesiumCards.length > 1) { cesiumCards.removeAt(index); saveCesiumCards(); } } Future<void> saveCesiumCards() async { final String json = jsonEncode(cesiumCards.map((CesiumCard e) => e.toJson()).toList()); await _prefs.setString('cesiumCards', json); } // Get the wallet from the specified index (default to first wallet) Future<CesiumWallet> getWallet({int index = 0}) async { if (cesiumCards.isNotEmpty && index < cesiumCards.length) { final CesiumCard card = cesiumCards[index]; return CesiumWallet.fromSeed(seedFromString(card.seed)); } else { // Generate a new wallet if no wallets exist final Uint8List uS = generateUintSeed(); final String seed = seedToString(uS); final CesiumWallet wallet = CesiumWallet.fromSeed(uS); logger('Generated public key: ${wallet.pubkey}'); addCesiumCard(buildCesiumCard(seed: seed, pubKey: wallet.pubkey)); return wallet; } } // Get the public key from the specified index (default to first wallet) String getPubKey({int index = 0}) { final CesiumCard card = cesiumCards[index]; final String pubKey = card.pubKey; final String checksum = pkChecksum(pubKey); return '$pubKey:$checksum'; } List<CesiumCard> get cards => cesiumCards; static const String _currentWalletIndexKey = 'current_wallet_index'; // Get the current wallet index from shared preferences int getCurrentWalletIndex() { return _prefs.getInt(_currentWalletIndexKey) ?? 0; } // Set the current wallet index in shared preferences Future<void> setCurrentWalletIndex(int index) async { await _prefs.setInt(_currentWalletIndexKey, index); } // Select the current wallet and save its index in shared preferences Future<void> selectCurrentWallet(int index) async { if (index < cesiumCards.length) { final CesiumCard card = cesiumCards[index]; await setCurrentWalletIndex(index); logger('Selected wallet: ${card.pubKey}'); } else { logger('Invalid wallet index: $index'); } } // Get the currently selected wallet Future<CesiumWallet> getCurrentWallet() async { final int index = getCurrentWalletIndex(); return getWallet(index: index); } @Deprecated('We should remove this in the future when multi-card is enabled') void setDefaultWallet(CesiumCard defCesiumCard) { cesiumCards[0] = defCesiumCard; saveCesiumCards(); } }