mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-09 20:29:57 +00:00
various firo restore/rescan fixes and tweaks
This commit is contained in:
parent
e5043dfe90
commit
5b3a998091
7 changed files with 363 additions and 51 deletions
|
@ -422,8 +422,8 @@ class MainDB {
|
||||||
await isar.transactionV2s.where().walletIdEqualTo(walletId).count();
|
await isar.transactionV2s.where().walletIdEqualTo(walletId).count();
|
||||||
final addressCount = await getAddresses(walletId).count();
|
final addressCount = await getAddresses(walletId).count();
|
||||||
final utxoCount = await getUTXOs(walletId).count();
|
final utxoCount = await getUTXOs(walletId).count();
|
||||||
final lelantusCoinCount =
|
// final lelantusCoinCount =
|
||||||
await isar.lelantusCoins.where().walletIdEqualTo(walletId).count();
|
// await isar.lelantusCoins.where().walletIdEqualTo(walletId).count();
|
||||||
|
|
||||||
await isar.writeTxn(() async {
|
await isar.writeTxn(() async {
|
||||||
const paginateLimit = 50;
|
const paginateLimit = 50;
|
||||||
|
@ -471,16 +471,17 @@ class MainDB {
|
||||||
}
|
}
|
||||||
|
|
||||||
// lelantusCoins
|
// lelantusCoins
|
||||||
for (int i = 0; i < lelantusCoinCount; i += paginateLimit) {
|
await isar.lelantusCoins.where().walletIdEqualTo(walletId).deleteAll();
|
||||||
final lelantusCoinIds = await isar.lelantusCoins
|
// for (int i = 0; i < lelantusCoinCount; i += paginateLimit) {
|
||||||
.where()
|
// final lelantusCoinIds = await isar.lelantusCoins
|
||||||
.walletIdEqualTo(walletId)
|
// .where()
|
||||||
.offset(i)
|
// .walletIdEqualTo(walletId)
|
||||||
.limit(paginateLimit)
|
// .offset(i)
|
||||||
.idProperty()
|
// .limit(paginateLimit)
|
||||||
.findAll();
|
// .idProperty()
|
||||||
await isar.lelantusCoins.deleteAll(lelantusCoinIds);
|
// .findAll();
|
||||||
}
|
// await isar.lelantusCoins.deleteAll(lelantusCoinIds);
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,236 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Stack Wallet.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Cypher Stack
|
||||||
|
* All Rights Reserved.
|
||||||
|
* The code is distributed under GPLv3 license, see LICENSE file for details.
|
||||||
|
* Generated by Cypher Stack on 2023-05-26
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
|
class LelantusCoinsView extends ConsumerStatefulWidget {
|
||||||
|
const LelantusCoinsView({
|
||||||
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
static const String routeName = "/lelantusCoinsView";
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<LelantusCoinsView> createState() => _LelantusCoinsViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LelantusCoinsViewState extends ConsumerState<LelantusCoinsView> {
|
||||||
|
List<LelantusCoin> _coins = [];
|
||||||
|
|
||||||
|
Stream<List<LelantusCoin>>? lelantusCoinsCollectionWatcher;
|
||||||
|
|
||||||
|
void _onLelantusCoinsCollectionWatcherEvent(List<LelantusCoin> coins) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_coins = coins;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
lelantusCoinsCollectionWatcher = ref
|
||||||
|
.read(mainDBProvider)
|
||||||
|
.isar
|
||||||
|
.lelantusCoins
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(widget.walletId)
|
||||||
|
.sortByMintIndexDesc()
|
||||||
|
.watch(fireImmediately: true);
|
||||||
|
lelantusCoinsCollectionWatcher!
|
||||||
|
.listen((data) => _onLelantusCoinsCollectionWatcherEvent(data));
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
lelantusCoinsCollectionWatcher = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DesktopScaffold(
|
||||||
|
appBar: DesktopAppBar(
|
||||||
|
background: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||||
|
leading: Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
width: 32,
|
||||||
|
),
|
||||||
|
AppBarIconButton(
|
||||||
|
size: 32,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldDefaultBG,
|
||||||
|
shadows: const [],
|
||||||
|
icon: SvgPicture.asset(
|
||||||
|
Assets.svg.arrowLeft,
|
||||||
|
width: 18,
|
||||||
|
height: 18,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.topNavIconPrimary,
|
||||||
|
),
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Lelantus Coins",
|
||||||
|
style: STextStyles.desktopH3(context),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
useSpacers: false,
|
||||||
|
isCompactHeight: true,
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: RoundedWhiteContainer(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 9,
|
||||||
|
child: Text(
|
||||||
|
"TXID",
|
||||||
|
style: STextStyles.itemSubtitle(context),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: Text(
|
||||||
|
"Value (sats)",
|
||||||
|
style: STextStyles.itemSubtitle(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
"Index",
|
||||||
|
style: STextStyles.itemSubtitle(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
"Is JMint",
|
||||||
|
style: STextStyles.itemSubtitle(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Text(
|
||||||
|
"Used",
|
||||||
|
style: STextStyles.itemSubtitle(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: _coins.length,
|
||||||
|
separatorBuilder: (_, __) => Container(
|
||||||
|
height: 1,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.backgroundAppBar,
|
||||||
|
),
|
||||||
|
itemBuilder: (_, index) => Padding(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: RoundedWhiteContainer(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 9,
|
||||||
|
child: SelectableText(
|
||||||
|
_coins[index].txid,
|
||||||
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: SelectableText(
|
||||||
|
_coins[index].value,
|
||||||
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: SelectableText(
|
||||||
|
_coins[index].mintIndex.toString(),
|
||||||
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: SelectableText(
|
||||||
|
_coins[index].isJMint.toString(),
|
||||||
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: SelectableText(
|
||||||
|
_coins[index].isUsed.toString(),
|
||||||
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,12 +10,14 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart';
|
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart';
|
||||||
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart';
|
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart';
|
||||||
|
import 'package:stackwallet/pages_desktop_specific/lelantus_coins/lelantus_coins_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
|
||||||
import 'package:stackwallet/route_generator.dart';
|
import 'package:stackwallet/route_generator.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
@ -29,7 +31,8 @@ enum _WalletOptions {
|
||||||
addressList,
|
addressList,
|
||||||
deleteWallet,
|
deleteWallet,
|
||||||
changeRepresentative,
|
changeRepresentative,
|
||||||
showXpub;
|
showXpub,
|
||||||
|
lelantusCoins;
|
||||||
|
|
||||||
String get prettyName {
|
String get prettyName {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
|
@ -41,6 +44,8 @@ enum _WalletOptions {
|
||||||
return "Change representative";
|
return "Change representative";
|
||||||
case _WalletOptions.showXpub:
|
case _WalletOptions.showXpub:
|
||||||
return "Show xPub";
|
return "Show xPub";
|
||||||
|
case _WalletOptions.lelantusCoins:
|
||||||
|
return "Lelantus Coins";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,6 +86,9 @@ class WalletOptionsButton extends StatelessWidget {
|
||||||
onShowXpubPressed: () async {
|
onShowXpubPressed: () async {
|
||||||
Navigator.of(context).pop(_WalletOptions.showXpub);
|
Navigator.of(context).pop(_WalletOptions.showXpub);
|
||||||
},
|
},
|
||||||
|
onFiroShowLelantusCoins: () async {
|
||||||
|
Navigator.of(context).pop(_WalletOptions.lelantusCoins);
|
||||||
|
},
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -174,6 +182,15 @@ class WalletOptionsButton extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case _WalletOptions.lelantusCoins:
|
||||||
|
unawaited(
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
LelantusCoinsView.routeName,
|
||||||
|
arguments: walletId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -206,6 +223,7 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
|
||||||
required this.onAddressListPressed,
|
required this.onAddressListPressed,
|
||||||
required this.onShowXpubPressed,
|
required this.onShowXpubPressed,
|
||||||
required this.onChangeRepPressed,
|
required this.onChangeRepPressed,
|
||||||
|
required this.onFiroShowLelantusCoins,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@ -213,12 +231,16 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
|
||||||
final VoidCallback onAddressListPressed;
|
final VoidCallback onAddressListPressed;
|
||||||
final VoidCallback onShowXpubPressed;
|
final VoidCallback onShowXpubPressed;
|
||||||
final VoidCallback onChangeRepPressed;
|
final VoidCallback onChangeRepPressed;
|
||||||
|
final VoidCallback onFiroShowLelantusCoins;
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final coin = ref.watch(pWalletCoin(walletId));
|
final coin = ref.watch(pWalletCoin(walletId));
|
||||||
|
|
||||||
|
final firoDebug =
|
||||||
|
kDebugMode && (coin == Coin.firo || coin == Coin.firoTestNet);
|
||||||
|
|
||||||
// TODO: [prio=low]
|
// TODO: [prio=low]
|
||||||
// final bool xpubEnabled = manager.hasXPub;
|
// final bool xpubEnabled = manager.hasXPub;
|
||||||
final bool xpubEnabled = false;
|
final bool xpubEnabled = false;
|
||||||
|
@ -315,6 +337,43 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (firoDebug)
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
if (firoDebug)
|
||||||
|
TransparentButton(
|
||||||
|
onPressed: onFiroShowLelantusCoins,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.svg.eye,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldActiveSearchIconLeft,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 14),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
_WalletOptions.lelantusCoins.prettyName,
|
||||||
|
style: STextStyles.desktopTextExtraExtraSmall(
|
||||||
|
context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textDark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
if (xpubEnabled)
|
if (xpubEnabled)
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8,
|
height: 8,
|
||||||
|
|
|
@ -146,6 +146,7 @@ import 'package:stackwallet/pages_desktop_specific/desktop_buy/desktop_buy_view.
|
||||||
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_all_trades_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_all_trades_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart';
|
||||||
|
import 'package:stackwallet/pages_desktop_specific/lelantus_coins/lelantus_coins_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/my_stack_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/my_stack_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart';
|
||||||
|
@ -1843,6 +1844,20 @@ class RouteGenerator {
|
||||||
}
|
}
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
|
case LelantusCoinsView.routeName:
|
||||||
|
if (args is String) {
|
||||||
|
return getRoute(
|
||||||
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
|
builder: (_) => LelantusCoinsView(
|
||||||
|
walletId: args,
|
||||||
|
),
|
||||||
|
settings: RouteSettings(
|
||||||
|
name: settings.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case DesktopCoinControlView.routeName:
|
case DesktopCoinControlView.routeName:
|
||||||
if (args is String) {
|
if (args is String) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
|
|
|
@ -31,7 +31,7 @@ abstract final class LelantusFfiWrapper {
|
||||||
required final Bip39HDCurrency cryptoCurrency,
|
required final Bip39HDCurrency cryptoCurrency,
|
||||||
required final int latestSetId,
|
required final int latestSetId,
|
||||||
required final Map<dynamic, dynamic> setDataMap,
|
required final Map<dynamic, dynamic> setDataMap,
|
||||||
required final List<String> usedSerialNumbers,
|
required final Set<String> usedSerialNumbers,
|
||||||
required final String walletId,
|
required final String walletId,
|
||||||
required final String partialDerivationPath,
|
required final String partialDerivationPath,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -65,10 +65,11 @@ abstract final class LelantusFfiWrapper {
|
||||||
Bip39HDCurrency cryptoCurrency,
|
Bip39HDCurrency cryptoCurrency,
|
||||||
int latestSetId,
|
int latestSetId,
|
||||||
Map<dynamic, dynamic> setDataMap,
|
Map<dynamic, dynamic> setDataMap,
|
||||||
List<String> usedSerialNumbers,
|
Set<String> usedSerialNumbers,
|
||||||
String walletId,
|
String walletId,
|
||||||
String partialDerivationPath,
|
String partialDerivationPath,
|
||||||
}) args) async {
|
}) args,
|
||||||
|
) async {
|
||||||
List<int> jindexes = [];
|
List<int> jindexes = [];
|
||||||
List<isar_models.LelantusCoin> lelantusCoins = [];
|
List<isar_models.LelantusCoin> lelantusCoins = [];
|
||||||
|
|
||||||
|
@ -76,23 +77,20 @@ abstract final class LelantusFfiWrapper {
|
||||||
int lastFoundIndex = 0;
|
int lastFoundIndex = 0;
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
|
|
||||||
Set<String> usedSerialNumbersSet = args.usedSerialNumbers.toSet();
|
|
||||||
|
|
||||||
final root = BIP32.fromPrivateKey(
|
final root = BIP32.fromPrivateKey(
|
||||||
args.hexRootPrivateKey.toUint8ListFromHex,
|
args.hexRootPrivateKey.toUint8ListFromHex,
|
||||||
args.chaincode,
|
args.chaincode,
|
||||||
);
|
);
|
||||||
|
|
||||||
while (currentIndex < lastFoundIndex + 50) {
|
while (currentIndex < lastFoundIndex + 50) {
|
||||||
final _derivePath =
|
final mintKeyPair = root.derivePath(
|
||||||
"${args.partialDerivationPath}$MINT_INDEX/$currentIndex";
|
"${args.partialDerivationPath}$MINT_INDEX/$currentIndex",
|
||||||
|
);
|
||||||
final mintKeyPair = root.derivePath(_derivePath);
|
|
||||||
|
|
||||||
final String mintTag = lelantus.CreateTag(
|
final String mintTag = lelantus.CreateTag(
|
||||||
mintKeyPair.privateKey!.toHex,
|
mintKeyPair.privateKey!.toHex,
|
||||||
currentIndex,
|
currentIndex,
|
||||||
Format.uint8listToString(mintKeyPair.identifier),
|
mintKeyPair.identifier.toHex,
|
||||||
isTestnet: args.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
isTestnet: args.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -121,7 +119,7 @@ abstract final class LelantusFfiWrapper {
|
||||||
isTestnet:
|
isTestnet:
|
||||||
args.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
args.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
||||||
);
|
);
|
||||||
final bool isUsed = usedSerialNumbersSet.contains(serialNumber);
|
final bool isUsed = args.usedSerialNumbers.contains(serialNumber);
|
||||||
|
|
||||||
lelantusCoins.removeWhere((e) =>
|
lelantusCoins.removeWhere((e) =>
|
||||||
e.txid == txId &&
|
e.txid == txId &&
|
||||||
|
@ -141,14 +139,13 @@ abstract final class LelantusFfiWrapper {
|
||||||
publicCoin, // not really needed but saved just in case
|
publicCoin, // not really needed but saved just in case
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
debugPrint("amount $amount used $isUsed");
|
debugPrint("serial=$serialNumber amount=$amount used=$isUsed");
|
||||||
} else if (thirdValue is String) {
|
} else if (thirdValue is String) {
|
||||||
final int keyPath = lelantus.GetAesKeyPath(publicCoin);
|
final int keyPath = lelantus.GetAesKeyPath(publicCoin);
|
||||||
|
|
||||||
final derivePath =
|
final aesKeyPair = root.derivePath(
|
||||||
"${args.partialDerivationPath}$JMINT_INDEX/$keyPath";
|
"${args.partialDerivationPath}$JMINT_INDEX/$keyPath",
|
||||||
|
);
|
||||||
final aesKeyPair = root.derivePath(derivePath);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final String aesPrivateKey = aesKeyPair.privateKey!.toHex;
|
final String aesPrivateKey = aesKeyPair.privateKey!.toHex;
|
||||||
|
@ -165,7 +162,8 @@ abstract final class LelantusFfiWrapper {
|
||||||
isTestnet:
|
isTestnet:
|
||||||
args.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
args.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
||||||
);
|
);
|
||||||
bool isUsed = usedSerialNumbersSet.contains(serialNumber);
|
final bool isUsed = args.usedSerialNumbers.contains(serialNumber);
|
||||||
|
|
||||||
lelantusCoins.removeWhere((e) =>
|
lelantusCoins.removeWhere((e) =>
|
||||||
e.txid == txId &&
|
e.txid == txId &&
|
||||||
e.mintIndex == currentIndex &&
|
e.mintIndex == currentIndex &&
|
||||||
|
@ -188,8 +186,7 @@ abstract final class LelantusFfiWrapper {
|
||||||
|
|
||||||
spendTxIds.add(txId);
|
spendTxIds.add(txId);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
debugPrint(
|
debugPrint("AES keypair derivation issue for key path: $keyPath");
|
||||||
"AES keypair derivation issue for derive path: $derivePath");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debugPrint("Unexpected coin found: $foundCoin");
|
debugPrint("Unexpected coin found: $foundCoin");
|
||||||
|
@ -312,9 +309,9 @@ abstract final class LelantusFfiWrapper {
|
||||||
isTestNet: arg.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
isTestNet: arg.cryptoCurrency.network == CryptoCurrencyNetwork.test,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
var changeToMint = estimateJoinSplitFee.changeToMint;
|
final changeToMint = estimateJoinSplitFee.changeToMint;
|
||||||
var fee = estimateJoinSplitFee.fee;
|
final fee = estimateJoinSplitFee.fee;
|
||||||
var spendCoinIndexes = estimateJoinSplitFee.spendCoinIndexes;
|
final spendCoinIndexes = estimateJoinSplitFee.spendCoinIndexes;
|
||||||
debugPrint("$changeToMint $fee $spendCoinIndexes");
|
debugPrint("$changeToMint $fee $spendCoinIndexes");
|
||||||
if (spendCoinIndexes.isEmpty) {
|
if (spendCoinIndexes.isEmpty) {
|
||||||
throw Exception("Error, Not enough funds.");
|
throw Exception("Error, Not enough funds.");
|
||||||
|
|
|
@ -796,14 +796,17 @@ class FiroWallet extends Bip39HDWallet
|
||||||
setDataMapFuture,
|
setDataMapFuture,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
final usedSerialsSet = (futureResults[0] as List<String>).toSet();
|
||||||
|
final setDataMap = futureResults[1] as Map<dynamic, dynamic>;
|
||||||
|
|
||||||
await recoverLelantusWallet(
|
await recoverLelantusWallet(
|
||||||
latestSetId: latestSetId,
|
latestSetId: latestSetId,
|
||||||
setDataMap: futureResults[1] as Map<dynamic, dynamic>,
|
usedSerialNumbers: usedSerialsSet,
|
||||||
usedSerialNumbers: futureResults[0] as List<String>,
|
setDataMap: setDataMap,
|
||||||
);
|
);
|
||||||
|
|
||||||
await updateBalance();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await refresh();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
"Exception rethrown from electrumx_mixin recover(): $e\n$s",
|
"Exception rethrown from electrumx_mixin recover(): $e\n$s",
|
||||||
|
|
|
@ -559,7 +559,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
|
||||||
Future<void> recoverLelantusWallet({
|
Future<void> recoverLelantusWallet({
|
||||||
required int latestSetId,
|
required int latestSetId,
|
||||||
required Map<dynamic, dynamic> setDataMap,
|
required Map<dynamic, dynamic> setDataMap,
|
||||||
required List<String> usedSerialNumbers,
|
required Set<String> usedSerialNumbers,
|
||||||
}) async {
|
}) async {
|
||||||
final root = await getRootHDNode();
|
final root = await getRootHDNode();
|
||||||
|
|
||||||
|
@ -568,6 +568,8 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
|
||||||
chain: 0,
|
chain: 0,
|
||||||
index: 0,
|
index: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// get "m/$purpose'/$coinType'/$account'/" from "m/$purpose'/$coinType'/$account'/0/0"
|
||||||
final partialDerivationPath = derivePath.substring(
|
final partialDerivationPath = derivePath.substring(
|
||||||
0,
|
0,
|
||||||
derivePath.length - 3,
|
derivePath.length - 3,
|
||||||
|
@ -593,12 +595,11 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
|
||||||
.or()
|
.or()
|
||||||
.isLelantusEqualTo(false)
|
.isLelantusEqualTo(false)
|
||||||
.findAll();
|
.findAll();
|
||||||
final lelantusCoins = result.lelantusCoins;
|
|
||||||
|
|
||||||
// Edit the receive transactions with the mint fees.
|
// Edit the receive transactions with the mint fees.
|
||||||
List<Transaction> editedTransactions = [];
|
List<Transaction> editedTransactions = [];
|
||||||
|
|
||||||
for (final coin in lelantusCoins) {
|
for (final coin in result.lelantusCoins) {
|
||||||
String txid = coin.txid;
|
String txid = coin.txid;
|
||||||
Transaction? tx;
|
Transaction? tx;
|
||||||
try {
|
try {
|
||||||
|
@ -675,7 +676,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionMap.removeWhere((key, value) =>
|
transactionMap.removeWhere((key, value) =>
|
||||||
lelantusCoins.any((element) => element.txid == key) ||
|
result.lelantusCoins.any((element) => element.txid == key) ||
|
||||||
((value.height == -1 || value.height == null) &&
|
((value.height == -1 || value.height == null) &&
|
||||||
!value.isConfirmed(currentHeight, cryptoCurrency.minConfirms)));
|
!value.isConfirmed(currentHeight, cryptoCurrency.minConfirms)));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue