feat(mobile-app): add detailed debug logging for account creation flow

Add comprehensive debugPrint logging with [Tag] prefixes:
- [AccountService]: API calls, storage operations, responses
- [OnboardingPage]: account status check, creation flow
- [BackupMnemonicPage]: wallet info loading, polling state

Logging includes:
- Request/response details with masked sensitive data
- Stack traces for error handling
- Polling count and timing for wallet generation
- User interaction tracking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-06 20:03:36 -08:00
parent 6150617c14
commit 37aab77e7a
3 changed files with 268 additions and 39 deletions

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import '../network/api_client.dart'; import '../network/api_client.dart';
import '../storage/secure_storage.dart'; import '../storage/secure_storage.dart';
@ -44,6 +45,10 @@ class DeviceHardwareInfo {
if (sdkInt != null) 'sdkInt': sdkInt, if (sdkInt != null) 'sdkInt': sdkInt,
if (isPhysicalDevice != null) 'isPhysicalDevice': isPhysicalDevice, if (isPhysicalDevice != null) 'isPhysicalDevice': isPhysicalDevice,
}; };
@override
String toString() =>
'DeviceHardwareInfo(brand: $brand, model: $model, platform: $platform, osVersion: $osVersion)';
} }
/// ///
@ -64,6 +69,10 @@ class CreateAccountRequest {
if (inviterReferralCode != null) if (inviterReferralCode != null)
'inviterReferralCode': inviterReferralCode, 'inviterReferralCode': inviterReferralCode,
}; };
@override
String toString() =>
'CreateAccountRequest(deviceId: $deviceId, inviterReferralCode: $inviterReferralCode)';
} }
/// ( - ) /// ( - )
@ -85,6 +94,7 @@ class CreateAccountResponse {
}); });
factory CreateAccountResponse.fromJson(Map<String, dynamic> json) { factory CreateAccountResponse.fromJson(Map<String, dynamic> json) {
debugPrint('[AccountService] 解析 CreateAccountResponse: ${json.keys.toList()}');
return CreateAccountResponse( return CreateAccountResponse(
userSerialNum: json['userSerialNum'] as int, userSerialNum: json['userSerialNum'] as int,
referralCode: json['referralCode'] as String, referralCode: json['referralCode'] as String,
@ -94,6 +104,10 @@ class CreateAccountResponse {
refreshToken: json['refreshToken'] as String, refreshToken: json['refreshToken'] as String,
); );
} }
@override
String toString() =>
'CreateAccountResponse(userSerialNum: $userSerialNum, username: $username, referralCode: $referralCode)';
} }
/// ///
@ -109,6 +123,7 @@ class WalletInfoResponse {
}); });
factory WalletInfoResponse.fromJson(Map<String, dynamic> json) { factory WalletInfoResponse.fromJson(Map<String, dynamic> json) {
debugPrint('[AccountService] 解析 WalletInfoResponse: status=${json['status']}');
return WalletInfoResponse( return WalletInfoResponse(
status: json['status'] as String, status: json['status'] as String,
walletAddresses: json['walletAddresses'] != null walletAddresses: json['walletAddresses'] != null
@ -122,6 +137,10 @@ class WalletInfoResponse {
bool get isReady => status == 'ready'; bool get isReady => status == 'ready';
bool get isGenerating => status == 'generating'; bool get isGenerating => status == 'generating';
bool get isFailed => status == 'failed'; bool get isFailed => status == 'failed';
@override
String toString() =>
'WalletInfoResponse(status: $status, hasAddresses: ${walletAddresses != null}, hasMnemonic: ${mnemonic != null})';
} }
/// ///
@ -137,12 +156,23 @@ class WalletAddresses {
}); });
factory WalletAddresses.fromJson(Map<String, dynamic> json) { factory WalletAddresses.fromJson(Map<String, dynamic> json) {
debugPrint('[AccountService] 解析 WalletAddresses: kava=${_maskAddress(json['kava'])}, dst=${_maskAddress(json['dst'])}, bsc=${_maskAddress(json['bsc'])}');
return WalletAddresses( return WalletAddresses(
kava: json['kava'] as String, kava: json['kava'] as String,
dst: json['dst'] as String, dst: json['dst'] as String,
bsc: json['bsc'] as String, bsc: json['bsc'] as String,
); );
} }
@override
String toString() =>
'WalletAddresses(kava: ${_maskAddress(kava)}, dst: ${_maskAddress(dst)}, bsc: ${_maskAddress(bsc)})';
}
///
String _maskAddress(String? address) {
if (address == null || address.length <= 10) return address ?? 'null';
return '${address.substring(0, 6)}...${address.substring(address.length - 4)}';
} }
/// ///
@ -152,29 +182,40 @@ class AccountService {
final ApiClient _apiClient; final ApiClient _apiClient;
final SecureStorage _secureStorage; final SecureStorage _secureStorage;
static const String _tag = '[AccountService]';
AccountService({ AccountService({
required ApiClient apiClient, required ApiClient apiClient,
required SecureStorage secureStorage, required SecureStorage secureStorage,
}) : _apiClient = apiClient, }) : _apiClient = apiClient,
_secureStorage = secureStorage; _secureStorage = secureStorage {
debugPrint('$_tag 初始化完成');
}
/// ///
/// ///
/// Android: 使 Android ID (64) /// Android: 使 Android ID (64)
/// iOS: 使 identifierForVendor /// iOS: 使 identifierForVendor
Future<String> getDeviceId() async { Future<String> getDeviceId() async {
debugPrint('$_tag getDeviceId() - 开始获取设备ID');
final deviceInfoPlugin = DeviceInfoPlugin(); final deviceInfoPlugin = DeviceInfoPlugin();
if (Platform.isAndroid) { if (Platform.isAndroid) {
final info = await deviceInfoPlugin.androidInfo; final info = await deviceInfoPlugin.androidInfo;
return info.id; // Android ID final deviceId = info.id;
debugPrint('$_tag getDeviceId() - Android ID: ${_maskAddress(deviceId)}');
return deviceId;
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
final info = await deviceInfoPlugin.iosInfo; final info = await deviceInfoPlugin.iosInfo;
return info.identifierForVendor ?? const Uuid().v4(); final deviceId = info.identifierForVendor ?? const Uuid().v4();
debugPrint('$_tag getDeviceId() - iOS identifierForVendor: ${_maskAddress(deviceId)}');
return deviceId;
} }
// 退 UUID // 退 UUID
return const Uuid().v4(); final uuid = const Uuid().v4();
debugPrint('$_tag getDeviceId() - 其他平台,使用 UUID: ${_maskAddress(uuid)}');
return uuid;
} }
/// ///
@ -182,11 +223,12 @@ class AccountService {
/// Android: /// Android:
/// iOS: /// iOS:
Future<DeviceHardwareInfo> getDeviceHardwareInfo() async { Future<DeviceHardwareInfo> getDeviceHardwareInfo() async {
debugPrint('$_tag getDeviceHardwareInfo() - 开始获取设备硬件信息');
final deviceInfoPlugin = DeviceInfoPlugin(); final deviceInfoPlugin = DeviceInfoPlugin();
if (Platform.isAndroid) { if (Platform.isAndroid) {
final info = await deviceInfoPlugin.androidInfo; final info = await deviceInfoPlugin.androidInfo;
return DeviceHardwareInfo( final hardwareInfo = DeviceHardwareInfo(
brand: info.brand, brand: info.brand,
manufacturer: info.manufacturer, manufacturer: info.manufacturer,
model: info.model, model: info.model,
@ -198,9 +240,11 @@ class AccountService {
sdkInt: info.version.sdkInt, sdkInt: info.version.sdkInt,
isPhysicalDevice: info.isPhysicalDevice, isPhysicalDevice: info.isPhysicalDevice,
); );
debugPrint('$_tag getDeviceHardwareInfo() - Android: $hardwareInfo');
return hardwareInfo;
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
final info = await deviceInfoPlugin.iosInfo; final info = await deviceInfoPlugin.iosInfo;
return DeviceHardwareInfo( final hardwareInfo = DeviceHardwareInfo(
brand: 'Apple', brand: 'Apple',
manufacturer: 'Apple', manufacturer: 'Apple',
model: info.model, model: info.model,
@ -209,9 +253,12 @@ class AccountService {
platform: 'ios', platform: 'ios',
isPhysicalDevice: info.isPhysicalDevice, isPhysicalDevice: info.isPhysicalDevice,
); );
debugPrint('$_tag getDeviceHardwareInfo() - iOS: $hardwareInfo');
return hardwareInfo;
} }
// //
debugPrint('$_tag getDeviceHardwareInfo() - 其他平台,返回空信息');
return DeviceHardwareInfo(); return DeviceHardwareInfo();
} }
@ -221,37 +268,57 @@ class AccountService {
Future<CreateAccountResponse> createAccount({ Future<CreateAccountResponse> createAccount({
String? inviterReferralCode, String? inviterReferralCode,
}) async { }) async {
debugPrint('$_tag createAccount() - 开始创建账号');
debugPrint('$_tag createAccount() - 邀请码: ${inviterReferralCode ?? ""}');
try { try {
// ID () // ID ()
final deviceId = await getDeviceId(); final deviceId = await getDeviceId();
debugPrint('$_tag createAccount() - 获取设备ID成功');
// () // ()
final deviceName = await getDeviceHardwareInfo(); final deviceName = await getDeviceHardwareInfo();
debugPrint('$_tag createAccount() - 获取设备硬件信息成功');
final request = CreateAccountRequest(
deviceId: deviceId,
deviceName: deviceName,
inviterReferralCode: inviterReferralCode,
);
debugPrint('$_tag createAccount() - 请求参数: $request');
// API // API
debugPrint('$_tag createAccount() - 调用 POST /user/auto-create');
final response = await _apiClient.post( final response = await _apiClient.post(
'/user/auto-create', '/user/auto-create',
data: CreateAccountRequest( data: request.toJson(),
deviceId: deviceId,
deviceName: deviceName,
inviterReferralCode: inviterReferralCode,
).toJson(),
); );
debugPrint('$_tag createAccount() - API 响应状态码: ${response.statusCode}');
if (response.data == null) { if (response.data == null) {
debugPrint('$_tag createAccount() - 错误: API 返回空响应');
throw const ApiException('创建账号失败: 空响应'); throw const ApiException('创建账号失败: 空响应');
} }
debugPrint('$_tag createAccount() - 解析响应数据');
final result = CreateAccountResponse.fromJson( final result = CreateAccountResponse.fromJson(
response.data as Map<String, dynamic>, response.data as Map<String, dynamic>,
); );
debugPrint('$_tag createAccount() - 解析成功: $result');
// //
debugPrint('$_tag createAccount() - 保存账号数据到安全存储');
await _saveAccountData(result, deviceId); await _saveAccountData(result, deviceId);
debugPrint('$_tag createAccount() - 账号数据保存成功');
debugPrint('$_tag createAccount() - 账号创建完成');
return result; return result;
} on ApiException { } on ApiException catch (e) {
debugPrint('$_tag createAccount() - API 异常: $e');
rethrow; rethrow;
} catch (e) { } catch (e, stackTrace) {
debugPrint('$_tag createAccount() - 未知异常: $e');
debugPrint('$_tag createAccount() - 堆栈: $stackTrace');
throw ApiException('创建账号失败: $e'); throw ApiException('创建账号失败: $e');
} }
} }
@ -260,26 +327,43 @@ class AccountService {
/// ///
/// userSerialNum /// userSerialNum
Future<WalletInfoResponse> getWalletInfo(int userSerialNum) async { Future<WalletInfoResponse> getWalletInfo(int userSerialNum) async {
debugPrint('$_tag getWalletInfo() - 开始获取钱包信息');
debugPrint('$_tag getWalletInfo() - userSerialNum: $userSerialNum');
try { try {
debugPrint('$_tag getWalletInfo() - 调用 GET /user/$userSerialNum/wallet');
final response = await _apiClient.get('/user/$userSerialNum/wallet'); final response = await _apiClient.get('/user/$userSerialNum/wallet');
debugPrint('$_tag getWalletInfo() - API 响应状态码: ${response.statusCode}');
if (response.data == null) { if (response.data == null) {
debugPrint('$_tag getWalletInfo() - 错误: API 返回空响应');
throw const ApiException('获取钱包信息失败: 空响应'); throw const ApiException('获取钱包信息失败: 空响应');
} }
debugPrint('$_tag getWalletInfo() - 解析响应数据');
final result = WalletInfoResponse.fromJson( final result = WalletInfoResponse.fromJson(
response.data as Map<String, dynamic>, response.data as Map<String, dynamic>,
); );
debugPrint('$_tag getWalletInfo() - 解析成功: $result');
// //
if (result.isReady) { if (result.isReady) {
debugPrint('$_tag getWalletInfo() - 钱包已就绪,保存钱包数据');
await _saveWalletData(result); await _saveWalletData(result);
debugPrint('$_tag getWalletInfo() - 钱包数据保存成功');
} else if (result.isGenerating) {
debugPrint('$_tag getWalletInfo() - 钱包生成中,需要继续轮询');
} else if (result.isFailed) {
debugPrint('$_tag getWalletInfo() - 钱包生成失败');
} }
return result; return result;
} on ApiException { } on ApiException catch (e) {
debugPrint('$_tag getWalletInfo() - API 异常: $e');
rethrow; rethrow;
} catch (e) { } catch (e, stackTrace) {
debugPrint('$_tag getWalletInfo() - 未知异常: $e');
debugPrint('$_tag getWalletInfo() - 堆栈: $stackTrace');
throw ApiException('获取钱包信息失败: $e'); throw ApiException('获取钱包信息失败: $e');
} }
} }
@ -289,150 +373,218 @@ class AccountService {
CreateAccountResponse response, CreateAccountResponse response,
String deviceId, String deviceId,
) async { ) async {
debugPrint('$_tag _saveAccountData() - 开始保存账号数据');
// //
debugPrint('$_tag _saveAccountData() - 保存 userSerialNum: ${response.userSerialNum}');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.userSerialNum, key: StorageKeys.userSerialNum,
value: response.userSerialNum.toString(), value: response.userSerialNum.toString(),
); );
debugPrint('$_tag _saveAccountData() - 保存 referralCode: ${response.referralCode}');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.referralCode, key: StorageKeys.referralCode,
value: response.referralCode, value: response.referralCode,
); );
// //
debugPrint('$_tag _saveAccountData() - 保存 username: ${response.username}');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.username, key: StorageKeys.username,
value: response.username, value: response.username,
); );
debugPrint('$_tag _saveAccountData() - 保存 avatarSvg (长度: ${response.avatarSvg.length})');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.avatarSvg, key: StorageKeys.avatarSvg,
value: response.avatarSvg, value: response.avatarSvg,
); );
// Token // Token
debugPrint('$_tag _saveAccountData() - 保存 accessToken (长度: ${response.accessToken.length})');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.accessToken, key: StorageKeys.accessToken,
value: response.accessToken, value: response.accessToken,
); );
debugPrint('$_tag _saveAccountData() - 保存 refreshToken (长度: ${response.refreshToken.length})');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.refreshToken, key: StorageKeys.refreshToken,
value: response.refreshToken, value: response.refreshToken,
); );
// ID // ID
debugPrint('$_tag _saveAccountData() - 保存 deviceId: ${_maskAddress(deviceId)}');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.deviceId, key: StorageKeys.deviceId,
value: deviceId, value: deviceId,
); );
// //
debugPrint('$_tag _saveAccountData() - 标记账号已创建');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.isAccountCreated, key: StorageKeys.isAccountCreated,
value: 'true', value: 'true',
); );
debugPrint('$_tag _saveAccountData() - 账号数据保存完成');
} }
/// ///
Future<void> _saveWalletData(WalletInfoResponse response) async { Future<void> _saveWalletData(WalletInfoResponse response) async {
debugPrint('$_tag _saveWalletData() - 开始保存钱包数据');
if (response.walletAddresses != null) { if (response.walletAddresses != null) {
debugPrint('$_tag _saveWalletData() - 保存 BSC 地址: ${_maskAddress(response.walletAddresses!.bsc)}');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.walletAddressBsc, key: StorageKeys.walletAddressBsc,
value: response.walletAddresses!.bsc, value: response.walletAddresses!.bsc,
); );
debugPrint('$_tag _saveWalletData() - 保存 KAVA 地址: ${_maskAddress(response.walletAddresses!.kava)}');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.walletAddressKava, key: StorageKeys.walletAddressKava,
value: response.walletAddresses!.kava, value: response.walletAddresses!.kava,
); );
debugPrint('$_tag _saveWalletData() - 保存 DST 地址: ${_maskAddress(response.walletAddresses!.dst)}');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.walletAddressDst, key: StorageKeys.walletAddressDst,
value: response.walletAddresses!.dst, value: response.walletAddresses!.dst,
); );
} else {
debugPrint('$_tag _saveWalletData() - 警告: walletAddresses 为空');
} }
if (response.mnemonic != null && response.mnemonic!.isNotEmpty) { if (response.mnemonic != null && response.mnemonic!.isNotEmpty) {
final wordCount = response.mnemonic!.split(' ').length;
debugPrint('$_tag _saveWalletData() - 保存助记词 ($wordCount 个单词)');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.mnemonic, key: StorageKeys.mnemonic,
value: response.mnemonic!, value: response.mnemonic!,
); );
} else {
debugPrint('$_tag _saveWalletData() - 警告: mnemonic 为空');
} }
// //
debugPrint('$_tag _saveWalletData() - 标记钱包已就绪');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.isWalletReady, key: StorageKeys.isWalletReady,
value: 'true', value: 'true',
); );
debugPrint('$_tag _saveWalletData() - 钱包数据保存完成');
} }
/// ///
Future<bool> hasAccount() async { Future<bool> hasAccount() async {
debugPrint('$_tag hasAccount() - 检查账号是否已创建');
final isCreated = final isCreated =
await _secureStorage.read(key: StorageKeys.isAccountCreated); await _secureStorage.read(key: StorageKeys.isAccountCreated);
return isCreated == 'true'; final result = isCreated == 'true';
debugPrint('$_tag hasAccount() - 结果: $result');
return result;
} }
/// ///
Future<bool> isWalletReady() async { Future<bool> isWalletReady() async {
debugPrint('$_tag isWalletReady() - 检查钱包是否已就绪');
final isReady = await _secureStorage.read(key: StorageKeys.isWalletReady); final isReady = await _secureStorage.read(key: StorageKeys.isWalletReady);
return isReady == 'true'; final result = isReady == 'true';
debugPrint('$_tag isWalletReady() - 结果: $result');
return result;
} }
/// ///
Future<int?> getUserSerialNum() async { Future<int?> getUserSerialNum() async {
debugPrint('$_tag getUserSerialNum() - 获取用户序列号');
final serialNum = final serialNum =
await _secureStorage.read(key: StorageKeys.userSerialNum); await _secureStorage.read(key: StorageKeys.userSerialNum);
return serialNum != null ? int.tryParse(serialNum) : null; final result = serialNum != null ? int.tryParse(serialNum) : null;
debugPrint('$_tag getUserSerialNum() - 结果: $result');
return result;
} }
/// ///
Future<String?> getUsername() async { Future<String?> getUsername() async {
return _secureStorage.read(key: StorageKeys.username); debugPrint('$_tag getUsername() - 获取用户名');
final result = await _secureStorage.read(key: StorageKeys.username);
debugPrint('$_tag getUsername() - 结果: $result');
return result;
} }
/// SVG /// SVG
Future<String?> getAvatarSvg() async { Future<String?> getAvatarSvg() async {
return _secureStorage.read(key: StorageKeys.avatarSvg); debugPrint('$_tag getAvatarSvg() - 获取头像 SVG');
final result = await _secureStorage.read(key: StorageKeys.avatarSvg);
debugPrint('$_tag getAvatarSvg() - 结果长度: ${result?.length ?? 0}');
return result;
} }
/// ///
Future<String?> getReferralCode() async { Future<String?> getReferralCode() async {
return _secureStorage.read(key: StorageKeys.referralCode); debugPrint('$_tag getReferralCode() - 获取推荐码');
final result = await _secureStorage.read(key: StorageKeys.referralCode);
debugPrint('$_tag getReferralCode() - 结果: $result');
return result;
} }
/// () /// ()
Future<WalletAddresses?> getWalletAddresses() async { Future<WalletAddresses?> getWalletAddresses() async {
debugPrint('$_tag getWalletAddresses() - 获取钱包地址');
final bsc = await _secureStorage.read(key: StorageKeys.walletAddressBsc); final bsc = await _secureStorage.read(key: StorageKeys.walletAddressBsc);
final kava = await _secureStorage.read(key: StorageKeys.walletAddressKava); final kava = await _secureStorage.read(key: StorageKeys.walletAddressKava);
final dst = await _secureStorage.read(key: StorageKeys.walletAddressDst); final dst = await _secureStorage.read(key: StorageKeys.walletAddressDst);
if (bsc == null || kava == null || dst == null) { if (bsc == null || kava == null || dst == null) {
debugPrint('$_tag getWalletAddresses() - 钱包地址不完整');
return null; return null;
} }
return WalletAddresses(kava: kava, dst: dst, bsc: bsc); final result = WalletAddresses(kava: kava, dst: dst, bsc: bsc);
debugPrint('$_tag getWalletAddresses() - 结果: $result');
return result;
} }
/// () /// ()
Future<String?> getMnemonic() async { Future<String?> getMnemonic() async {
return _secureStorage.read(key: StorageKeys.mnemonic); debugPrint('$_tag getMnemonic() - 获取助记词');
final result = await _secureStorage.read(key: StorageKeys.mnemonic);
if (result != null) {
final wordCount = result.split(' ').length;
debugPrint('$_tag getMnemonic() - 获取到 $wordCount 个单词');
} else {
debugPrint('$_tag getMnemonic() - 未找到助记词');
}
return result;
} }
/// ///
Future<void> markMnemonicBackedUp() async { Future<void> markMnemonicBackedUp() async {
debugPrint('$_tag markMnemonicBackedUp() - 标记助记词已备份');
await _secureStorage.write( await _secureStorage.write(
key: StorageKeys.isMnemonicBackedUp, key: StorageKeys.isMnemonicBackedUp,
value: 'true', value: 'true',
); );
debugPrint('$_tag markMnemonicBackedUp() - 完成');
} }
/// ///
Future<bool> isMnemonicBackedUp() async { Future<bool> isMnemonicBackedUp() async {
debugPrint('$_tag isMnemonicBackedUp() - 检查助记词是否已备份');
final isBackedUp = final isBackedUp =
await _secureStorage.read(key: StorageKeys.isMnemonicBackedUp); await _secureStorage.read(key: StorageKeys.isMnemonicBackedUp);
return isBackedUp == 'true'; final result = isBackedUp == 'true';
debugPrint('$_tag isMnemonicBackedUp() - 结果: $result');
return result;
} }
/// ///
Future<void> logout() async { Future<void> logout() async {
debugPrint('$_tag logout() - 开始登出,清除所有数据');
await _secureStorage.deleteAll(); await _secureStorage.deleteAll();
debugPrint('$_tag logout() - 登出完成');
} }
} }

View File

@ -54,27 +54,41 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
debugPrint('[BackupMnemonicPage] initState - userSerialNum: ${widget.userSerialNum}, referralCode: ${widget.referralCode}');
_loadWalletInfo(); _loadWalletInfo();
} }
@override @override
void dispose() { void dispose() {
debugPrint('[BackupMnemonicPage] dispose - 取消轮询定时器');
_pollTimer?.cancel(); _pollTimer?.cancel();
super.dispose(); super.dispose();
} }
/// ///
Future<void> _loadWalletInfo() async { Future<void> _loadWalletInfo() async {
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 开始加载钱包信息, userSerialNum: ${widget.userSerialNum}');
try { try {
final accountService = ref.read(accountServiceProvider); final accountService = ref.read(accountServiceProvider);
// API // API
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 调用 accountService.getWalletInfo()');
final response = await accountService.getWalletInfo(widget.userSerialNum); final response = await accountService.getWalletInfo(widget.userSerialNum);
if (!mounted) return; if (!mounted) {
debugPrint('[BackupMnemonicPage] _loadWalletInfo - Widget已卸载忽略响应');
return;
}
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 响应状态: ${response.status}, isReady: ${response.isReady}, isGenerating: ${response.isGenerating}, isFailed: ${response.isFailed}');
if (response.isReady) { if (response.isReady) {
// //
final wordCount = response.mnemonic?.split(' ').length ?? 0;
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 钱包就绪! 助记词数量: $wordCount');
debugPrint('[BackupMnemonicPage] _loadWalletInfo - KAVA: ${_maskAddress(response.walletAddresses?.kava)}');
debugPrint('[BackupMnemonicPage] _loadWalletInfo - DST: ${_maskAddress(response.walletAddresses?.dst)}');
debugPrint('[BackupMnemonicPage] _loadWalletInfo - BSC: ${_maskAddress(response.walletAddresses?.bsc)}');
setState(() { setState(() {
_walletInfo = response; _walletInfo = response;
_mnemonicWords = response.mnemonic?.split(' ') ?? []; _mnemonicWords = response.mnemonic?.split(' ') ?? [];
@ -86,6 +100,7 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
}); });
} else if (response.isGenerating) { } else if (response.isGenerating) {
// //
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 钱包生成中,开始轮询...');
setState(() { setState(() {
_isLoading = true; _isLoading = true;
_errorMessage = null; _errorMessage = null;
@ -93,13 +108,15 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
_startPolling(); _startPolling();
} else if (response.isFailed) { } else if (response.isFailed) {
// //
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 钱包生成失败');
setState(() { setState(() {
_isLoading = false; _isLoading = false;
_errorMessage = '钱包生成失败,请稍后重试'; _errorMessage = '钱包生成失败,请稍后重试';
}); });
} }
} catch (e) { } catch (e, stackTrace) {
debugPrint('加载钱包信息失败: $e'); debugPrint('[BackupMnemonicPage] _loadWalletInfo - 异常: $e');
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 堆栈: $stackTrace');
if (mounted) { if (mounted) {
setState(() { setState(() {
_isLoading = false; _isLoading = false;
@ -109,23 +126,44 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
} }
} }
/// ()
String _maskAddress(String? address) {
if (address == null || address.length < 10) return address ?? 'null';
return '${address.substring(0, 6)}...${address.substring(address.length - 4)}';
}
/// ///
int _pollCount = 0;
void _startPolling() { void _startPolling() {
_pollTimer?.cancel(); _pollTimer?.cancel();
_pollCount = 0;
debugPrint('[BackupMnemonicPage] _startPolling - 启动轮询定时器 (每2秒)');
_pollTimer = Timer.periodic(const Duration(seconds: 2), (timer) async { _pollTimer = Timer.periodic(const Duration(seconds: 2), (timer) async {
_pollCount++;
if (!mounted) { if (!mounted) {
debugPrint('[BackupMnemonicPage] _startPolling - Widget已卸载取消轮询');
timer.cancel(); timer.cancel();
return; return;
} }
debugPrint('[BackupMnemonicPage] _startPolling - 第 $_pollCount 次轮询...');
try { try {
final accountService = ref.read(accountServiceProvider); final accountService = ref.read(accountServiceProvider);
final response = await accountService.getWalletInfo(widget.userSerialNum); final response = await accountService.getWalletInfo(widget.userSerialNum);
if (!mounted) return; if (!mounted) {
debugPrint('[BackupMnemonicPage] _startPolling - Widget已卸载忽略响应');
return;
}
debugPrint('[BackupMnemonicPage] _startPolling - 轮询响应状态: ${response.status}');
if (response.isReady) { if (response.isReady) {
debugPrint('[BackupMnemonicPage] _startPolling - 钱包就绪! 停止轮询 (共轮询 $_pollCount 次)');
timer.cancel(); timer.cancel();
final wordCount = response.mnemonic?.split(' ').length ?? 0;
debugPrint('[BackupMnemonicPage] _startPolling - 助记词数量: $wordCount');
setState(() { setState(() {
_walletInfo = response; _walletInfo = response;
_mnemonicWords = response.mnemonic?.split(' ') ?? []; _mnemonicWords = response.mnemonic?.split(' ') ?? [];
@ -136,22 +174,25 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
_errorMessage = null; _errorMessage = null;
}); });
} else if (response.isFailed) { } else if (response.isFailed) {
debugPrint('[BackupMnemonicPage] _startPolling - 钱包生成失败,停止轮询');
timer.cancel(); timer.cancel();
setState(() { setState(() {
_isLoading = false; _isLoading = false;
_errorMessage = '钱包生成失败,请稍后重试'; _errorMessage = '钱包生成失败,请稍后重试';
}); });
} else {
debugPrint('[BackupMnemonicPage] _startPolling - 仍在生成中,继续轮询...');
} }
//
} catch (e) { } catch (e) {
// //
debugPrint('轮询钱包信息出错: $e'); debugPrint('[BackupMnemonicPage] _startPolling - 轮询出错 (继续重试): $e');
} }
}); });
} }
/// ///
void _copyAllMnemonic() { void _copyAllMnemonic() {
debugPrint('[BackupMnemonicPage] _copyAllMnemonic - 复制助记词到剪贴板');
final mnemonicText = _mnemonicWords.join(' '); final mnemonicText = _mnemonicWords.join(' ');
Clipboard.setData(ClipboardData(text: mnemonicText)); Clipboard.setData(ClipboardData(text: mnemonicText));
_showCopySuccess('助记词已复制到剪贴板'); _showCopySuccess('助记词已复制到剪贴板');
@ -159,6 +200,7 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
/// ///
void _copyAddress(String address, String label) { void _copyAddress(String address, String label) {
debugPrint('[BackupMnemonicPage] _copyAddress - 复制 $label: ${_maskAddress(address)}');
Clipboard.setData(ClipboardData(text: address)); Clipboard.setData(ClipboardData(text: address));
_showCopySuccess('$label 已复制'); _showCopySuccess('$label 已复制');
} }
@ -183,12 +225,17 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
/// ///
Future<void> _downloadMnemonic() async { Future<void> _downloadMnemonic() async {
if (_isDownloading || _mnemonicWords.isEmpty) return; debugPrint('[BackupMnemonicPage] _downloadMnemonic - 开始下载备份文件');
if (_isDownloading || _mnemonicWords.isEmpty) {
debugPrint('[BackupMnemonicPage] _downloadMnemonic - 跳过: isDownloading=$_isDownloading, wordsEmpty=${_mnemonicWords.isEmpty}');
return;
}
setState(() => _isDownloading = true); setState(() => _isDownloading = true);
try { try {
// //
debugPrint('[BackupMnemonicPage] _downloadMnemonic - 获取临时目录');
final directory = await getTemporaryDirectory(); final directory = await getTemporaryDirectory();
final timestamp = DateTime.now().millisecondsSinceEpoch; final timestamp = DateTime.now().millisecondsSinceEpoch;
final file = File('${directory.path}/mnemonic_backup_$timestamp.txt'); final file = File('${directory.path}/mnemonic_backup_$timestamp.txt');
@ -229,11 +276,13 @@ ${DateTime.now().toString()}
'''; ''';
// //
debugPrint('[BackupMnemonicPage] _downloadMnemonic - 写入文件: ${file.path}');
await file.writeAsString(content); await file.writeAsString(content);
if (!mounted) return; if (!mounted) return;
// //
debugPrint('[BackupMnemonicPage] _downloadMnemonic - 调用分享');
await Share.shareXFiles( await Share.shareXFiles(
[XFile(file.path)], [XFile(file.path)],
subject: 'RWA 助记词备份', subject: 'RWA 助记词备份',
@ -241,9 +290,13 @@ ${DateTime.now().toString()}
// //
if (await file.exists()) { if (await file.exists()) {
debugPrint('[BackupMnemonicPage] _downloadMnemonic - 删除临时文件');
await file.delete(); await file.delete();
} }
} catch (e) { debugPrint('[BackupMnemonicPage] _downloadMnemonic - 下载完成');
} catch (e, stackTrace) {
debugPrint('[BackupMnemonicPage] _downloadMnemonic - 下载失败: $e');
debugPrint('[BackupMnemonicPage] _downloadMnemonic - 堆栈: $stackTrace');
if (!mounted) return; if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
@ -260,7 +313,9 @@ ${DateTime.now().toString()}
/// ///
void _confirmBackup() { void _confirmBackup() {
debugPrint('[BackupMnemonicPage] _confirmBackup - 用户点击确认备份');
if (_mnemonicWords.isEmpty || _kavaAddress == null) { if (_mnemonicWords.isEmpty || _kavaAddress == null) {
debugPrint('[BackupMnemonicPage] _confirmBackup - 钱包信息不完整: words=${_mnemonicWords.length}, kavaAddress=${_kavaAddress != null}');
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('钱包信息不完整,请等待加载完成'), content: Text('钱包信息不完整,请等待加载完成'),
@ -270,6 +325,7 @@ ${DateTime.now().toString()}
return; return;
} }
debugPrint('[BackupMnemonicPage] _confirmBackup - 跳转到验证页面, userSerialNum: ${widget.userSerialNum}');
// //
context.push( context.push(
RoutePaths.verifyMnemonic, RoutePaths.verifyMnemonic,
@ -286,6 +342,7 @@ ${DateTime.now().toString()}
/// ///
void _goBack() { void _goBack() {
debugPrint('[BackupMnemonicPage] _goBack - 用户返回上一步');
context.pop(); context.pop();
} }

View File

@ -33,24 +33,30 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
debugPrint('[OnboardingPage] initState - 检查账号状态');
_checkAccountStatus(); _checkAccountStatus();
} }
/// ///
Future<void> _checkAccountStatus() async { Future<void> _checkAccountStatus() async {
debugPrint('[OnboardingPage] _checkAccountStatus - 开始检查');
try { try {
final accountService = ref.read(accountServiceProvider); final accountService = ref.read(accountServiceProvider);
// //
final hasAccount = await accountService.hasAccount(); final hasAccount = await accountService.hasAccount();
debugPrint('[OnboardingPage] _checkAccountStatus - hasAccount: $hasAccount');
if (hasAccount) { if (hasAccount) {
// //
debugPrint('[OnboardingPage] _checkAccountStatus - 读取已保存账号数据');
final userSerialNum = await accountService.getUserSerialNum(); final userSerialNum = await accountService.getUserSerialNum();
final username = await accountService.getUsername(); final username = await accountService.getUsername();
final avatarSvg = await accountService.getAvatarSvg(); final avatarSvg = await accountService.getAvatarSvg();
final referralCode = await accountService.getReferralCode(); final referralCode = await accountService.getReferralCode();
debugPrint('[OnboardingPage] _checkAccountStatus - userSerialNum: $userSerialNum, username: $username');
if (mounted) { if (mounted) {
setState(() { setState(() {
_isAccountCreated = true; _isAccountCreated = true;
@ -64,6 +70,7 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
}); });
} }
} else { } else {
debugPrint('[OnboardingPage] _checkAccountStatus - 账号未创建');
if (mounted) { if (mounted) {
setState(() { setState(() {
_isAccountCreated = false; _isAccountCreated = false;
@ -71,8 +78,9 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
}); });
} }
} }
} catch (e) { } catch (e, stackTrace) {
debugPrint('检查账号状态失败: $e'); debugPrint('[OnboardingPage] _checkAccountStatus - 异常: $e');
debugPrint('[OnboardingPage] _checkAccountStatus - 堆栈: $stackTrace');
if (mounted) { if (mounted) {
setState(() { setState(() {
_isAccountCreated = false; _isAccountCreated = false;
@ -86,7 +94,9 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
/// ///
/// API /// API
Future<void> _createAccount() async { Future<void> _createAccount() async {
debugPrint('[OnboardingPage] _createAccount - 用户点击创建账号');
if (!_isAgreed) { if (!_isAgreed) {
debugPrint('[OnboardingPage] _createAccount - 未同意协议,显示提示');
_showAgreementTip(); _showAgreementTip();
return; return;
} }
@ -100,13 +110,17 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
final accountService = ref.read(accountServiceProvider); final accountService = ref.read(accountServiceProvider);
// API // API
debugPrint('开始创建账号...'); debugPrint('[OnboardingPage] _createAccount - 调用 accountService.createAccount()');
final response = await accountService.createAccount(); final response = await accountService.createAccount();
debugPrint('账号创建成功: 序列号=${response.userSerialNum}, 用户名=${response.username}'); debugPrint('[OnboardingPage] _createAccount - 成功! 序列号=${response.userSerialNum}, 用户名=${response.username}');
if (!mounted) return; if (!mounted) {
debugPrint('[OnboardingPage] _createAccount - Widget已卸载忽略响应');
return;
}
// //
debugPrint('[OnboardingPage] _createAccount - 更新本地状态');
setState(() { setState(() {
_isAccountCreated = true; _isAccountCreated = true;
_userSerialNum = response.userSerialNum; _userSerialNum = response.userSerialNum;
@ -116,6 +130,7 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
}); });
// //
debugPrint('[OnboardingPage] _createAccount - 跳转到备份助记词页面');
context.push( context.push(
RoutePaths.backupMnemonic, RoutePaths.backupMnemonic,
extra: BackupMnemonicParams( extra: BackupMnemonicParams(
@ -123,8 +138,9 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
referralCode: response.referralCode, referralCode: response.referralCode,
), ),
); );
} catch (e) { } catch (e, stackTrace) {
debugPrint('创建账号失败: $e'); debugPrint('[OnboardingPage] _createAccount - 创建失败: $e');
debugPrint('[OnboardingPage] _createAccount - 堆栈: $stackTrace');
if (!mounted) return; if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
@ -171,7 +187,9 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
/// ///
void _goToBackupMnemonic() { void _goToBackupMnemonic() {
debugPrint('[OnboardingPage] _goToBackupMnemonic - 跳转到备份页面');
if (_userSerialNum == null) { if (_userSerialNum == null) {
debugPrint('[OnboardingPage] _goToBackupMnemonic - userSerialNum为空显示错误');
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('账号数据不完整,请重新创建'), content: Text('账号数据不完整,请重新创建'),
@ -181,6 +199,7 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
return; return;
} }
debugPrint('[OnboardingPage] _goToBackupMnemonic - userSerialNum: $_userSerialNum');
context.push( context.push(
RoutePaths.backupMnemonic, RoutePaths.backupMnemonic,
extra: BackupMnemonicParams( extra: BackupMnemonicParams(
@ -192,6 +211,7 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
/// ///
void _handleButtonTap() { void _handleButtonTap() {
debugPrint('[OnboardingPage] _handleButtonTap - isAccountCreated: $_isAccountCreated');
if (_isAccountCreated) { if (_isAccountCreated) {
// //
_goToBackupMnemonic(); _goToBackupMnemonic();