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:
parent
6150617c14
commit
37aab77e7a
|
|
@ -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() - 登出完成');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue