mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-09 20:29:57 +00:00
Merge pull request #917 from cypherstack/julian_working_branch
XMR/WOW view keys and bug fixes
This commit is contained in:
commit
dfd08d972a
17 changed files with 427 additions and 76 deletions
21
lib/models/keys/cw_key_data.dart
Normal file
21
lib/models/keys/cw_key_data.dart
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import 'key_data_interface.dart';
|
||||||
|
|
||||||
|
class CWKeyData with KeyDataInterface {
|
||||||
|
CWKeyData({
|
||||||
|
required this.walletId,
|
||||||
|
required String? privateSpendKey,
|
||||||
|
required String? privateViewKey,
|
||||||
|
required String? publicSpendKey,
|
||||||
|
required String? publicViewKey,
|
||||||
|
}) : keys = List.unmodifiable([
|
||||||
|
(label: "Public View Key", key: publicViewKey),
|
||||||
|
(label: "Private View Key", key: privateViewKey),
|
||||||
|
(label: "Public Spend Key", key: publicSpendKey),
|
||||||
|
(label: "Private Spend Key", key: privateSpendKey),
|
||||||
|
]);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
final List<({String label, String key})> keys;
|
||||||
|
}
|
3
lib/models/keys/key_data_interface.dart
Normal file
3
lib/models/keys/key_data_interface.dart
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
mixin KeyDataInterface {
|
||||||
|
String get walletId;
|
||||||
|
}
|
17
lib/models/keys/xpriv_data.dart
Normal file
17
lib/models/keys/xpriv_data.dart
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import '../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||||
|
import 'key_data_interface.dart';
|
||||||
|
|
||||||
|
class XPrivData with KeyDataInterface {
|
||||||
|
XPrivData({
|
||||||
|
required this.walletId,
|
||||||
|
required this.fingerprint,
|
||||||
|
required List<XPriv> xprivs,
|
||||||
|
}) : xprivs = List.unmodifiable(xprivs);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
final String fingerprint;
|
||||||
|
|
||||||
|
final List<XPriv> xprivs;
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
|
import '../../../../models/keys/cw_key_data.dart';
|
||||||
|
import '../../../../notifications/show_flush_bar.dart';
|
||||||
|
import '../../../../themes/stack_colors.dart';
|
||||||
|
import '../../../../utilities/assets.dart';
|
||||||
|
import '../../../../utilities/clipboard_interface.dart';
|
||||||
|
import '../../../../utilities/constants.dart';
|
||||||
|
import '../../../../utilities/text_styles.dart';
|
||||||
|
import '../../../../utilities/util.dart';
|
||||||
|
import '../../../../widgets/desktop/primary_button.dart';
|
||||||
|
import '../../../../widgets/detail_item.dart';
|
||||||
|
import '../../../../widgets/qr.dart';
|
||||||
|
import '../../../../widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
|
class CNWalletKeys extends StatefulWidget {
|
||||||
|
const CNWalletKeys({
|
||||||
|
super.key,
|
||||||
|
required this.cwKeyData,
|
||||||
|
required this.walletId,
|
||||||
|
this.clipboardInterface = const ClipboardWrapper(),
|
||||||
|
});
|
||||||
|
|
||||||
|
final CWKeyData cwKeyData;
|
||||||
|
final String walletId;
|
||||||
|
final ClipboardInterface clipboardInterface;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CNWalletKeys> createState() => _CNWalletKeysState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CNWalletKeysState extends State<CNWalletKeys> {
|
||||||
|
late String _currentDropDownValue;
|
||||||
|
|
||||||
|
String _current(String key) =>
|
||||||
|
widget.cwKeyData.keys.firstWhere((e) => e.label == key).key;
|
||||||
|
|
||||||
|
Future<void> _copy() async {
|
||||||
|
await widget.clipboardInterface.setData(
|
||||||
|
ClipboardData(text: _current(_currentDropDownValue)),
|
||||||
|
);
|
||||||
|
if (mounted) {
|
||||||
|
unawaited(
|
||||||
|
showFloatingFlushBar(
|
||||||
|
type: FlushBarType.info,
|
||||||
|
message: "Copied to clipboard",
|
||||||
|
iconAsset: Assets.svg.copy,
|
||||||
|
context: context,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_currentDropDownValue = widget.cwKeyData.keys.first.label;
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: Util.isDesktop
|
||||||
|
? const EdgeInsets.symmetric(horizontal: 20)
|
||||||
|
: EdgeInsets.zero,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: Util.isDesktop ? MainAxisSize.min : MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: Util.isDesktop ? 12 : 16,
|
||||||
|
),
|
||||||
|
DetailItemBase(
|
||||||
|
horizontal: true,
|
||||||
|
borderColor: Util.isDesktop
|
||||||
|
? Theme.of(context).extension<StackColors>()!.textFieldDefaultBG
|
||||||
|
: null,
|
||||||
|
title: Text(
|
||||||
|
"Selected key",
|
||||||
|
style: STextStyles.itemSubtitle(context),
|
||||||
|
),
|
||||||
|
detail: SizedBox(
|
||||||
|
width: Util.isDesktop ? 200 : 170,
|
||||||
|
child: DropdownButtonHideUnderline(
|
||||||
|
child: DropdownButton2<String>(
|
||||||
|
value: _currentDropDownValue,
|
||||||
|
items: [
|
||||||
|
...widget.cwKeyData.keys.map(
|
||||||
|
(e) => DropdownMenuItem(
|
||||||
|
value: e.label,
|
||||||
|
child: Text(
|
||||||
|
e.label,
|
||||||
|
style: STextStyles.w500_14(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value is String) {
|
||||||
|
setState(() {
|
||||||
|
_currentDropDownValue = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isExpanded: true,
|
||||||
|
buttonStyleData: ButtonStyleData(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldDefaultBG,
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
iconStyleData: IconStyleData(
|
||||||
|
icon: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 10),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.svg.chevronDown,
|
||||||
|
width: 12,
|
||||||
|
height: 6,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldActiveSearchIconRight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dropdownStyleData: DropdownStyleData(
|
||||||
|
offset: const Offset(0, -10),
|
||||||
|
elevation: 0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldDefaultBG,
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
menuItemStyleData: const MenuItemStyleData(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 16,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: Util.isDesktop ? 12 : 16,
|
||||||
|
),
|
||||||
|
QR(
|
||||||
|
data: _current(_currentDropDownValue),
|
||||||
|
size:
|
||||||
|
Util.isDesktop ? 256 : MediaQuery.of(context).size.width / 1.5,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: Util.isDesktop ? 12 : 16,
|
||||||
|
),
|
||||||
|
RoundedWhiteContainer(
|
||||||
|
borderColor: Util.isDesktop
|
||||||
|
? Theme.of(context).extension<StackColors>()!.textFieldDefaultBG
|
||||||
|
: null,
|
||||||
|
child: SelectableText(
|
||||||
|
_current(_currentDropDownValue),
|
||||||
|
style: STextStyles.w500_14(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: Util.isDesktop ? 12 : 16,
|
||||||
|
),
|
||||||
|
if (!Util.isDesktop) const Spacer(),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
if (Util.isDesktop) const Spacer(),
|
||||||
|
if (Util.isDesktop)
|
||||||
|
const SizedBox(
|
||||||
|
width: 16,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: PrimaryButton(
|
||||||
|
label: "Copy",
|
||||||
|
onPressed: _copy,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
import '../../../../app_config.dart';
|
import '../../../../app_config.dart';
|
||||||
|
import '../../../../models/keys/cw_key_data.dart';
|
||||||
|
import '../../../../models/keys/key_data_interface.dart';
|
||||||
|
import '../../../../models/keys/xpriv_data.dart';
|
||||||
import '../../../../notifications/show_flush_bar.dart';
|
import '../../../../notifications/show_flush_bar.dart';
|
||||||
import '../../../../themes/stack_colors.dart';
|
import '../../../../themes/stack_colors.dart';
|
||||||
import '../../../../utilities/address_utils.dart';
|
import '../../../../utilities/address_utils.dart';
|
||||||
|
@ -25,7 +28,6 @@ import '../../../../utilities/constants.dart';
|
||||||
import '../../../../utilities/text_styles.dart';
|
import '../../../../utilities/text_styles.dart';
|
||||||
import '../../../../utilities/util.dart';
|
import '../../../../utilities/util.dart';
|
||||||
import '../../../../wallets/isar/providers/wallet_info_provider.dart';
|
import '../../../../wallets/isar/providers/wallet_info_provider.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
|
||||||
import '../../../../widgets/background.dart';
|
import '../../../../widgets/background.dart';
|
||||||
import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
|
import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
import '../../../../widgets/custom_buttons/blue_text_button.dart';
|
import '../../../../widgets/custom_buttons/blue_text_button.dart';
|
||||||
|
@ -36,6 +38,7 @@ import '../../../../widgets/rounded_white_container.dart';
|
||||||
import '../../../../widgets/stack_dialog.dart';
|
import '../../../../widgets/stack_dialog.dart';
|
||||||
import '../../../add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
|
import '../../../add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
|
||||||
import '../../../wallet_view/transaction_views/transaction_details_view.dart';
|
import '../../../wallet_view/transaction_views/transaction_details_view.dart';
|
||||||
|
import 'cn_wallet_keys.dart';
|
||||||
import 'wallet_xprivs.dart';
|
import 'wallet_xprivs.dart';
|
||||||
|
|
||||||
class WalletBackupView extends ConsumerWidget {
|
class WalletBackupView extends ConsumerWidget {
|
||||||
|
@ -45,7 +48,7 @@ class WalletBackupView extends ConsumerWidget {
|
||||||
required this.mnemonic,
|
required this.mnemonic,
|
||||||
this.frostWalletData,
|
this.frostWalletData,
|
||||||
this.clipboardInterface = const ClipboardWrapper(),
|
this.clipboardInterface = const ClipboardWrapper(),
|
||||||
this.xprivData,
|
this.keyData,
|
||||||
});
|
});
|
||||||
|
|
||||||
static const String routeName = "/walletBackup";
|
static const String routeName = "/walletBackup";
|
||||||
|
@ -59,7 +62,7 @@ class WalletBackupView extends ConsumerWidget {
|
||||||
({String config, String keys})? prevGen,
|
({String config, String keys})? prevGen,
|
||||||
})? frostWalletData;
|
})? frostWalletData;
|
||||||
final ClipboardInterface clipboardInterface;
|
final ClipboardInterface clipboardInterface;
|
||||||
final ({List<XPriv> xprivs, String fingerprint})? xprivData;
|
final KeyDataInterface? keyData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
@ -81,24 +84,30 @@ class WalletBackupView extends ConsumerWidget {
|
||||||
style: STextStyles.navBarTitle(context),
|
style: STextStyles.navBarTitle(context),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
if (xprivData != null)
|
if (keyData != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: CustomTextButton(
|
child: CustomTextButton(
|
||||||
text: "xpriv(s)",
|
text: switch (keyData.runtimeType) {
|
||||||
|
const (XPrivData) => "xpriv(s)",
|
||||||
|
const (CWKeyData) => "keys",
|
||||||
|
_ => throw UnimplementedError(
|
||||||
|
"Don't forget to add your KeyDataInterface here! ${keyData.runtimeType}",
|
||||||
|
),
|
||||||
|
},
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(
|
Navigator.pushNamed(
|
||||||
context,
|
context,
|
||||||
MobileXPrivsView.routeName,
|
MobileKeyDataView.routeName,
|
||||||
arguments: (
|
arguments: (
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
xprivData: xprivData!,
|
keyData: keyData!,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (!frost && xprivData == null)
|
if (!frost && keyData == null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
|
@ -433,19 +442,19 @@ class _FrostKeys extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MobileXPrivsView extends StatelessWidget {
|
class MobileKeyDataView extends StatelessWidget {
|
||||||
const MobileXPrivsView({
|
const MobileKeyDataView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
this.clipboardInterface = const ClipboardWrapper(),
|
this.clipboardInterface = const ClipboardWrapper(),
|
||||||
required this.xprivData,
|
required this.keyData,
|
||||||
});
|
});
|
||||||
|
|
||||||
static const String routeName = "/mobileXPrivView";
|
static const String routeName = "/mobileXPrivView";
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final ClipboardInterface clipboardInterface;
|
final ClipboardInterface clipboardInterface;
|
||||||
final ({List<XPriv> xprivs, String fingerprint}) xprivData;
|
final KeyDataInterface keyData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -459,7 +468,13 @@ class MobileXPrivsView extends StatelessWidget {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
"Wallet xpriv(s)",
|
"Wallet ${switch (keyData.runtimeType) {
|
||||||
|
const (XPrivData) => "xpriv(s)",
|
||||||
|
const (CWKeyData) => "keys",
|
||||||
|
_ => throw UnimplementedError(
|
||||||
|
"Don't forget to add your KeyDataInterface here!",
|
||||||
|
),
|
||||||
|
}}",
|
||||||
style: STextStyles.navBarTitle(context),
|
style: STextStyles.navBarTitle(context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -475,10 +490,19 @@ class MobileXPrivsView extends StatelessWidget {
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: WalletXPrivs(
|
child: switch (keyData.runtimeType) {
|
||||||
walletId: walletId,
|
const (XPrivData) => WalletXPrivs(
|
||||||
xprivData: xprivData,
|
walletId: walletId,
|
||||||
),
|
xprivData: keyData as XPrivData,
|
||||||
|
),
|
||||||
|
const (CWKeyData) => CNWalletKeys(
|
||||||
|
walletId: walletId,
|
||||||
|
cwKeyData: keyData as CWKeyData,
|
||||||
|
),
|
||||||
|
_ => throw UnimplementedError(
|
||||||
|
"Don't forget to add your KeyDataInterface here!",
|
||||||
|
),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 16,
|
height: 16,
|
||||||
|
|
|
@ -16,6 +16,7 @@ import 'package:flutter/services.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 '../../../../models/keys/xpriv_data.dart';
|
||||||
import '../../../../notifications/show_flush_bar.dart';
|
import '../../../../notifications/show_flush_bar.dart';
|
||||||
import '../../../../themes/stack_colors.dart';
|
import '../../../../themes/stack_colors.dart';
|
||||||
import '../../../../utilities/assets.dart';
|
import '../../../../utilities/assets.dart';
|
||||||
|
@ -23,7 +24,6 @@ import '../../../../utilities/clipboard_interface.dart';
|
||||||
import '../../../../utilities/constants.dart';
|
import '../../../../utilities/constants.dart';
|
||||||
import '../../../../utilities/text_styles.dart';
|
import '../../../../utilities/text_styles.dart';
|
||||||
import '../../../../utilities/util.dart';
|
import '../../../../utilities/util.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
|
||||||
import '../../../../widgets/desktop/primary_button.dart';
|
import '../../../../widgets/desktop/primary_button.dart';
|
||||||
import '../../../../widgets/detail_item.dart';
|
import '../../../../widgets/detail_item.dart';
|
||||||
import '../../../../widgets/qr.dart';
|
import '../../../../widgets/qr.dart';
|
||||||
|
@ -37,7 +37,7 @@ class WalletXPrivs extends ConsumerStatefulWidget {
|
||||||
this.clipboardInterface = const ClipboardWrapper(),
|
this.clipboardInterface = const ClipboardWrapper(),
|
||||||
});
|
});
|
||||||
|
|
||||||
final ({List<XPriv> xprivs, String fingerprint}) xprivData;
|
final XPrivData xprivData;
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final ClipboardInterface clipboardInterface;
|
final ClipboardInterface clipboardInterface;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import 'package:tuple/tuple.dart';
|
||||||
import '../../../db/hive/db.dart';
|
import '../../../db/hive/db.dart';
|
||||||
import '../../../db/sqlite/firo_cache.dart';
|
import '../../../db/sqlite/firo_cache.dart';
|
||||||
import '../../../models/epicbox_config_model.dart';
|
import '../../../models/epicbox_config_model.dart';
|
||||||
|
import '../../../models/keys/key_data_interface.dart';
|
||||||
import '../../../notifications/show_flush_bar.dart';
|
import '../../../notifications/show_flush_bar.dart';
|
||||||
import '../../../providers/global/wallets_provider.dart';
|
import '../../../providers/global/wallets_provider.dart';
|
||||||
import '../../../providers/ui/transaction_filter_provider.dart';
|
import '../../../providers/ui/transaction_filter_provider.dart';
|
||||||
|
@ -35,6 +36,7 @@ import '../../../wallets/crypto_currency/intermediate/frost_currency.dart';
|
||||||
import '../../../wallets/crypto_currency/intermediate/nano_currency.dart';
|
import '../../../wallets/crypto_currency/intermediate/nano_currency.dart';
|
||||||
import '../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
import '../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
||||||
import '../../../wallets/wallet/impl/epiccash_wallet.dart';
|
import '../../../wallets/wallet/impl/epiccash_wallet.dart';
|
||||||
|
import '../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
||||||
import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||||
import '../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import '../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import '../../../widgets/background.dart';
|
import '../../../widgets/background.dart';
|
||||||
|
@ -261,10 +263,6 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
|
||||||
|
|
||||||
// TODO: [prio=med] take wallets that don't have a mnemonic into account
|
// TODO: [prio=med] take wallets that don't have a mnemonic into account
|
||||||
|
|
||||||
({
|
|
||||||
List<XPriv> xprivs,
|
|
||||||
String fingerprint
|
|
||||||
})? xprivData;
|
|
||||||
List<String>? mnemonic;
|
List<String>? mnemonic;
|
||||||
({
|
({
|
||||||
String myName,
|
String myName,
|
||||||
|
@ -306,8 +304,11 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
|
||||||
await wallet.getMnemonicAsWords();
|
await wallet.getMnemonicAsWords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
xprivData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
|
} else if (wallet is CwBasedInterface) {
|
||||||
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
@ -323,7 +324,7 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
|
||||||
mnemonic: mnemonic ?? [],
|
mnemonic: mnemonic ?? [],
|
||||||
frostWalletData:
|
frostWalletData:
|
||||||
frostWalletData,
|
frostWalletData,
|
||||||
xprivData: xprivData,
|
keyData: keyData,
|
||||||
),
|
),
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
routeOnSuccess:
|
routeOnSuccess:
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
|
import '../../models/keys/key_data_interface.dart';
|
||||||
import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
|
import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
|
||||||
import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart';
|
import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart';
|
||||||
import '../../providers/global/wallets_provider.dart';
|
import '../../providers/global/wallets_provider.dart';
|
||||||
|
@ -11,6 +12,7 @@ import '../../utilities/assets.dart';
|
||||||
import '../../utilities/text_styles.dart';
|
import '../../utilities/text_styles.dart';
|
||||||
import '../../utilities/util.dart';
|
import '../../utilities/util.dart';
|
||||||
import '../../wallets/isar/providers/wallet_info_provider.dart';
|
import '../../wallets/isar/providers/wallet_info_provider.dart';
|
||||||
|
import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
import '../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||||
import '../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import '../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import '../../widgets/background.dart';
|
import '../../widgets/background.dart';
|
||||||
|
@ -265,9 +267,11 @@ class _FiroRescanRecoveryErrorViewState
|
||||||
if (wallet is MnemonicInterface) {
|
if (wallet is MnemonicInterface) {
|
||||||
final mnemonic = await wallet.getMnemonicAsWords();
|
final mnemonic = await wallet.getMnemonicAsWords();
|
||||||
|
|
||||||
({List<XPriv> xprivs, String fingerprint})? xprivData;
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
xprivData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
|
} else if (wallet is CwBasedInterface) {
|
||||||
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
@ -280,7 +284,7 @@ class _FiroRescanRecoveryErrorViewState
|
||||||
routeOnSuccessArguments: (
|
routeOnSuccessArguments: (
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
xprivData: xprivData,
|
keyData: keyData,
|
||||||
),
|
),
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
routeOnSuccess: WalletBackupView.routeName,
|
routeOnSuccess: WalletBackupView.routeName,
|
||||||
|
|
|
@ -338,7 +338,7 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
|
||||||
onTap: () {
|
onTap: () {
|
||||||
clipboard.setData(
|
clipboard.setData(
|
||||||
ClipboardData(
|
ClipboardData(
|
||||||
text: ref.watch(pWalletReceivingAddress(walletId)),
|
text: address,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
showFloatingFlushBar(
|
showFloatingFlushBar(
|
||||||
|
|
|
@ -14,6 +14,7 @@ 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 '../../../../models/keys/key_data_interface.dart';
|
||||||
import '../../../../notifications/show_flush_bar.dart';
|
import '../../../../notifications/show_flush_bar.dart';
|
||||||
import '../../../../providers/desktop/storage_crypto_handler_provider.dart';
|
import '../../../../providers/desktop/storage_crypto_handler_provider.dart';
|
||||||
import '../../../../providers/providers.dart';
|
import '../../../../providers/providers.dart';
|
||||||
|
@ -22,6 +23,7 @@ import '../../../../utilities/assets.dart';
|
||||||
import '../../../../utilities/constants.dart';
|
import '../../../../utilities/constants.dart';
|
||||||
import '../../../../utilities/text_styles.dart';
|
import '../../../../utilities/text_styles.dart';
|
||||||
import '../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
import '../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
|
||||||
|
import '../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import '../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import '../../../../widgets/desktop/desktop_dialog.dart';
|
import '../../../../widgets/desktop/desktop_dialog.dart';
|
||||||
|
@ -85,7 +87,6 @@ class _UnlockWalletKeysDesktopState
|
||||||
final wallet = ref.read(pWallets).getWallet(widget.walletId);
|
final wallet = ref.read(pWallets).getWallet(widget.walletId);
|
||||||
({String keys, String config})? frostData;
|
({String keys, String config})? frostData;
|
||||||
List<String>? words;
|
List<String>? words;
|
||||||
({List<XPriv> xprivs, String fingerprint})? xprivData;
|
|
||||||
|
|
||||||
// TODO: [prio=low] handle wallets that don't have a mnemonic
|
// TODO: [prio=low] handle wallets that don't have a mnemonic
|
||||||
// All wallets currently are mnemonic based
|
// All wallets currently are mnemonic based
|
||||||
|
@ -102,8 +103,11 @@ class _UnlockWalletKeysDesktopState
|
||||||
words = await wallet.getMnemonicAsWords();
|
words = await wallet.getMnemonicAsWords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
xprivData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
|
} else if (wallet is CwBasedInterface) {
|
||||||
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
@ -113,7 +117,7 @@ class _UnlockWalletKeysDesktopState
|
||||||
mnemonic: words ?? [],
|
mnemonic: words ?? [],
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
frostData: frostData,
|
frostData: frostData,
|
||||||
xprivData: xprivData,
|
keyData: keyData,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -327,10 +331,6 @@ class _UnlockWalletKeysDesktopState
|
||||||
|
|
||||||
({String keys, String config})? frostData;
|
({String keys, String config})? frostData;
|
||||||
List<String>? words;
|
List<String>? words;
|
||||||
({
|
|
||||||
List<XPriv> xprivs,
|
|
||||||
String fingerprint
|
|
||||||
})? xprivData;
|
|
||||||
|
|
||||||
final wallet =
|
final wallet =
|
||||||
ref.read(pWallets).getWallet(widget.walletId);
|
ref.read(pWallets).getWallet(widget.walletId);
|
||||||
|
@ -350,11 +350,14 @@ class _UnlockWalletKeysDesktopState
|
||||||
words = await wallet.getMnemonicAsWords();
|
words = await wallet.getMnemonicAsWords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyDataInterface? keyData;
|
||||||
if (wallet is ExtendedKeysInterface) {
|
if (wallet is ExtendedKeysInterface) {
|
||||||
xprivData = await wallet.getXPrivs();
|
keyData = await wallet.getXPrivs();
|
||||||
|
} else if (wallet is CwBasedInterface) {
|
||||||
|
keyData = await wallet.getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mounted) {
|
if (context.mounted) {
|
||||||
await Navigator.of(context)
|
await Navigator.of(context)
|
||||||
.pushReplacementNamed(
|
.pushReplacementNamed(
|
||||||
WalletKeysDesktopPopup.routeName,
|
WalletKeysDesktopPopup.routeName,
|
||||||
|
@ -362,7 +365,7 @@ class _UnlockWalletKeysDesktopState
|
||||||
mnemonic: words ?? [],
|
mnemonic: words ?? [],
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
frostData: frostData,
|
frostData: frostData,
|
||||||
xprivData: xprivData,
|
keyData: keyData,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,12 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
import '../../../../models/keys/cw_key_data.dart';
|
||||||
|
import '../../../../models/keys/key_data_interface.dart';
|
||||||
|
import '../../../../models/keys/xpriv_data.dart';
|
||||||
import '../../../../notifications/show_flush_bar.dart';
|
import '../../../../notifications/show_flush_bar.dart';
|
||||||
import '../../../../pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
|
import '../../../../pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
|
||||||
|
import '../../../../pages/settings_views/wallet_settings_view/wallet_backup_views/cn_wallet_keys.dart';
|
||||||
import '../../../../pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_xprivs.dart';
|
import '../../../../pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_xprivs.dart';
|
||||||
import '../../../../pages/wallet_view/transaction_views/transaction_details_view.dart';
|
import '../../../../pages/wallet_view/transaction_views/transaction_details_view.dart';
|
||||||
import '../../../../themes/stack_colors.dart';
|
import '../../../../themes/stack_colors.dart';
|
||||||
|
@ -23,7 +27,6 @@ import '../../../../utilities/address_utils.dart';
|
||||||
import '../../../../utilities/assets.dart';
|
import '../../../../utilities/assets.dart';
|
||||||
import '../../../../utilities/clipboard_interface.dart';
|
import '../../../../utilities/clipboard_interface.dart';
|
||||||
import '../../../../utilities/text_styles.dart';
|
import '../../../../utilities/text_styles.dart';
|
||||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
|
||||||
import '../../../../widgets/custom_tab_view.dart';
|
import '../../../../widgets/custom_tab_view.dart';
|
||||||
import '../../../../widgets/desktop/desktop_dialog.dart';
|
import '../../../../widgets/desktop/desktop_dialog.dart';
|
||||||
import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
|
import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
|
||||||
|
@ -39,14 +42,14 @@ class WalletKeysDesktopPopup extends ConsumerWidget {
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
this.frostData,
|
this.frostData,
|
||||||
this.clipboardInterface = const ClipboardWrapper(),
|
this.clipboardInterface = const ClipboardWrapper(),
|
||||||
this.xprivData,
|
this.keyData,
|
||||||
});
|
});
|
||||||
|
|
||||||
final List<String> words;
|
final List<String> words;
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final ({String keys, String config})? frostData;
|
final ({String keys, String config})? frostData;
|
||||||
final ClipboardInterface clipboardInterface;
|
final ClipboardInterface clipboardInterface;
|
||||||
final ({List<XPriv> xprivs, String fingerprint})? xprivData;
|
final KeyDataInterface? keyData;
|
||||||
|
|
||||||
static const String routeName = "walletKeysDesktopPopup";
|
static const String routeName = "walletKeysDesktopPopup";
|
||||||
|
|
||||||
|
@ -176,9 +179,13 @@ class WalletKeysDesktopPopup extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: xprivData != null
|
: keyData != null
|
||||||
? CustomTabView(
|
? CustomTabView(
|
||||||
titles: const ["Mnemonic", "XPriv(s)"],
|
titles: [
|
||||||
|
"Mnemonic",
|
||||||
|
if (keyData is XPrivData) "XPriv(s)",
|
||||||
|
if (keyData is CWKeyData) "Keys",
|
||||||
|
],
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 16),
|
padding: const EdgeInsets.only(top: 16),
|
||||||
|
@ -186,10 +193,16 @@ class WalletKeysDesktopPopup extends ConsumerWidget {
|
||||||
words: words,
|
words: words,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
WalletXPrivs(
|
if (keyData is XPrivData)
|
||||||
xprivData: xprivData!,
|
WalletXPrivs(
|
||||||
walletId: walletId,
|
xprivData: keyData as XPrivData,
|
||||||
),
|
walletId: walletId,
|
||||||
|
),
|
||||||
|
if (keyData is CWKeyData)
|
||||||
|
CNWalletKeys(
|
||||||
|
cwKeyData: keyData as CWKeyData,
|
||||||
|
walletId: walletId,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: _Mnemonic(
|
: _Mnemonic(
|
||||||
|
|
|
@ -22,6 +22,7 @@ import 'models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||||
import 'models/isar/models/contact_entry.dart';
|
import 'models/isar/models/contact_entry.dart';
|
||||||
import 'models/isar/models/isar_models.dart';
|
import 'models/isar/models/isar_models.dart';
|
||||||
import 'models/isar/ordinal.dart';
|
import 'models/isar/ordinal.dart';
|
||||||
|
import 'models/keys/key_data_interface.dart';
|
||||||
import 'models/paynym/paynym_account_lite.dart';
|
import 'models/paynym/paynym_account_lite.dart';
|
||||||
import 'models/send_view_auto_fill_data.dart';
|
import 'models/send_view_auto_fill_data.dart';
|
||||||
import 'pages/add_wallet_views/add_token_view/add_custom_token_view.dart';
|
import 'pages/add_wallet_views/add_token_view/add_custom_token_view.dart';
|
||||||
|
@ -1280,14 +1281,14 @@ class RouteGenerator {
|
||||||
} else if (args is ({
|
} else if (args is ({
|
||||||
String walletId,
|
String walletId,
|
||||||
List<String> mnemonic,
|
List<String> mnemonic,
|
||||||
({List<XPriv> xprivs, String fingerprint})? xprivData,
|
KeyDataInterface? keyData,
|
||||||
})) {
|
})) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => WalletBackupView(
|
builder: (_) => WalletBackupView(
|
||||||
walletId: args.walletId,
|
walletId: args.walletId,
|
||||||
mnemonic: args.mnemonic,
|
mnemonic: args.mnemonic,
|
||||||
xprivData: args.xprivData,
|
keyData: args.keyData,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
@ -1296,7 +1297,7 @@ class RouteGenerator {
|
||||||
} else if (args is ({
|
} else if (args is ({
|
||||||
String walletId,
|
String walletId,
|
||||||
List<String> mnemonic,
|
List<String> mnemonic,
|
||||||
({List<XPriv> xprivs, String fingerprint})? xprivData,
|
KeyDataInterface? keyData,
|
||||||
({
|
({
|
||||||
String myName,
|
String myName,
|
||||||
String config,
|
String config,
|
||||||
|
@ -1310,7 +1311,7 @@ class RouteGenerator {
|
||||||
walletId: args.walletId,
|
walletId: args.walletId,
|
||||||
mnemonic: args.mnemonic,
|
mnemonic: args.mnemonic,
|
||||||
frostWalletData: args.frostWalletData,
|
frostWalletData: args.frostWalletData,
|
||||||
xprivData: args.xprivData,
|
keyData: args.keyData,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
@ -1319,16 +1320,16 @@ class RouteGenerator {
|
||||||
}
|
}
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case MobileXPrivsView.routeName:
|
case MobileKeyDataView.routeName:
|
||||||
if (args is ({
|
if (args is ({
|
||||||
String walletId,
|
String walletId,
|
||||||
({List<XPriv> xprivs, String fingerprint}) xprivData,
|
KeyDataInterface keyData,
|
||||||
})) {
|
})) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => MobileXPrivsView(
|
builder: (_) => MobileKeyDataView(
|
||||||
walletId: args.walletId,
|
walletId: args.walletId,
|
||||||
xprivData: args.xprivData,
|
keyData: args.keyData,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
@ -2369,14 +2370,14 @@ class RouteGenerator {
|
||||||
List<String> mnemonic,
|
List<String> mnemonic,
|
||||||
String walletId,
|
String walletId,
|
||||||
({String keys, String config})? frostData,
|
({String keys, String config})? frostData,
|
||||||
({List<XPriv> xprivs, String fingerprint})? xprivData,
|
KeyDataInterface? keyData,
|
||||||
})) {
|
})) {
|
||||||
return FadePageRoute(
|
return FadePageRoute(
|
||||||
WalletKeysDesktopPopup(
|
WalletKeysDesktopPopup(
|
||||||
words: args.mnemonic,
|
words: args.mnemonic,
|
||||||
walletId: args.walletId,
|
walletId: args.walletId,
|
||||||
frostData: args.frostData,
|
frostData: args.frostData,
|
||||||
xprivData: args.xprivData,
|
keyData: args.keyData,
|
||||||
),
|
),
|
||||||
RouteSettings(
|
RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
@ -2385,13 +2386,13 @@ class RouteGenerator {
|
||||||
} else if (args is ({
|
} else if (args is ({
|
||||||
List<String> mnemonic,
|
List<String> mnemonic,
|
||||||
String walletId,
|
String walletId,
|
||||||
({List<XPriv> xprivs, String fingerprint})? xprivData,
|
KeyDataInterface? keyData,
|
||||||
})) {
|
})) {
|
||||||
return FadePageRoute(
|
return FadePageRoute(
|
||||||
WalletKeysDesktopPopup(
|
WalletKeysDesktopPopup(
|
||||||
words: args.mnemonic,
|
words: args.mnemonic,
|
||||||
walletId: args.walletId,
|
walletId: args.walletId,
|
||||||
xprivData: args.xprivData,
|
keyData: args.keyData,
|
||||||
),
|
),
|
||||||
RouteSettings(
|
RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
|
|
@ -133,21 +133,41 @@ class TxData {
|
||||||
.reduce((total, amount) => total += amount)
|
.reduce((total, amount) => total += amount)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
Amount? get amountWithoutChange =>
|
Amount? get amountWithoutChange {
|
||||||
recipients != null && recipients!.isNotEmpty
|
if (recipients != null && recipients!.isNotEmpty) {
|
||||||
? recipients!
|
if (recipients!.where((e) => !e.isChange).isEmpty) {
|
||||||
.where((e) => !e.isChange)
|
return Amount(
|
||||||
.map((e) => e.amount)
|
rawValue: BigInt.zero,
|
||||||
.reduce((total, amount) => total += amount)
|
fractionDigits: recipients!.first.amount.fractionDigits,
|
||||||
: null;
|
);
|
||||||
|
} else {
|
||||||
|
return recipients!
|
||||||
|
.where((e) => !e.isChange)
|
||||||
|
.map((e) => e.amount)
|
||||||
|
.reduce((total, amount) => total += amount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Amount? get amountSparkWithoutChange =>
|
Amount? get amountSparkWithoutChange {
|
||||||
sparkRecipients != null && sparkRecipients!.isNotEmpty
|
if (sparkRecipients != null && sparkRecipients!.isNotEmpty) {
|
||||||
? sparkRecipients!
|
if (sparkRecipients!.where((e) => !e.isChange).isEmpty) {
|
||||||
.where((e) => !e.isChange)
|
return Amount(
|
||||||
.map((e) => e.amount)
|
rawValue: BigInt.zero,
|
||||||
.reduce((total, amount) => total += amount)
|
fractionDigits: sparkRecipients!.first.amount.fractionDigits,
|
||||||
: null;
|
);
|
||||||
|
} else {
|
||||||
|
return sparkRecipients!
|
||||||
|
.where((e) => !e.isChange)
|
||||||
|
.map((e) => e.amount)
|
||||||
|
.reduce((total, amount) => total += amount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int? get estimatedSatsPerVByte => fee != null && vSize != null
|
int? get estimatedSatsPerVByte => fee != null && vSize != null
|
||||||
? (fee!.raw ~/ BigInt.from(vSize!)).toInt()
|
? (fee!.raw ~/ BigInt.from(vSize!)).toInt()
|
||||||
|
|
|
@ -25,6 +25,7 @@ import 'package:tuple/tuple.dart';
|
||||||
import '../../../db/hive/db.dart';
|
import '../../../db/hive/db.dart';
|
||||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
import '../../../models/isar/models/blockchain_data/address.dart';
|
||||||
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
||||||
|
import '../../../models/keys/cw_key_data.dart';
|
||||||
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
||||||
import '../../../services/event_bus/events/global/tor_status_changed_event.dart';
|
import '../../../services/event_bus/events/global/tor_status_changed_event.dart';
|
||||||
import '../../../services/event_bus/global_event_bus.dart';
|
import '../../../services/event_bus/global_event_bus.dart';
|
||||||
|
@ -235,6 +236,25 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CWKeyData?> getKeys() async {
|
||||||
|
final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?);
|
||||||
|
|
||||||
|
if (base == null ||
|
||||||
|
base.walletInfo.name != walletId ||
|
||||||
|
CwBasedInterface.exitMutex.isLocked) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CWKeyData(
|
||||||
|
walletId: walletId,
|
||||||
|
publicViewKey: base.keys.publicViewKey,
|
||||||
|
privateViewKey: base.keys.privateViewKey,
|
||||||
|
publicSpendKey: base.keys.publicSpendKey,
|
||||||
|
privateSpendKey: base.keys.privateSpendKey,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateTransactions() async {
|
Future<void> updateTransactions() async {
|
||||||
final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?);
|
final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import 'package:tuple/tuple.dart';
|
||||||
import '../../../db/hive/db.dart';
|
import '../../../db/hive/db.dart';
|
||||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
import '../../../models/isar/models/blockchain_data/address.dart';
|
||||||
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
||||||
|
import '../../../models/keys/cw_key_data.dart';
|
||||||
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
|
||||||
import '../../../services/event_bus/events/global/tor_status_changed_event.dart';
|
import '../../../services/event_bus/events/global/tor_status_changed_event.dart';
|
||||||
import '../../../services/event_bus/global_event_bus.dart';
|
import '../../../services/event_bus/global_event_bus.dart';
|
||||||
|
@ -214,6 +215,25 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<CWKeyData?> getKeys() async {
|
||||||
|
final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?);
|
||||||
|
|
||||||
|
if (base == null ||
|
||||||
|
base.walletInfo.name != walletId ||
|
||||||
|
CwBasedInterface.exitMutex.isLocked) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CWKeyData(
|
||||||
|
walletId: walletId,
|
||||||
|
publicViewKey: base.keys.publicViewKey,
|
||||||
|
privateViewKey: base.keys.privateViewKey,
|
||||||
|
publicSpendKey: base.keys.publicSpendKey,
|
||||||
|
privateSpendKey: base.keys.privateSpendKey,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateTransactions() async {
|
Future<void> updateTransactions() async {
|
||||||
final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?);
|
final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?);
|
||||||
|
|
|
@ -14,6 +14,7 @@ import 'package:mutex/mutex.dart';
|
||||||
|
|
||||||
import '../../../models/balance.dart';
|
import '../../../models/balance.dart';
|
||||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
import '../../../models/isar/models/blockchain_data/address.dart';
|
||||||
|
import '../../../models/keys/cw_key_data.dart';
|
||||||
import '../../../models/paymint/fee_object_model.dart';
|
import '../../../models/paymint/fee_object_model.dart';
|
||||||
import '../../../services/event_bus/events/global/blocks_remaining_event.dart';
|
import '../../../services/event_bus/events/global/blocks_remaining_event.dart';
|
||||||
import '../../../services/event_bus/events/global/refresh_percent_changed_event.dart';
|
import '../../../services/event_bus/events/global/refresh_percent_changed_event.dart';
|
||||||
|
@ -195,6 +196,8 @@ mixin CwBasedInterface<T extends CryptonoteCurrency> on CryptonoteWallet<T>
|
||||||
|
|
||||||
Address addressFor({required int index, int account = 0});
|
Address addressFor({required int index, int account = 0});
|
||||||
|
|
||||||
|
Future<CWKeyData?> getKeys();
|
||||||
|
|
||||||
// ============ Private ======================================================
|
// ============ Private ======================================================
|
||||||
Future<void> _refreshTxDataHelper() async {
|
Future<void> _refreshTxDataHelper() async {
|
||||||
if (_txRefreshLock) return;
|
if (_txRefreshLock) return;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import '../../../models/keys/xpriv_data.dart';
|
||||||
import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
|
import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
|
||||||
import 'electrumx_interface.dart';
|
import 'electrumx_interface.dart';
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ mixin ExtendedKeysInterface<T extends ElectrumXCurrencyInterface>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<({List<XPriv> xprivs, String fingerprint})> getXPrivs() async {
|
Future<XPrivData> getXPrivs() async {
|
||||||
final paths = cryptoCurrency.supportedDerivationPathTypes.map(
|
final paths = cryptoCurrency.supportedDerivationPathTypes.map(
|
||||||
(e) => (
|
(e) => (
|
||||||
path: e,
|
path: e,
|
||||||
|
@ -71,7 +72,8 @@ mixin ExtendedKeysInterface<T extends ElectrumXCurrencyInterface>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return XPrivData(
|
||||||
|
walletId: walletId,
|
||||||
fingerprint: fingerprint,
|
fingerprint: fingerprint,
|
||||||
xprivs: [
|
xprivs: [
|
||||||
(
|
(
|
||||||
|
|
Loading…
Reference in a new issue