show xpubs

This commit is contained in:
julian 2024-07-03 12:30:30 -06:00
parent d66e0580ec
commit 64b61779cd
4 changed files with 170 additions and 214 deletions

View file

@ -35,6 +35,7 @@ import '../../../wallets/crypto_currency/intermediate/frost_currency.dart';
import '../../../wallets/crypto_currency/intermediate/nano_currency.dart';
import '../../../wallets/wallet/impl/bitcoin_frost_wallet.dart';
import '../../../wallets/wallet/impl/epiccash_wallet.dart';
import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
import '../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
import '../../../widgets/background.dart';
import '../../../widgets/custom_buttons/app_bar_icon_button.dart';
@ -95,9 +96,9 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
void initState() {
walletId = widget.walletId;
coin = widget.coin;
// TODO: [prio=low] xpubs
// xPubEnabled = ref.read(pWallets).getWallet(walletId).hasXPub;
xPubEnabled = false;
xPubEnabled =
ref.read(pWallets).getWallet(walletId) is ExtendedKeysInterface;
xpub = "";
_currentSyncStatus = widget.initialSyncStatus;
@ -373,11 +374,30 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
return SettingsListButton(
iconAssetName: Assets.svg.eye,
title: "Wallet xPub",
onPressed: () {
Navigator.of(context).pushNamed(
XPubView.routeName,
arguments: widget.walletId,
onPressed: () async {
final xpubData = await showLoading(
delay: const Duration(
milliseconds: 800,
),
whileFuture: (ref
.read(pWallets)
.getWallet(walletId)
as ExtendedKeysInterface)
.getXPubs(),
context: context,
message: "Loading xpubs",
rootNavigator: Util.isDesktop,
);
if (context.mounted) {
await Navigator.of(context)
.pushNamed(
XPubView.routeName,
arguments: (
widget.walletId,
xpubData
),
);
}
},
);
},

View file

@ -13,80 +13,45 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import '../../../../notifications/show_flush_bar.dart';
import '../../../../providers/global/wallets_provider.dart';
import '../../../../themes/stack_colors.dart';
import '../../../../utilities/assets.dart';
import '../../../../utilities/clipboard_interface.dart';
import '../../../../utilities/text_styles.dart';
import '../../../../utilities/util.dart';
import '../../../../wallets/wallet/wallet.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/conditional_parent.dart';
import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
import '../../../../widgets/custom_tab_view.dart';
import '../../../../widgets/desktop/desktop_dialog.dart';
import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
import '../../../../widgets/desktop/primary_button.dart';
import '../../../../widgets/desktop/secondary_button.dart';
import '../../../../widgets/loading_indicator.dart';
import '../../../../widgets/detail_item.dart';
import '../../../../widgets/qr.dart';
import '../../../../widgets/rounded_white_container.dart';
class XPubView extends ConsumerStatefulWidget {
class XPubView extends ConsumerWidget {
const XPubView({
super.key,
required this.walletId,
required this.xpubData,
this.clipboardInterface = const ClipboardWrapper(),
});
final String walletId;
final ClipboardInterface clipboardInterface;
final ({List<XPub> xpubs, String fingerprint}) xpubData;
static const String routeName = "/xpub";
@override
ConsumerState<XPubView> createState() => _XPubViewState();
}
class _XPubViewState extends ConsumerState<XPubView> {
Widget build(BuildContext context, WidgetRef ref) {
final bool isDesktop = Util.isDesktop;
late ClipboardInterface _clipboardInterface;
late final Wallet wallet;
String? xpub;
@override
void initState() {
_clipboardInterface = widget.clipboardInterface;
wallet = ref.read(pWallets).getWallet(widget.walletId);
super.initState();
}
@override
void dispose() {
super.dispose();
}
Future<void> _copy() async {
await _clipboardInterface.setData(ClipboardData(text: xpub!));
if (mounted) {
unawaited(
showFloatingFlushBar(
type: FlushBarType.info,
message: "Copied to clipboard",
iconAsset: Assets.svg.copy,
context: context,
),
);
}
}
@override
Widget build(BuildContext context) {
return ConditionalParent(
condition: !isDesktop,
builder: (child) => Background(
@ -100,35 +65,9 @@ class _XPubViewState extends ConsumerState<XPubView> {
},
),
title: Text(
"Wallet xPub",
"Wallet xpub(s)",
style: STextStyles.navBarTitle(context),
),
actions: [
Padding(
padding: const EdgeInsets.all(10),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
color:
Theme.of(context).extension<StackColors>()!.background,
shadows: const [],
icon: SvgPicture.asset(
Assets.svg.copy,
width: 24,
height: 24,
color: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: () {
if (xpub != null) {
_copy();
}
},
),
),
),
],
),
body: Padding(
padding: const EdgeInsets.only(
@ -136,7 +75,7 @@ class _XPubViewState extends ConsumerState<XPubView> {
left: 16,
right: 16,
),
child: child,
child: SingleChildScrollView(child: child),
),
),
),
@ -146,6 +85,7 @@ class _XPubViewState extends ConsumerState<XPubView> {
maxWidth: 600,
maxHeight: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -155,7 +95,7 @@ class _XPubViewState extends ConsumerState<XPubView> {
left: 32,
),
child: Text(
"${wallet.info.name} xPub",
"${ref.watch(pWalletName(walletId))} xpub(s)",
style: STextStyles.desktopH2(context),
),
),
@ -167,62 +107,40 @@ class _XPubViewState extends ConsumerState<XPubView> {
),
],
),
AnimatedSize(
duration: const Duration(
milliseconds: 150,
),
Flexible(
child: Padding(
padding: const EdgeInsets.fromLTRB(32, 0, 32, 32),
child: SingleChildScrollView(
child: child,
),
),
),
],
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (isDesktop) const SizedBox(height: 44),
ConditionalParent(
condition: !isDesktop,
builder: (child) => Expanded(
child: child,
if (isDesktop) const SizedBox(height: 16),
DetailItem(
title: "Master fingerprint",
detail: xpubData.fingerprint,
horizontal: true,
),
child: FutureBuilder(
future: Future(() => "fixme"),
// future: wallet.xpub,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
xpub = snapshot.data!;
}
const height = 600.0;
Widget child;
if (xpub == null) {
child = const SizedBox(
key: Key("loadingXPUB"),
height: height,
child: Center(
child: LoadingIndicator(
width: 100,
if (isDesktop) const SizedBox(height: 16),
CustomTabView(
titles: xpubData.xpubs.map((e) => e.path).toList(),
children: xpubData.xpubs
.map(
(e) => Padding(
padding: const EdgeInsets.only(top: 16),
child: _XPub(
xpub: e.xpub,
derivation: e.path,
),
),
);
} else {
child = _XPub(
xpub: xpub!,
height: height,
);
}
return AnimatedSwitcher(
duration: const Duration(
milliseconds: 200,
),
child: child,
);
},
),
)
.toList(),
),
],
),
@ -235,22 +153,25 @@ class _XPub extends StatelessWidget {
const _XPub({
super.key,
required this.xpub,
required this.height,
required this.derivation,
this.clipboardInterface = const ClipboardWrapper(),
});
final String xpub;
final double height;
final String derivation;
final ClipboardInterface clipboardInterface;
@override
Widget build(BuildContext context) {
final bool isDesktop = Util.isDesktop;
return SizedBox(
height: isDesktop ? height : double.infinity,
child: Column(
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 25,
),
ConditionalParent(
condition: !isDesktop,
builder: (child) => RoundedWhiteContainer(
@ -311,9 +232,7 @@ class _XPub extends StatelessWidget {
),
],
),
if (!isDesktop) const Spacer(),
],
),
);
}
}

