Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions miner-app/lib/features/miner/miner_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:quantus_miner/src/config/miner_config.dart';
import 'package:quantus_miner/src/services/miner_wallet_service.dart';
import 'package:quantus_miner/src/services/mining_orchestrator.dart';
import 'package:quantus_miner/src/services/mining_stats_service.dart';
Expand Down Expand Up @@ -38,7 +37,6 @@ class _MinerControlsState extends State<MinerControls> {
int _cpuWorkers = 8;
int _gpuDevices = 0;
int _detectedGpuCount = 0;
String _chainId = MinerConfig.defaultChainId;
final _settingsService = MinerSettingsService();

@override
Expand All @@ -51,13 +49,11 @@ class _MinerControlsState extends State<MinerControls> {
Future<void> _loadSettings() async {
final savedCpuWorkers = await _settingsService.getCpuWorkers();
final savedGpuDevices = await _settingsService.getGpuDevices();
final savedChainId = await _settingsService.getChainId();

if (mounted) {
setState(() {
_cpuWorkers = savedCpuWorkers ?? (Platform.numberOfProcessors > 0 ? Platform.numberOfProcessors : 8);
_gpuDevices = savedGpuDevices ?? 0;
_chainId = savedChainId;
});
}
}
Expand Down Expand Up @@ -93,13 +89,6 @@ class _MinerControlsState extends State<MinerControls> {
Future<void> _startNode() async {
_log.i('Starting node');

// Reload chain ID in case it was changed in settings
final chainId = await _settingsService.getChainId();
if (mounted) {
setState(() => _chainId = chainId);
}

// Get rewards preimage directly from the wallet (not from file)
final walletService = MinerWalletService();
final wormholeKeyPair = await walletService.getWormholeKeyPair();
if (wormholeKeyPair == null) {
Expand All @@ -110,7 +99,6 @@ class _MinerControlsState extends State<MinerControls> {
return;
}

// Check for required files
final quantusHome = await BinaryManager.getQuantusHomeDirectoryPath();
final identityFile = File('$quantusHome/node_key.p2p');
final nodeBinPath = await BinaryManager.getNodeBinaryFilePath();
Expand All @@ -126,7 +114,6 @@ class _MinerControlsState extends State<MinerControls> {
return;
}

// Create new orchestrator
final orchestrator = MiningOrchestrator();
widget.onOrchestratorChanged(orchestrator);

Expand All @@ -138,7 +125,6 @@ class _MinerControlsState extends State<MinerControls> {
identityFile: identityFile,
rewardsInnerHash: wormholeKeyPair.rewardsPreimageHex,
wormholeAddress: wormholeKeyPair.address,
chainId: _chainId,
cpuWorkers: _cpuWorkers,
gpuDevices: _gpuDevices,
detectedGpuCount: _detectedGpuCount,
Expand Down
158 changes: 0 additions & 158 deletions miner-app/lib/features/settings/settings_screen.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:quantus_miner/features/settings/settings_app_bar.dart';
import 'package:quantus_miner/main.dart';
import 'package:quantus_miner/src/config/miner_config.dart';
import 'package:quantus_miner/src/services/binary_manager.dart';
import 'package:quantus_miner/src/services/miner_settings_service.dart';
import 'package:quantus_miner/src/services/miner_wallet_service.dart';
import 'package:quantus_sdk/quantus_sdk.dart';

Expand All @@ -20,10 +17,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
BinaryVersion? _nodeUpdateInfo;
bool _isLoading = true;

// Chain selection
final MinerSettingsService _settingsService = MinerSettingsService();
final MinerWalletService _walletService = MinerWalletService();
String _selectedChainId = MinerConfig.defaultChainId;

@override
void initState() {
Expand All @@ -39,77 +33,15 @@ class _SettingsScreenState extends State<SettingsScreen> {
BinaryManager.getMinerBinaryVersion(),
]);

final chainId = await _settingsService.getChainId();

if (mounted) {
setState(() {
_minerUpdateInfo = minerUpdateInfo;
_nodeUpdateInfo = nodeUpdateInfo;
_selectedChainId = chainId;
_isLoading = false;
});
}
}

Future<void> _onChainChanged(String? newChainId) async {
if (newChainId == null || newChainId == _selectedChainId) return;

// Check if mining is currently running
final orchestrator = GlobalMinerManager.getOrchestrator();
final isMining = orchestrator?.isRunning ?? false;

if (isMining) {
// Show warning dialog
final shouldChange = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
backgroundColor: const Color(0xFF1C1C1C),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
title: const Text('Stop Mining?', style: TextStyle(color: Colors.white)),
content: const Text(
'Changing the chain requires stopping mining first. '
'Do you want to stop mining and switch chains?',
style: TextStyle(color: Colors.white70),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text('Cancel', style: TextStyle(color: Colors.white.useOpacity(0.7))),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
style: TextButton.styleFrom(foregroundColor: const Color(0xFF00E676)),
child: const Text('Stop & Switch'),
),
],
),
);

if (shouldChange != true) return;

// Stop mining
await orchestrator?.stop();
}

// Save the new chain ID
await _settingsService.saveChainId(newChainId);

if (mounted) {
setState(() {
_selectedChainId = newChainId;
});

// Show confirmation
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Switched to ${MinerConfig.getChainById(newChainId).displayName}'),
backgroundColor: const Color(0xFF00E676),
behavior: SnackBarBehavior.floating,
),
);
}
}

