- Clean architecture with feature-based organization - Riverpod state management, Dio HTTP, GoRouter navigation - Dashboard, blocks, wallet, transactions, mining screens - Dark crypto theme with JetBrains Mono font
106 lines
2.8 KiB
Dart
106 lines
2.8 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
class ApiClient {
|
|
static const String _defaultBaseUrl = 'http://localhost:3000';
|
|
// Use 10.0.2.2 for Android emulator to reach host localhost
|
|
static const String _androidEmulatorUrl = 'http://10.0.2.2:3000';
|
|
|
|
late final Dio dio;
|
|
|
|
ApiClient({String? baseUrl}) {
|
|
final url = baseUrl ?? _resolveBaseUrl();
|
|
|
|
dio = Dio(BaseOptions(
|
|
baseUrl: url,
|
|
connectTimeout: const Duration(seconds: 5),
|
|
receiveTimeout: const Duration(seconds: 10),
|
|
headers: {'Content-Type': 'application/json'},
|
|
));
|
|
|
|
dio.interceptors.add(LogInterceptor(
|
|
requestBody: true,
|
|
responseBody: true,
|
|
logPrint: (log) => debugPrint(log.toString()),
|
|
));
|
|
}
|
|
|
|
static String _resolveBaseUrl() {
|
|
// Android emulator uses 10.0.2.2 to reach host machine
|
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
|
return _androidEmulatorUrl;
|
|
}
|
|
return _defaultBaseUrl;
|
|
}
|
|
|
|
// Chain
|
|
Future<Map<String, dynamic>> getChainInfo() async {
|
|
final response = await dio.get('/api/chain/info');
|
|
return response.data;
|
|
}
|
|
|
|
Future<Map<String, dynamic>> validateChain() async {
|
|
final response = await dio.post('/api/chain/validate');
|
|
return response.data;
|
|
}
|
|
|
|
// Blocks
|
|
Future<Map<String, dynamic>> getBlocks({int offset = 0, int limit = 10}) async {
|
|
final response = await dio.get('/api/blocks', queryParameters: {
|
|
'offset': offset,
|
|
'limit': limit,
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
Future<Map<String, dynamic>> getBlock(String hash) async {
|
|
final response = await dio.get('/api/blocks/$hash');
|
|
return response.data;
|
|
}
|
|
|
|
// Wallets
|
|
Future<Map<String, dynamic>> createWallet() async {
|
|
final response = await dio.post('/api/wallets');
|
|
return response.data;
|
|
}
|
|
|
|
Future<Map<String, dynamic>> getBalance(String address) async {
|
|
final response = await dio.get('/api/wallets/$address/balance');
|
|
return response.data;
|
|
}
|
|
|
|
// Transactions
|
|
Future<Map<String, dynamic>> submitTransaction(Map<String, dynamic> tx) async {
|
|
final response = await dio.post('/api/transactions', data: tx);
|
|
return response.data;
|
|
}
|
|
|
|
Future<List<dynamic>> getPendingTransactions() async {
|
|
final response = await dio.get('/api/transactions/pending');
|
|
return response.data;
|
|
}
|
|
|
|
// Mining
|
|
Future<Map<String, dynamic>> mine(String minerAddress) async {
|
|
final response = await dio.post('/api/mine', data: {
|
|
'miner_address': minerAddress,
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
Future<Map<String, dynamic>> getMiningStatus() async {
|
|
final response = await dio.get('/api/mining/status');
|
|
return response.data;
|
|
}
|
|
|
|
// Health
|
|
Future<bool> healthCheck() async {
|
|
try {
|
|
await dio.get('/api/health');
|
|
return true;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|