-
Notifications
You must be signed in to change notification settings - Fork 3
Add miner reward menu #477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2d0ee9d
5765020
9775189
639aa0a
5bda3a0
db03006
5453876
5379fe8
58b4f1b
f1776f8
43b3dda
754b94b
2da5314
a4ac898
6f1a510
368ef8f
3ff16e1
c2e2614
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,36 @@ | ||
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
| import 'package:quantus_sdk/quantus_sdk.dart'; | ||
| import 'package:resonance_network_wallet/providers/account_providers.dart'; | ||
| import 'package:resonance_network_wallet/providers/wallet_providers.dart'; | ||
| import 'package:resonance_network_wallet/services/mining_rewards_service.dart'; | ||
|
|
||
| final miningRewardsServiceProvider = Provider<MiningRewardsService>((ref) => MiningRewardsService()); | ||
|
|
||
| final miningRewardsProvider = FutureProvider<MiningRewardsData>((ref) async { | ||
| final service = ref.watch(miningRewardsServiceProvider); | ||
| final accounts = ref.watch(accountsProvider).value; | ||
|
|
||
| if (accounts == null || accounts.isEmpty) { | ||
| return const MiningRewardsData(resonanceBlocks: 0, schrodingerBlocks: 0, diracBlocks: 0, planckBlocks: 0); | ||
| return MiningRewardsData( | ||
| resonanceBlocks: 0, | ||
| schrodingerBlocks: 0, | ||
| diracBlocks: 0, | ||
| planckBlocks: 0, | ||
| planckRewards: BigInt.zero, | ||
| redeemedRewards: BigInt.zero, | ||
| redeemableRewards: BigInt.zero, | ||
| ); | ||
| } | ||
|
|
||
| final mnemonic = await ref.watch(settingsServiceProvider).getMnemonic(0); | ||
| if (mnemonic == null) { | ||
| throw Exception('Mnemonic not found!'); | ||
| } | ||
| final keyPair = ref.watch(hdWalletServiceProvider).deriveWormholeKeyPair(mnemonic: mnemonic); | ||
|
|
||
| final oldMiningAccountId = await TaskmasterService().getOldMiningAccountId(); | ||
| final accountsList = accounts.map((a) => a.accountId).toList(); | ||
| accountsList.add(oldMiningAccountId); | ||
| return service.getMiningRewards(accountsList); | ||
|
|
||
| return service.getMiningRewards(ref, keyPair, accountsList); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,28 @@ | ||
| import 'dart:convert'; | ||
|
|
||
| import 'package:flutter/services.dart'; | ||
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
| import 'package:quantus_sdk/quantus_sdk.dart'; | ||
| import 'package:resonance_network_wallet/providers/wallet_providers.dart'; | ||
| import 'package:resonance_network_wallet/utils/env_utils.dart'; | ||
|
|
||
| class MiningRewardsData { | ||
| final int resonanceBlocks; | ||
| final int schrodingerBlocks; | ||
| final int diracBlocks; | ||
| final int planckBlocks; | ||
| final BigInt planckRewards; | ||
| final BigInt redeemedRewards; | ||
| final BigInt redeemableRewards; | ||
|
|
||
| const MiningRewardsData({ | ||
| required this.resonanceBlocks, | ||
| required this.schrodingerBlocks, | ||
| required this.diracBlocks, | ||
| required this.planckBlocks, | ||
| required this.planckRewards, | ||
| required this.redeemedRewards, | ||
| required this.redeemableRewards, | ||
| }); | ||
|
|
||
| int get totalBlocks => resonanceBlocks + schrodingerBlocks + diracBlocks + planckBlocks; | ||
|
|
@@ -33,8 +41,9 @@ class MiningRewardsService { | |
| _cachedAccountIds = null; | ||
| } | ||
|
|
||
| Future<MiningRewardsData> getMiningRewards(List<String> currentAccountIds) async { | ||
| Future<MiningRewardsData> getMiningRewards(Ref ref, WormholeKeyPair keyPair, List<String> currentAccountIds) async { | ||
| print('[MiningRewards] Current account IDs: $currentAccountIds'); | ||
| final wormholeUtxoService = ref.read(wormholeUtxoServiceProvider); | ||
|
|
||
| final miners = <String, List<_MinerEntry>>{}; | ||
| for (final entry in _assets.entries) { | ||
|
|
@@ -49,22 +58,23 @@ class MiningRewardsService { | |
| final resonance = _countBlocks('resonance', miners['resonance']!, allAccountIds); | ||
| final schrodinger = _countBlocks('schrodinger', miners['schrodinger']!, allAccountIds); | ||
| final dirac = _countBlocks('dirac', miners['dirac']!, allAccountIds); | ||
| final planck = await _fetchPlanckBlocks(allAccountIds); | ||
| final (planckStats, redeemableRewards) = await ( | ||
| TaskmasterService().getMinerStats(), | ||
| wormholeUtxoService.getUnspentBalance(wormholeAddress: keyPair.address, secretHex: keyPair.secretHex), | ||
| ).wait; | ||
| final redeemedRewards = planckStats.totalRewards - redeemableRewards; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redeemed rewards can be negative from data inconsistencyMedium Severity The calculation Additional Locations (1)Reviewed by Cursor Bugbot for commit a4ac898. Configure here.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is nonsense |
||
|
|
||
| print('[MiningRewards] Resonance: $resonance, Schrödinger: $schrodinger, Dirac: $dirac, Planck: $planck'); | ||
| return MiningRewardsData( | ||
| resonanceBlocks: resonance, | ||
| schrodingerBlocks: schrodinger, | ||
| diracBlocks: dirac, | ||
| planckBlocks: planck, | ||
| planckBlocks: planckStats.totalMinedBlocks, | ||
| planckRewards: planckStats.totalRewards, | ||
| redeemedRewards: redeemedRewards, | ||
| redeemableRewards: redeemableRewards, | ||
| ); | ||
| } | ||
|
|
||
| Future<int> _fetchPlanckBlocks(Set<String> accountIds) async { | ||
| final minerStats = await TaskmasterService().getMinerStats(); | ||
| return minerStats.totalMinedBlocks; | ||
| } | ||
|
|
||
| List<_MinerEntry> _parseMiners(String jsonStr) { | ||
| final decoded = jsonDecode(jsonStr); | ||
| final stats = decoded['data']['minerStats'] as List; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import 'package:url_launcher/url_launcher.dart'; | ||
|
|
||
| Future<void> openUrl(String urlString, {LaunchMode mode = LaunchMode.platformDefault}) async { | ||
| final uri = Uri.parse(urlString); | ||
| try { | ||
| final launched = await launchUrl(uri, mode: mode); | ||
| if (!launched) { | ||
| print('launchUrl returned false: $urlString'); | ||
| } | ||
| } catch (e, st) { | ||
| print('launchUrl failed: $urlString error=$e\n$st'); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,11 +5,11 @@ import 'package:resonance_network_wallet/features/components/dotted_border.dart' | |
| import 'package:resonance_network_wallet/providers/currency_display_provider.dart'; | ||
| import 'package:resonance_network_wallet/providers/wallet_providers.dart'; | ||
| import 'package:resonance_network_wallet/shared/extensions/transaction_event_extension.dart'; | ||
| import 'package:resonance_network_wallet/shared/utils/open_external_url.dart'; | ||
| import 'package:resonance_network_wallet/v2/components/amount_display_with_conversion.dart'; | ||
| import 'package:resonance_network_wallet/v2/components/bottom_sheet_container.dart'; | ||
| import 'package:resonance_network_wallet/v2/theme/app_colors.dart'; | ||
| import 'package:resonance_network_wallet/v2/theme/app_text_styles.dart'; | ||
| import 'package:url_launcher/url_launcher.dart'; | ||
|
|
||
| void showTransactionDetailSheet(BuildContext context, TransactionEvent tx, String activeAccountId) { | ||
| BottomSheetContainer.show( | ||
|
|
@@ -213,6 +213,6 @@ class _ExplorerLink extends StatelessWidget { | |
| path = '$transactionType/${tx.blockHash}'; | ||
| } | ||
|
|
||
| if (path != null) launchUrl(Uri.parse('${AppConstants.explorerEndpoint}/$path')); | ||
| if (path != null) openUrl('${AppConstants.explorerEndpoint}/$path'); | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are we changing semantics here, and why? All these changes should be in separate PRs - there's some style changes, class changes, and the main implementation of miner reweards all mixed together. |
||
| } | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these style and API changes should be in a separate PR, they have nothing to do with the feature