View file

@ -18,15 +18,19 @@ import 'package:flutter_svg/svg.dart';
import '../../../../pages/settings_views/wallet_settings_view/frost_ms/frost_ms_options_view.dart';
import '../../../../pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart';
import '../../../../pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart';
import '../../../../providers/global/wallets_provider.dart';
import '../../../../route_generator.dart';
import '../../../../themes/stack_colors.dart';
import '../../../../utilities/assets.dart';
import '../../../../utilities/constants.dart';
import '../../../../utilities/show_loading.dart';
import '../../../../utilities/text_styles.dart';
import '../../../../utilities/util.dart';
import '../../../../wallets/crypto_currency/coins/firo.dart';
import '../../../../wallets/crypto_currency/intermediate/frost_currency.dart';
import '../../../../wallets/crypto_currency/intermediate/nano_currency.dart';
import '../../../../wallets/isar/providers/wallet_info_provider.dart';
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
import '../../../addresses/desktop_wallet_addresses_view.dart';
import '../../../lelantus_coins/lelantus_coins_view.dart';
import '../../../spark_coins/spark_coins_view.dart';
@ -61,7 +65,7 @@ enum _WalletOptions {
}
}
class WalletOptionsButton extends StatelessWidget {
class WalletOptionsButton extends ConsumerWidget {
const WalletOptionsButton({
super.key,
required this.walletId,
@ -70,7 +74,7 @@ class WalletOptionsButton extends StatelessWidget {
final String walletId;
@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
return RawMaterialButton(
constraints: const BoxConstraints(
minHeight: 32,
@ -148,6 +152,17 @@ class WalletOptionsButton extends StatelessWidget {
}
break;
case _WalletOptions.showXpub:
final xpubData = await showLoading(
delay: const Duration(milliseconds: 800),
whileFuture: (ref.read(pWallets).getWallet(walletId)
as ExtendedKeysInterface)
.getXPubs(),
context: context,
message: "Loading xpubs",
rootNavigator: Util.isDesktop,
);
if (context.mounted) {
final result = await showDialog<bool?>(
context: context,
barrierDismissible: false,
@ -159,7 +174,7 @@ class WalletOptionsButton extends StatelessWidget {
RouteGenerator.generateRoute(
RouteSettings(
name: XPubView.routeName,
arguments: walletId,
arguments: (walletId, xpubData),
),
),
];
@ -172,6 +187,7 @@ class WalletOptionsButton extends StatelessWidget {
Navigator.of(context).pop();
}
}
}
break;
case _WalletOptions.changeRepresentative:
final result = await showDialog<bool?>(
@ -279,9 +295,8 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
final firoDebug = kDebugMode && (coin is Firo);
// TODO: [prio=low]
// final bool xpubEnabled = manager.hasXPub;
final bool xpubEnabled = false;
final bool xpubEnabled =
ref.watch(pWallets).getWallet(walletId) is ExtendedKeysInterface;
final bool canChangeRep = coin is NanoCurrency;

View file

@ -198,6 +198,7 @@ import 'wallets/crypto_currency/crypto_currency.dart';
import 'wallets/crypto_currency/intermediate/frost_currency.dart';
import 'wallets/models/tx_data.dart';
import 'wallets/wallet/wallet.dart';
import 'wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
import 'widgets/choose_coin_view.dart';
import 'widgets/frost_scaffold.dart';
@ -908,11 +909,12 @@ class RouteGenerator {
);
case XPubView.routeName:
if (args is String) {
if (args is (String, ({List<XPub> xpubs, String fingerprint}))) {
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,
builder: (_) => XPubView(
walletId: args,
walletId: args.$1,
xpubData: args.$2,
),
settings: RouteSettings(
name: settings.name,