blockchain-flutter/lib/core/network/api_client.dart
StillHammer 5a8300c5ea Initial setup: Flutter blockchain explorer app
- 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
2026-02-01 10:12:34 +08:00

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;
}
}
}