@override
Widget build(BuildContext context) {
// Define a theme-consistent accent color (e.g., a tech green or teal)
Expand Down Expand Up @@ -177,23 +109,6 @@ class _SettingsScreenState extends State<SettingsScreen> {

const SizedBox(height: 32),

// Network Section Header
Text(
'NETWORK',
style: TextStyle(
color: Colors.white.useOpacity(0.5),
fontSize: 12,
letterSpacing: 1.5,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 16),

// Chain Selector
_buildChainSelector(accentColor),

const SizedBox(height: 32),

// Wallet Section Header
Text(
'WALLET',
Expand Down Expand Up @@ -291,79 +206,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
);
}

Widget _buildChainSelector(Color accentColor) {
final selectedChain = MinerConfig.getChainById(_selectedChainId);

return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF1C1C1C),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.white.useOpacity(0.05), width: 1),
boxShadow: [BoxShadow(color: Colors.black.useOpacity(0.2), blurRadius: 10, offset: const Offset(0, 4))],
),
child: Row(
children: [
// Icon Container
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(color: accentColor.useOpacity(0.1), borderRadius: BorderRadius.circular(12)),
child: Icon(Icons.link_rounded, color: accentColor, size: 20),
),
const SizedBox(width: 16),

// Title and description
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Chain',
style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),
),
const SizedBox(height: 2),
Text(selectedChain.description, style: TextStyle(color: Colors.white.useOpacity(0.5), fontSize: 12)),
],
),
),

// Dropdown
if (_isLoading)
SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white.useOpacity(0.3)),
)
else
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.white.useOpacity(0.1)),
),
child: DropdownButton<String>(
value: _selectedChainId,
dropdownColor: const Color(0xFF1C1C1C),
underline: const SizedBox(),
icon: Icon(Icons.arrow_drop_down, color: Colors.white.useOpacity(0.7)),
style: TextStyle(
color: Colors.white.useOpacity(0.9),
fontFamily: 'Courier',
fontWeight: FontWeight.bold,
fontSize: 13,
),
items: MinerConfig.availableChains.map((chain) {
return DropdownMenuItem<String>(value: chain.id, child: Text(chain.displayName));
}).toList(),
onChanged: _onChainChanged,
),
),
],
),
);
}

