branch backend + ajout du serveur backend, next, et sqlite

This commit is contained in:
streaper2
2026-04-29 15:45:09 +02:00
parent 105eb1cab0
commit cea2fab989
42 changed files with 10566 additions and 4 deletions

View File

@@ -0,0 +1,112 @@
import 'dart:math';
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'dart:io';
class WalletIdentityService {
static const String _prefsKey = 'wallet_identity_phrase';
static const String _uploadEnabledKey = 'is_ai_upload_enabled';
// A standard list of 256 words (8 bits of entropy per word)
static const List<String> _wordList = [
// ... same as before
'abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract', 'absurd', 'abuse',
'access', 'accident', 'account', 'accuse', 'achieve', 'acid', 'acoustic', 'acquire', 'across', 'act',
'action', 'actor', 'actress', 'actual', 'adapt', 'add', 'addict', 'address', 'adjust', 'admit',
'adult', 'advance', 'advice', 'aerobic', 'affair', 'afford', 'afraid', 'again', 'age', 'agent',
'agree', 'ahead', 'aim', 'air', 'airport', 'aisle', 'alarm', 'album', 'alcohol', 'alert',
'alien', 'all', 'alley', 'allow', 'almost', 'alone', 'alpha', 'already', 'also', 'alter',
'always', 'amateur', 'amazing', 'among', 'amount', 'amused', 'analyst', 'anchor', 'ancient', 'anger',
'angle', 'angry', 'animal', 'ankle', 'announce', 'annual', 'another', 'answer', 'antenna', 'antique',
'anxiety', 'any', 'apart', 'apology', 'appear', 'apple', 'approve', 'april', 'arch', 'arctic',
'area', 'arena', 'argue', 'arm', 'armed', 'armor', 'army', 'around', 'arrange', 'arrest',
'arrive', 'arrow', 'art', 'artefact', 'artist', 'artwork', 'ask', 'aspect', 'assault', 'asset',
'assist', 'assume', 'asthma', 'athlete', 'atom', 'attack', 'attend', 'attitude', 'attract', 'auction',
'audit', 'august', 'aunt', 'author', 'auto', 'autumn', 'average', 'avocado', 'avoid', 'awake',
'aware', 'away', 'awesome', 'awful', 'awkward', 'axis', 'baby', 'bachelor', 'bacon', 'badge',
'bag', 'balance', 'balcony', 'ball', 'bamboo', 'banana', 'banner', 'bar', 'barely', 'bargain',
'barrel', 'base', 'basic', 'basket', 'battle', 'beach', 'bean', 'beauty', 'because', 'become',
'beef', 'before', 'begin', 'behave', 'behind', 'believe', 'below', 'belt', 'bench', 'benefit',
'best', 'betray', 'better', 'between', 'beyond', 'bicycle', 'bid', 'bike', 'bind', 'biology',
'bird', 'birth', 'bitter', 'black', 'blade', 'blame', 'blanket', 'blast', 'bleak', 'bless',
'blind', 'blood', 'blossom', 'blouse', 'blue', 'blur', 'blush', 'board', 'boat', 'body',
'boil', 'bomb', 'bone', 'bonus', 'book', 'boost', 'border', 'boring', 'borrow', 'boss',
'bottom', 'bounce', 'box', 'boy', 'bracket', 'brain', 'brand', 'brass', 'brave', 'bread',
'breeze', 'brick', 'bridge', 'brief', 'bright', 'bring', 'brisk', 'broccoli', 'broken', 'bronze',
'broom', 'brother', 'brown', 'brush', 'bubble', 'buddy', 'budget', 'buffalo', 'build', 'bulb',
'bulk', 'bullet', 'bundle', 'bunker', 'burden', 'burger', 'burst', 'bus', 'business', 'butter'
];
/// Vérifie si l'utilisateur a accepté l'envoi de données à l'IA
Future<bool> isUploadEnabled() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getBool(_uploadEnabledKey) ?? false;
}
/// Active ou désactive l'envoi de données
Future<void> setUploadEnabled(bool enabled) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_uploadEnabledKey, enabled);
}
/// Gets the unique 15-word identity phrase
Future<String> getIdentityPhrase() async {
final prefs = await SharedPreferences.getInstance();
// Check if we already generated it
final existingPhrase = prefs.getString(_prefsKey);
if (existingPhrase != null && existingPhrase.isNotEmpty) {
return existingPhrase;
}
// Generate new phrase based on device ID
final phrase = await _generatePhraseFromDevice();
// Save for future use
await prefs.setString(_prefsKey, phrase);
return phrase;
}
Future<String> _generatePhraseFromDevice() async {
final deviceInfo = DeviceInfoPlugin();
String deviceId = 'unknown_device_${DateTime.now().millisecondsSinceEpoch}';
try {
if (Platform.isAndroid) {
final androidInfo = await deviceInfo.androidInfo;
deviceId = androidInfo.id; // Unique Android ID
} else if (Platform.isIOS) {
final iosInfo = await deviceInfo.iosInfo;
deviceId = iosInfo.identifierForVendor ?? deviceId;
} else if (Platform.isWindows) {
final windowsInfo = await deviceInfo.windowsInfo;
deviceId = windowsInfo.deviceId;
}
} catch (e) {
print('Erreur lecture device ID: $e');
}
// Add a salt to the device ID
final salt = 'bully_app_wallet_salt_v1';
final bytes = utf8.encode(deviceId + salt);
final digest = sha256.convert(bytes);
// Use the hash to seed a random number generator
// We take the first 4 bytes of the hash as the seed
final seedBytes = digest.bytes.sublist(0, 4);
final seed = (seedBytes[0] << 24) | (seedBytes[1] << 16) | (seedBytes[2] << 8) | seedBytes[3];
final random = Random(seed);
List<String> phraseWords = [];
for (int i = 0; i < 15; i++) {
final randomIndex = random.nextInt(_wordList.length);
phraseWords.add(_wordList[randomIndex]);
}
return phraseWords.join(' ');
}
}