Widget _buildActionTile({
required String title,
required String subtitle,
Expand Down
5 changes: 0 additions & 5 deletions miner-app/lib/features/withdrawal/claim_rewards_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:io';

import 'package:flutter/material.dart';
import 'package:quantus_miner/src/services/binary_manager.dart';
import 'package:quantus_miner/src/services/miner_settings_service.dart';
import 'package:quantus_miner/src/services/miner_wallet_service.dart';
import 'package:quantus_miner/src/services/wormhole_claim_service.dart';
import 'package:quantus_miner/src/utils/app_logger.dart';
Expand Down Expand Up @@ -32,7 +31,6 @@ class _ClaimRewardsDialogState extends State<_ClaimRewardsDialog> {
final _addressController = TextEditingController();
final _claimService = WormholeClaimService();
final _walletService = MinerWalletService();
final _settingsService = MinerSettingsService();

_Screen _screen = _Screen.input;
String? _addressError;
Expand Down Expand Up @@ -101,18 +99,15 @@ class _ClaimRewardsDialogState extends State<_ClaimRewardsDialog> {
throw StateError('Wormhole key pair not available');
}

final chainConfig = await _settingsService.getChainConfig();
final binsDir = '${await BinaryManager.getQuantusHomeDirectoryPath()}/generated-bins';
await Directory(binsDir).create(recursive: true);

final rpcUrl = chainConfig.rpcUrl;
_log.i('Starting claim for ${keyPair.address} to ${_addressController.text.trim()}');

final result = await _claimService.claimRewards(
wormholeAddress: keyPair.address,
secretHex: keyPair.secretHex,
destinationAddress: _addressController.text.trim(),
rpcUrl: rpcUrl,
circuitBinsDir: binsDir,
onProgress: (progress) {
if (!mounted) return;
Expand Down
65 changes: 3 additions & 62 deletions miner-app/lib/src/config/miner_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,41 +101,9 @@ class MinerConfig {
// Chain Configuration
// ============================================================

/// Available chain IDs
static const List<ChainConfig> availableChains = [
ChainConfig(
id: 'dev',
displayName: 'Development',
description: 'Local development chain',
rpcUrl: 'http://127.0.0.1:9933',
subsquidUrl: 'http://127.0.0.1:4350/graphql',
isDefault: false,
),
ChainConfig(
id: 'dirac',
displayName: 'Dirac',
description: 'Dirac testnet',
rpcUrl: 'https://a1-dirac.quantus.cat',
subsquidUrl: 'https://subsquid.quantus.com/blue/graphql',
isDefault: false,
),
ChainConfig(
id: 'planck',
displayName: 'Planck Testnet',
description: 'Planck testnet',
rpcUrl: 'https://a1-planck.quantus.cat',
subsquidUrl: 'http://127.0.0.1:4000/graphql', // Local Subsquid for testing
isDefault: true,
),
];

/// Get chain config by ID, returns dev chain if not found
static ChainConfig getChainById(String id) {
return availableChains.firstWhere((chain) => chain.id == id, orElse: () => availableChains.first);
}

/// The default chain ID
static String get defaultChainId => availableChains.firstWhere((c) => c.isDefault).id;
/// Chain spec passed to the local node binary via `--chain`.
/// Wallet/UTXO/claim endpoints come from `AppConstants` in the SDK.
static const String chainId = 'planck';

// ============================================================
// Process Names (for cleanup)
Expand Down Expand Up @@ -170,30 +138,3 @@ class MinerConfig {
/// Number of ports to try when finding an alternative
static const int portSearchRange = 10;
}

/// Configuration for a blockchain network.
///
/// Named ChainConfig to avoid conflict with ChainInfo in chain_rpc_client.dart
class ChainConfig {
final String id;
final String displayName;
final String description;
final String rpcUrl;
final String? subsquidUrl;
final bool isDefault;

const ChainConfig({
required this.id,
required this.displayName,
required this.description,
required this.rpcUrl,
this.subsquidUrl,
this.isDefault = false,
});

/// Whether this chain uses the local node RPC
bool get isLocalNode => rpcUrl.contains('127.0.0.1') || rpcUrl.contains('localhost');

@override
String toString() => 'ChainConfig(id: $id, displayName: $displayName, rpcUrl: $rpcUrl)';
}
Loading