Merge pull request #104 from cypherstack/staging

Staging
This commit is contained in:
Rylee Davis 2022-09-29 18:20:04 -06:00 committed by GitHub
commit 4d946bfe6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 8525 additions and 4351 deletions

View file

@ -0,0 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 23.8456C18.5421 23.8456 23.8456 18.5421 23.8456 12C23.8456 5.45778 18.5421 0.154297 12 0.154297C5.45778 0.154297 0.154297 5.45778 0.154297 12C0.154297 18.5421 5.45778 23.8456 12 23.8456Z" fill="white"/>
<path d="M12 24C5.38264 24 0 18.6174 0 12C0 5.38264 5.38264 0 12 0C18.6174 0 24 5.38264 24 12C24 18.6174 18.6174 24 12 24ZM12 0.327974C5.55627 0.327974 0.327974 5.57556 0.327974 12C0.327974 18.4244 5.57556 23.672 12 23.672C18.4244 23.672 23.672 18.4244 23.672 12C23.672 5.57556 18.4437 0.327974 12 0.327974Z" fill="#D0509D"/>
<path d="M11.9995 0.154297C6.75195 0.154297 2.29536 3.58838 0.751953 8.31507H6.73266V15.7427L11.961 10.0707H12.0381L17.2664 15.762V8.31507H23.2471C21.7037 3.58838 17.2471 0.154297 11.9995 0.154297Z" fill="#FFCD05"/>
<path d="M6.56007 16.1672V8.48875H0.521484L0.598655 8.27653C2.19994 3.31833 6.79158 0 12.0006 0C17.2096 0 21.8012 3.31833 23.4025 8.27653L23.4797 8.48875H17.4411V16.1672L12.0006 10.283L6.56007 16.1672ZM11.9041 9.9164H12.1163L17.1131 15.3376V8.16077H23.036C21.3961 3.47267 16.9974 0.327974 12.0006 0.327974C7.0038 0.327974 2.60509 3.47267 0.965214 8.16077H6.88804V15.3376L11.9041 9.9164Z" fill="#D0509D"/>
<path d="M18.2473 18.2508L16.5495 16.418L11.9965 11.4791L7.4434 16.418L5.74565 18.2508V15.762V9.5498H1.59774C1.40482 10.3601 1.28906 11.209 1.28906 12.0964C1.28906 18 6.07363 22.8038 11.9965 22.8038C17.9193 22.8038 22.7039 18.0193 22.7039 12.0964C22.7039 11.2283 22.5881 10.3794 22.3952 9.5498H18.228V15.762V18.2508H18.2473Z" fill="#D0519D"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

25
assets/svg/drd-icon.svg Normal file
View file

@ -0,0 +1,25 @@
<svg width="99" height="70" viewBox="0 0 99 70" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5372_11232)">
<path d="M91.2807 31.334H36.3926C32.1291 31.334 28.6729 34.8203 28.6729 39.1208V62.2128C28.6729 66.5134 32.1291 69.9996 36.3926 69.9996H91.2807C95.5442 69.9996 99.0004 66.5134 99.0004 62.2128V39.1208C99.0004 34.8203 95.5442 31.334 91.2807 31.334Z" fill="#E1E2E3"/>
<path d="M93.2051 28.6192V59.8664C93.2051 62.0499 91.4525 63.8177 89.2879 63.8177H25.0787C22.9088 63.8177 21.1562 62.0499 21.1562 59.8611V28.6245C21.1562 26.441 22.9088 24.668 25.0787 24.668H77.9639L89.3035 24.789C91.2856 24.81 93.0226 26.2937 93.1947 28.2773C93.2051 28.3877 93.2103 28.4982 93.2103 28.614L93.2051 28.6192Z" stroke="#222222" stroke-width="3" stroke-miterlimit="10"/>
<path d="M48.665 38.6689V49.8177" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M43.877 41.457L53.4483 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M53.4483 41.457L43.877 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M32.5166 38.6689V49.8177" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M27.7285 41.457L37.2999 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M37.2999 41.457L27.7285 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M64.9658 38.6689V49.8177" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M60.1777 41.457L69.7491 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M69.7491 41.457L60.1777 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M81.0518 38.6689V49.8177" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M76.2686 41.457L85.84 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M85.84 41.457L76.2686 47.0288" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M21.1565 50.8068V56.1681C11.9085 54.3214 4.21483 47.3396 1.69028 37.6902C1.62247 37.4272 1.78417 37.1589 2.04497 37.0957L6.15519 36.0855C6.40556 36.0224 6.65071 36.175 6.71852 36.4275C8.64845 43.6987 14.2818 49.0548 21.1565 50.8068V50.8068Z" stroke="#222222" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M50.6117 24.6681H45.2027C43.93 20.8221 41.541 17.4443 38.2654 14.9504C33.9778 11.6883 28.6888 10.2941 23.3684 11.0412C23.045 11.0886 22.7164 11.1412 22.3983 11.2043L26.4146 16.0711L11.5333 17.0076C11.0534 17.0339 10.6831 16.5867 10.803 16.1131L14.5273 1.68652L18.7105 6.74268C19.9885 6.34282 21.3081 6.05344 22.6538 5.86403C29.346 4.92751 36.0016 6.67428 41.3898 10.7781C45.9747 14.2822 49.1877 19.1384 50.6117 24.6734V24.6681Z" stroke="#222222" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_5372_11232">
<rect width="99" height="70" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -1 +1 @@
Subproject commit 4bffa40cb60ad3d98cf0ea5b5d819f3f4895dcd6 Subproject commit 8e3afd002968d21a3de788569356587a70818022

View file

@ -8,6 +8,7 @@ import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_libmonero/monero/monero.dart'; import 'package:flutter_libmonero/monero/monero.dart';
import 'package:flutter_libmonero/wownero/wownero.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
@ -84,7 +85,6 @@ void main() async {
appDirectory = (await getLibraryDirectory()); appDirectory = (await getLibraryDirectory());
} }
// FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
await Hive.initFlutter(appDirectory.path);
if (!(Logging.isArmLinux || Logging.isTestEnv)) { if (!(Logging.isArmLinux || Logging.isTestEnv)) {
final isar = await Isar.open( final isar = await Isar.open(
[LogSchema], [LogSchema],
@ -128,11 +128,14 @@ void main() async {
Hive.registerAdapter(NodeAdapter()); Hive.registerAdapter(NodeAdapter());
Hive.registerAdapter(WalletInfoAdapter()); if (!Hive.isAdapterRegistered(WalletInfoAdapter().typeId)) {
Hive.registerAdapter(WalletInfoAdapter());
}
Hive.registerAdapter(WalletTypeAdapter()); Hive.registerAdapter(WalletTypeAdapter());
Hive.registerAdapter(UnspentCoinsInfoAdapter()); Hive.registerAdapter(UnspentCoinsInfoAdapter());
await Hive.initFlutter(appDirectory.path);
await Hive.openBox<dynamic>(DB.boxNameDBInfo); await Hive.openBox<dynamic>(DB.boxNameDBInfo);
int dbVersion = DB.instance.get<dynamic>( int dbVersion = DB.instance.get<dynamic>(
@ -143,6 +146,7 @@ void main() async {
} }
monero.onStartup(); monero.onStartup();
wownero.onStartup();
await Hive.openBox<dynamic>(DB.boxNameTheme); await Hive.openBox<dynamic>(DB.boxNameTheme);

View file

@ -37,9 +37,11 @@ class CreateOrRestoreWalletView extends StatelessWidget {
body: SizedBox( body: SizedBox(
width: 480, width: 480,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
const Spacer(
flex: 10,
),
CreateRestoreWalletTitle( CreateRestoreWalletTitle(
coin: coin, coin: coin,
isDesktop: isDesktop, isDesktop: isDesktop,
@ -67,6 +69,9 @@ class CreateOrRestoreWalletView extends StatelessWidget {
coin: coin, coin: coin,
isDesktop: isDesktop, isDesktop: isDesktop,
), ),
const Spacer(
flex: 15,
),
], ],
), ),
), ),

View file

@ -151,6 +151,10 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
crossAxisAlignment: crossAxisAlignment:
isDesktop ? CrossAxisAlignment.center : CrossAxisAlignment.stretch, isDesktop ? CrossAxisAlignment.center : CrossAxisAlignment.stretch,
children: [ children: [
if (isDesktop)
const Spacer(
flex: 10,
),
if (!isDesktop) if (!isDesktop)
const Spacer( const Spacer(
flex: 1, flex: 1,
@ -163,7 +167,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
height: 100, height: 100,
), ),
SizedBox( SizedBox(
height: isDesktop ? 24 : 16, height: isDesktop ? 0 : 16,
), ),
Text( Text(
"Name your ${coin.prettyName} wallet", "Name your ${coin.prettyName} wallet",
@ -358,6 +362,10 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
), ),
), ),
), ),
if (isDesktop)
const Spacer(
flex: 15,
),
], ],
); );
} }

View file

@ -90,224 +90,233 @@ class _NewWalletRecoveryPhraseViewState
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
return WillPopScope( return WillPopScope(
onWillPop: onWillPop, onWillPop: onWillPop,
child: MasterScaffold( child: MasterScaffold(
isDesktop: isDesktop, isDesktop: isDesktop,
appBar: isDesktop appBar: isDesktop
? DesktopAppBar( ? DesktopAppBar(
isCompactHeight: false, isCompactHeight: false,
leading: AppBarBackButton( leading: AppBarBackButton(
onPressed: () async { onPressed: () async {
await delete(); await delete();
if (mounted) { if (mounted) {
Navigator.of(context).popUntil( Navigator.of(context).popUntil(
ModalRoute.withName( ModalRoute.withName(
NewWalletRecoveryPhraseWarningView.routeName, NewWalletRecoveryPhraseWarningView.routeName,
), ),
); );
} }
// Navigator.of(context).pop(); // Navigator.of(context).pop();
}, },
), ),
trailing: ExitToMyStackButton( trailing: ExitToMyStackButton(
onPressed: () async { onPressed: () async {
await delete(); await delete();
if (mounted) { if (mounted) {
Navigator.of(context).popUntil( Navigator.of(context).popUntil(
ModalRoute.withName(DesktopHomeView.routeName), ModalRoute.withName(DesktopHomeView.routeName),
); );
} }
}, },
), ),
) )
: AppBar( : AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
onPressed: () async { onPressed: () async {
await delete(); await delete();
if (mounted) { if (mounted) {
Navigator.of(context).popUntil( Navigator.of(context).popUntil(
ModalRoute.withName( ModalRoute.withName(
NewWalletRecoveryPhraseWarningView.routeName, NewWalletRecoveryPhraseWarningView.routeName,
), ),
); );
} }
}, },
), ),
actions: [ actions: [
Padding( Padding(
padding: const EdgeInsets.all(10), padding: const EdgeInsets.all(10),
child: AspectRatio( child: AspectRatio(
aspectRatio: 1, aspectRatio: 1,
child: AppBarIconButton( 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) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.background, .topNavIconPrimary,
shadows: const [],
icon: SvgPicture.asset(
Assets.svg.copy,
width: 24,
height: 24,
color: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: () async {
await _copy();
},
), ),
),
),
],
),
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
width: isDesktop ? 600 : null,
child: Padding(
padding: isDesktop
? const EdgeInsets.all(0)
: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (!isDesktop)
const SizedBox(
height: 4,
),
if (!isDesktop)
Text(
_manager.walletName,
textAlign: TextAlign.center,
style: STextStyles.label(context).copyWith(
fontSize: 12,
),
),
SizedBox(
height: isDesktop ? 24 : 4,
),
Text(
"Recovery Phrase",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 16,
),
Container(
decoration: BoxDecoration(
color: isDesktop
? Theme.of(context)
.extension<StackColors>()!
.background
: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius),
),
child: Padding(
padding: isDesktop
? const EdgeInsets.all(0)
: const EdgeInsets.all(12),
child: Text(
"Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopSubtitleH2(context)
: STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
),
SizedBox(
height: isDesktop ? 21 : 8,
),
if (!isDesktop)
Expanded(
child: SingleChildScrollView(
child: MnemonicTable(
words: _mnemonic,
isDesktop: isDesktop,
),
),
),
if (isDesktop)
MnemonicTable(
words: _mnemonic,
isDesktop: isDesktop,
),
SizedBox(
height: isDesktop ? 24 : 16,
),
if (isDesktop)
SizedBox(
height: 70,
child: TextButton(
onPressed: () async { onPressed: () async {
await _copy(); await _copy();
}, },
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.svg.copy,
width: 20,
height: 20,
),
const SizedBox(
width: 10,
),
Text(
"Copy to clipboard",
style: STextStyles.desktopButtonSecondaryEnabled(
context),
)
],
),
),
),
if (isDesktop)
const SizedBox(
height: 16,
),
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
),
child: TextButton(
onPressed: () async {
final int next = Random().nextInt(_mnemonic.length);
ref
.read(verifyMnemonicWordIndexStateProvider.state)
.update((state) => next);
ref
.read(verifyMnemonicCorrectWordStateProvider.state)
.update((state) => _mnemonic[next]);
unawaited(Navigator.of(context).pushNamed(
VerifyRecoveryPhraseView.routeName,
arguments: Tuple2(_manager, _mnemonic),
));
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"I saved my recovery phrase",
style: isDesktop
? STextStyles.desktopButtonEnabled(context)
: STextStyles.button(context),
), ),
), ),
), ),
], ],
), ),
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
width: isDesktop ? 600 : null,
child: Padding(
padding:
isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (isDesktop)
const Spacer(
flex: 10,
),
if (!isDesktop)
const SizedBox(
height: 4,
),
if (!isDesktop)
Text(
_manager.walletName,
textAlign: TextAlign.center,
style: STextStyles.label(context).copyWith(
fontSize: 12,
),
),
SizedBox(
height: isDesktop ? 24 : 4,
),
Text(
"Recovery Phrase",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 16,
),
Container(
decoration: BoxDecoration(
color: isDesktop
? Theme.of(context).extension<StackColors>()!.background
: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius),
),
child: Padding(
padding: isDesktop
? const EdgeInsets.all(0)
: const EdgeInsets.all(12),
child: Text(
"Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopSubtitleH2(context)
: STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
),
SizedBox(
height: isDesktop ? 21 : 8,
),
if (!isDesktop)
Expanded(
child: SingleChildScrollView(
child: MnemonicTable(
words: _mnemonic,
isDesktop: isDesktop,
),
),
),
if (isDesktop)
MnemonicTable(
words: _mnemonic,
isDesktop: isDesktop,
),
SizedBox(
height: isDesktop ? 24 : 16,
),
if (isDesktop)
SizedBox(
height: 70,
child: TextButton(
onPressed: () async {
await _copy();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.svg.copy,
width: 20,
height: 20,
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
const SizedBox(
width: 10,
),
Text(
"Copy to clipboard",
style: STextStyles.desktopButtonSecondaryEnabled(
context),
)
],
),
),
),
if (isDesktop)
const SizedBox(
height: 16,
),
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
),
child: TextButton(
onPressed: () async {
final int next = Random().nextInt(_mnemonic.length);
ref
.read(verifyMnemonicWordIndexStateProvider.state)
.update((state) => next);
ref
.read(verifyMnemonicCorrectWordStateProvider.state)
.update((state) => _mnemonic[next]);
unawaited(Navigator.of(context).pushNamed(
VerifyRecoveryPhraseView.routeName,
arguments: Tuple2(_manager, _mnemonic),
));
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"I saved my recovery phrase",
style: isDesktop
? STextStyles.desktopButtonEnabled(context)
: STextStyles.button(context),
),
),
),
if (isDesktop)
const Spacer(
flex: 15,
),
],
), ),
), ),
)); ),
),
);
} }
} }

View file

@ -59,7 +59,9 @@ class _NewWalletRecoveryPhraseWarningViewState
final _numberOfPhraseWords = coin == Coin.monero final _numberOfPhraseWords = coin == Coin.monero
? Constants.seedPhraseWordCountMonero ? Constants.seedPhraseWordCountMonero
: Constants.seedPhraseWordCountBip39; : coin == Coin.wownero
? 14
: Constants.seedPhraseWordCountBip39;
return MasterScaffold( return MasterScaffold(
isDesktop: isDesktop, isDesktop: isDesktop,
@ -79,9 +81,14 @@ class _NewWalletRecoveryPhraseWarningViewState
? CrossAxisAlignment.center ? CrossAxisAlignment.center
: CrossAxisAlignment.stretch, : CrossAxisAlignment.stretch,
children: [ children: [
const SizedBox( if (isDesktop)
height: 4, const Spacer(
), flex: 10,
),
if (!isDesktop)
const SizedBox(
height: 4,
),
if (!isDesktop) if (!isDesktop)
Text( Text(
walletName, walletName,
@ -90,9 +97,10 @@ class _NewWalletRecoveryPhraseWarningViewState
fontSize: 12, fontSize: 12,
), ),
), ),
const SizedBox( if (!isDesktop)
height: 4, const SizedBox(
), height: 4,
),
Text( Text(
"Recovery Phrase", "Recovery Phrase",
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -130,6 +138,7 @@ class _NewWalletRecoveryPhraseWarningViewState
builder: (_, ref, __) { builder: (_, ref, __) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [ children: [
GestureDetector( GestureDetector(
onTap: () { onTap: () {
@ -291,6 +300,10 @@ class _NewWalletRecoveryPhraseWarningViewState
}, },
), ),
), ),
if (isDesktop)
const Spacer(
flex: 15,
),
], ],
), ),
), ),

View file

@ -1,6 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart'; import 'package:stackwallet/widgets/stack_dialog.dart';
class ConfirmRecoveryDialog extends StatelessWidget { class ConfirmRecoveryDialog extends StatelessWidget {
@ -11,40 +18,94 @@ class ConfirmRecoveryDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return WillPopScope( if (Util.isDesktop) {
onWillPop: () async { return DesktopDialog(
return true; child: Column(
}, children: [
child: StackDialog( const DesktopDialogCloseButton(),
title: "Are you ready?", const SizedBox(
message: height: 5,
"Restoring your wallet may take a while. Please do not exit this screen once the process is started.", ),
leftButton: TextButton( SvgPicture.asset(
style: Theme.of(context) Assets.svg.drd,
.extension<StackColors>()! width: 99,
.getSecondaryEnabledButtonColor(context), height: 70,
child: Text( ),
"Cancel", const Spacer(),
style: STextStyles.itemSubtitle12(context), Text(
), "Restore wallet",
onPressed: () { style: STextStyles.desktopH2(context),
Navigator.of(context).pop(); textAlign: TextAlign.center,
}, ),
const SizedBox(
height: 16,
),
Text(
"Restoring your wallet may take a while.\nPlease do not exit this screen once the process is started.",
style: STextStyles.desktopTextMedium(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textDark3,
),
textAlign: TextAlign.center,
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
bottom: 32,
),
child: Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
onPressed: () {
Navigator.of(context).pop();
},
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Restore",
onPressed: () {
Navigator.of(context).pop();
onConfirm.call();
},
),
)
],
),
)
],
), ),
rightButton: TextButton( );
style: Theme.of(context) } else {
.extension<StackColors>()! return WillPopScope(
.getPrimaryEnabledButtonColor(context), onWillPop: () async {
child: Text( return true;
"Restore", },
style: STextStyles.button(context), child: StackDialog(
title: "Are you ready?",
message:
"Restoring your wallet may take a while. Please do not exit this screen once the process is started.",
leftButton: SecondaryButton(
label: "Cancel",
onPressed: () {
Navigator.of(context).pop();
},
),
rightButton: PrimaryButton(
label: "Restore",
onPressed: () {
Navigator.of(context).pop();
onConfirm.call();
},
), ),
onPressed: () {
Navigator.of(context).pop();
onConfirm.call();
},
), ),
), );
); }
} }
} }

View file

@ -10,6 +10,7 @@ import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_o
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_options_platform_layout.dart'; import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_options_platform_layout.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart'; import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/mnemonic_word_count_select_sheet.dart'; import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/mnemonic_word_count_select_sheet.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/ui/color_theme_provider.dart'; import 'package:stackwallet/providers/ui/color_theme_provider.dart';
import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart'; import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
@ -79,59 +80,30 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
colorArrowNext: Theme.of(context).extension<StackColors>()!.textSubtitle1, colorArrowNext: Theme.of(context).extension<StackColors>()!.textSubtitle1,
colorArrowPrevious: colorArrowPrevious:
Theme.of(context).extension<StackColors>()!.textSubtitle1, Theme.of(context).extension<StackColors>()!.textSubtitle1,
textStyleButtonNegative: GoogleFonts.inter( textStyleButtonNegative: STextStyles.datePicker600(context).copyWith(
color: baseColor, color: baseColor,
letterSpacing: 0.5,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleButtonPositive: GoogleFonts.inter( textStyleButtonPositive: STextStyles.datePicker600(context).copyWith(
color: baseColor, color: baseColor,
letterSpacing: 0.5,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleCurrentDayOnCalendar: GoogleFonts.inter( textStyleCurrentDayOnCalendar: STextStyles.datePicker400(context),
fontSize: 12, textStyleDayHeader: STextStyles.datePicker600(context),
fontWeight: FontWeight.w400, textStyleDayOnCalendar: STextStyles.datePicker400(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
),
textStyleDayHeader: GoogleFonts.inter(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleDayOnCalendar: GoogleFonts.inter(
color: baseColor, color: baseColor,
fontSize: 12,
fontWeight: FontWeight.w400,
letterSpacing: 0.5,
), ),
textStyleDayOnCalendarDisabled: GoogleFonts.inter( textStyleDayOnCalendarDisabled:
fontSize: 12, STextStyles.datePicker400(context).copyWith(
fontWeight: FontWeight.w400,
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.textSubtitle3, color: Theme.of(context).extension<StackColors>()!.textSubtitle3,
), ),
textStyleDayOnCalendarSelected: GoogleFonts.inter( textStyleDayOnCalendarSelected:
fontSize: 12, STextStyles.datePicker400(context).copyWith(
fontWeight: FontWeight.w400,
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.popupBG, color: Theme.of(context).extension<StackColors>()!.popupBG,
), ),
textStyleMonthYearHeader: GoogleFonts.inter( textStyleMonthYearHeader: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.textSubtitle1, color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleYearButton: GoogleFonts.inter( textStyleYearButton: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.textWhite, color: Theme.of(context).extension<StackColors>()!.textWhite,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleButtonAction: GoogleFonts.inter(), textStyleButtonAction: GoogleFonts.inter(),
); );
@ -139,16 +111,10 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
MaterialRoundedYearPickerStyle _buildYearPickerStyle() { MaterialRoundedYearPickerStyle _buildYearPickerStyle() {
return MaterialRoundedYearPickerStyle( return MaterialRoundedYearPickerStyle(
textStyleYear: GoogleFonts.inter( textStyleYear: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.textSubtitle2, color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
fontWeight: FontWeight.w600,
fontSize: 16,
), ),
textStyleYearSelected: GoogleFonts.inter( textStyleYearSelected: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
fontWeight: FontWeight.w600,
fontSize: 18, fontSize: 18,
), ),
); );
@ -232,11 +198,13 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
final lengths = Constants.possibleLengthsForCoin(coin).toList(); final lengths = Constants.possibleLengthsForCoin(coin).toList();
return DesktopScaffold( return MasterScaffold(
isDesktop: isDesktop,
appBar: isDesktop appBar: isDesktop
? const DesktopAppBar( ? const DesktopAppBar(
isCompactHeight: false, isCompactHeight: false,
leading: AppBarBackButton(), leading: AppBarBackButton(),
trailing: ExitToMyStackButton(),
) )
: AppBar( : AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
@ -260,10 +228,9 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
if (!isDesktop) Spacer(
const Spacer( flex: isDesktop ? 10 : 1,
flex: 1, ),
),
if (!isDesktop) if (!isDesktop)
Image( Image(
image: AssetImage( image: AssetImage(
@ -272,7 +239,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
height: 100, height: 100,
), ),
SizedBox( SizedBox(
height: isDesktop ? 24 : 16, height: isDesktop ? 0 : 16,
), ),
Text( Text(
"Restore options", "Restore options",
@ -417,6 +384,11 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
isDesktop: isDesktop, isDesktop: isDesktop,
onPressed: _nextEnabled ? nextPressed : null, onPressed: _nextEnabled ? nextPressed : null,
), ),
if (isDesktop)
const Spacer(
flex: 15,
),
], ],
), ),
), ),

View file

@ -17,6 +17,7 @@ import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widge
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart'; import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart';
import 'package:stackwallet/pages/home_view/home_view.dart'; import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart'; import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/coins/manager.dart'; import 'package:stackwallet/services/coins/manager.dart';
@ -36,8 +37,14 @@ import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.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/desktop/primary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
import 'package:stackwallet/widgets/table_view/table_view.dart';
import 'package:stackwallet/widgets/table_view/table_view_cell.dart';
import 'package:stackwallet/widgets/table_view/table_view_row.dart';
import 'package:wakelock/wakelock.dart'; import 'package:wakelock/wakelock.dart';
class RestoreWalletView extends ConsumerStatefulWidget { class RestoreWalletView extends ConsumerStatefulWidget {
@ -193,7 +200,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
// TODO: do actual check to make sure it is a valid mnemonic for monero // TODO: do actual check to make sure it is a valid mnemonic for monero
if (bip39.validateMnemonic(mnemonic) == false && if (bip39.validateMnemonic(mnemonic) == false &&
!(widget.coin == Coin.monero)) { !(widget.coin == Coin.monero || widget.coin == Coin.wownero)) {
unawaited(showFloatingFlushBar( unawaited(showFloatingFlushBar(
type: FlushBarType.warning, type: FlushBarType.warning,
message: "Invalid seed phrase!", message: "Invalid seed phrase!",
@ -404,6 +411,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
prefix, prefix,
style: STextStyles.fieldLabel(context).copyWith( style: STextStyles.fieldLabel(context).copyWith(
color: prefixColor, color: prefixColor,
fontSize: Util.isDesktop ? 16 : 14,
), ),
), ),
), ),
@ -412,7 +420,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
minWidth: 16, minWidth: 16,
minHeight: 16, minHeight: 16,
maxWidth: 36, maxWidth: 36,
maxHeight: 20, maxHeight: 32,
), ),
suffixIconConstraints: const BoxConstraints( suffixIconConstraints: const BoxConstraints(
minWidth: 16, minWidth: 16,
@ -529,193 +537,483 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( final isDesktop = Util.isDesktop;
appBar: AppBar( return MasterScaffold(
leading: AppBarBackButton( isDesktop: isDesktop,
onPressed: () async { appBar: isDesktop
if (FocusScope.of(context).hasFocus) { ? const DesktopAppBar(
FocusScope.of(context).unfocus(); isCompactHeight: false,
await Future<void>.delayed(const Duration(milliseconds: 50)); leading: AppBarBackButton(),
} trailing: ExitToMyStackButton(),
if (mounted) { )
Navigator.of(context).pop(); : AppBar(
} leading: AppBarBackButton(
}, onPressed: () async {
), if (FocusScope.of(context).hasFocus) {
actions: [ FocusScope.of(context).unfocus();
Padding( await Future<void>.delayed(
padding: const EdgeInsets.only( const Duration(milliseconds: 50));
top: 10, }
bottom: 10, if (mounted) {
right: 10, Navigator.of(context).pop();
), }
child: AspectRatio( },
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("restoreWalletViewQrCodeButton"),
size: 36,
shadows: const [],
color: Theme.of(context).extension<StackColors>()!.background,
icon: QrCodeIcon(
width: 20,
height: 20,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
onPressed: scanMnemonicQr,
), ),
), actions: [
), Padding(
Padding( padding: const EdgeInsets.only(
padding: const EdgeInsets.only( top: 10,
top: 10, bottom: 10,
bottom: 10, right: 10,
right: 10, ),
), child: AspectRatio(
child: AspectRatio( aspectRatio: 1,
aspectRatio: 1, child: AppBarIconButton(
child: AppBarIconButton( key: const Key("restoreWalletViewQrCodeButton"),
key: const Key("restoreWalletPasteButton"), size: 36,
size: 36, shadows: const [],
shadows: const [], color: Theme.of(context)
color: Theme.of(context).extension<StackColors>()!.background, .extension<StackColors>()!
icon: ClipboardIcon( .background,
width: 20, icon: QrCodeIcon(
height: 20, width: 20,
color: Theme.of(context) height: 20,
.extension<StackColors>()! color: Theme.of(context)
.accentColorDark, .extension<StackColors>()!
.accentColorDark,
),
onPressed: scanMnemonicQr,
),
),
), ),
onPressed: pasteMnemonic, Padding(
), padding: const EdgeInsets.only(
top: 10,
bottom: 10,
right: 10,
),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("restoreWalletPasteButton"),
size: 36,
shadows: const [],
color: Theme.of(context)
.extension<StackColors>()!
.background,
icon: ClipboardIcon(
width: 20,
height: 20,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
onPressed: pasteMnemonic,
),
),
),
],
), ),
),
],
),
body: Container( body: Container(
color: Theme.of(context).extension<StackColors>()!.background, color: Theme.of(context).extension<StackColors>()!.background,
child: Padding( child: Padding(
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(12.0),
child: Column( child: Column(
children: [ children: [
Text( if (isDesktop)
widget.walletName, const Spacer(
style: STextStyles.itemSubtitle(context), flex: 10,
), ),
const SizedBox( if (!isDesktop)
height: 4, Text(
widget.walletName,
style: STextStyles.itemSubtitle(context),
),
SizedBox(
height: isDesktop ? 0 : 4,
), ),
Text( Text(
"Recovery phrase", "Recovery phrase",
style: STextStyles.pageTitleH1(context), style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
), ),
const SizedBox( SizedBox(
height: 8, height: isDesktop ? 16 : 8,
), ),
Text( Text(
"Enter your $_seedWordCount-word recovery phrase.", "Enter your $_seedWordCount-word recovery phrase.",
style: STextStyles.subtitle(context), style: isDesktop
? STextStyles.desktopSubtitleH2(context)
: STextStyles.subtitle(context),
), ),
const SizedBox( SizedBox(
height: 10, height: isDesktop ? 16 : 10,
), ),
Expanded( if (isDesktop)
child: SingleChildScrollView( Row(
controller: controller, mainAxisAlignment: MainAxisAlignment.center,
child: Padding( children: [
padding: const EdgeInsets.all(4.0), TextButton(
child: Form( onPressed: pasteMnemonic,
key: _formKey, child: Padding(
child: Column( padding: const EdgeInsets.symmetric(
crossAxisAlignment: CrossAxisAlignment.stretch, horizontal: 16.0,
vertical: 12,
),
child: Row(
children: [
SvgPicture.asset(
Assets.svg.clipboard,
width: 22,
height: 22,
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
const SizedBox(
width: 8,
),
Text(
"Paste",
style: STextStyles
.desktopButtonSmallSecondaryEnabled(context),
)
],
),
),
),
],
),
if (isDesktop)
const SizedBox(
height: 20,
),
if (isDesktop)
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 1008,
),
child: Builder(
builder: (BuildContext context) {
const cols = 4;
final int rows = _seedWordCount ~/ cols;
final int remainder = _seedWordCount % cols;
return Column(
children: [ children: [
for (int i = 1; i <= _seedWordCount; i++) Form(
Column( key: _formKey,
children: [ child: TableView(
Padding( shrinkWrap: true,
padding: rowSpacing: 20,
const EdgeInsets.symmetric(vertical: 4), rows: [
child: TextFormField( for (int i = 0; i < rows; i++)
textCapitalization: TextCapitalization.none, TableViewRow(
key: Key("restoreMnemonicFormField_$i"), crossAxisAlignment:
decoration: _getInputDecorationFor( CrossAxisAlignment.start,
_inputStatuses[i - 1], "$i"), spacing: 16,
autovalidateMode: cells: [
AutovalidateMode.onUserInteraction, for (int j = 1; j <= cols; j++)
selectionControls: TableViewCell(
i == 1 ? textSelectionControls : null, flex: 1,
onChanged: (value) { child: Column(
if (value.isEmpty) { children: [
setState(() { TextFormField(
_inputStatuses[i - 1] = textCapitalization:
FormInputStatus.empty; TextCapitalization.none,
}); key: Key(
} else if (_isValidMnemonicWord( "restoreMnemonicFormField_$i"),
value.trim().toLowerCase())) { decoration:
setState(() { _getInputDecorationFor(
_inputStatuses[i - 1] = _inputStatuses[
FormInputStatus.valid; i * 4 + j - 1],
}); "${i * 4 + j}"),
} else { autovalidateMode:
setState(() { AutovalidateMode
_inputStatuses[i - 1] = .onUserInteraction,
FormInputStatus.invalid; selectionControls:
}); i * 4 + j - 1 == 1
} ? textSelectionControls
}, : null,
controller: _controllers[i - 1], onChanged: (value) {
style: STextStyles.field(context).copyWith( if (value.isEmpty) {
color: Theme.of(context) setState(() {
.extension<StackColors>()! _inputStatuses[
.overlay, i * 4 + j - 1] =
), FormInputStatus.empty;
), });
), } else if (_isValidMnemonicWord(
if (_inputStatuses[i - 1] == value
FormInputStatus.invalid) .trim()
Align( .toLowerCase())) {
alignment: Alignment.topLeft, setState(() {
child: Padding( _inputStatuses[
padding: const EdgeInsets.only( i * 4 + j - 1] =
left: 12.0, FormInputStatus.valid;
bottom: 4.0, });
), } else {
child: Text( setState(() {
"Please check spelling", _inputStatuses[
textAlign: TextAlign.left, i * 4 + j - 1] =
style: FormInputStatus
STextStyles.label(context).copyWith( .invalid;
color: Theme.of(context) });
.extension<StackColors>()! }
.textError, },
controller:
_controllers[i * 4 + j - 1],
style:
STextStyles.field(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.overlay,
fontSize: isDesktop ? 16 : 14,
),
),
if (_inputStatuses[
i * 4 + j - 1] ==
FormInputStatus.invalid)
Align(
alignment: Alignment.topLeft,
child: Padding(
padding:
const EdgeInsets.only(
left: 12.0,
bottom: 4.0,
),
child: Text(
"Please check spelling",
textAlign: TextAlign.left,
style: STextStyles.label(
context)
.copyWith(
color: Theme.of(context)
.extension<
StackColors>()!
.textError,
),
),
),
)
],
),
), ),
), ],
), expandingChild: null,
) ),
if (remainder > 0)
TableViewRow(
spacing: 16,
cells: [
for (int i = rows * cols;
i < _seedWordCount;
i++) ...[
TableViewCell(
flex: 1,
child: Column(
children: [
TextFormField(
textCapitalization:
TextCapitalization.none,
key: Key(
"restoreMnemonicFormField_$i"),
decoration:
_getInputDecorationFor(
_inputStatuses[i],
"${i + 1}"),
autovalidateMode:
AutovalidateMode
.onUserInteraction,
selectionControls: i == 1
? textSelectionControls
: null,
onChanged: (value) {
if (value.isEmpty) {
setState(() {
_inputStatuses[i] =
FormInputStatus.empty;
});
} else if (_isValidMnemonicWord(
value
.trim()
.toLowerCase())) {
setState(() {
_inputStatuses[i] =
FormInputStatus.valid;
});
} else {
setState(() {
_inputStatuses[i] =
FormInputStatus
.invalid;
});
}
},
controller: _controllers[i],
style:
STextStyles.field(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.overlay,
fontSize: isDesktop ? 16 : 14,
),
),
if (_inputStatuses[i] ==
FormInputStatus.invalid)
Align(
alignment: Alignment.topLeft,
child: Padding(
padding:
const EdgeInsets.only(
left: 12.0,
bottom: 4.0,
),
child: Text(
"Please check spelling",
textAlign: TextAlign.left,
style: STextStyles.label(
context)
.copyWith(
color: Theme.of(context)
.extension<
StackColors>()!
.textError,
),
),
),
)
],
),
),
],
for (int i = remainder;
i < cols;
i++) ...[
TableViewCell(
flex: 1,
child: Container(),
),
],
],
expandingChild: null,
),
], ],
), ),
Padding( ),
padding: const EdgeInsets.only( const SizedBox(
top: 8.0, height: 32,
), ),
child: TextButton( PrimaryButton(
style: Theme.of(context) label: "Restore wallet",
.extension<StackColors>()! width: 480,
.getPrimaryEnabledButtonColor(context), onPressed: requestRestore,
onPressed: requestRestore,
child: Text(
"Restore",
style: STextStyles.button(context),
),
),
), ),
], ],
);
},
),
),
if (isDesktop)
const Spacer(
flex: 15,
),
if (!isDesktop)
Expanded(
child: SingleChildScrollView(
controller: controller,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
for (int i = 1; i <= _seedWordCount; i++)
Column(
children: [
Padding(
padding:
const EdgeInsets.symmetric(vertical: 4),
child: TextFormField(
textCapitalization:
TextCapitalization.none,
key: Key("restoreMnemonicFormField_$i"),
decoration: _getInputDecorationFor(
_inputStatuses[i - 1], "$i"),
autovalidateMode:
AutovalidateMode.onUserInteraction,
selectionControls:
i == 1 ? textSelectionControls : null,
onChanged: (value) {
if (value.isEmpty) {
setState(() {
_inputStatuses[i - 1] =
FormInputStatus.empty;
});
} else if (_isValidMnemonicWord(
value.trim().toLowerCase())) {
setState(() {
_inputStatuses[i - 1] =
FormInputStatus.valid;
});
} else {
setState(() {
_inputStatuses[i - 1] =
FormInputStatus.invalid;
});
}
},
controller: _controllers[i - 1],
style:
STextStyles.field(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.overlay,
fontSize: isDesktop ? 16 : 14,
),
),
),
if (_inputStatuses[i - 1] ==
FormInputStatus.invalid)
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(
left: 12.0,
bottom: 4.0,
),
child: Text(
"Please check spelling",
textAlign: TextAlign.left,
style: STextStyles.label(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textError,
),
),
),
)
],
),
Padding(
padding: const EdgeInsets.only(
top: 8.0,
),
child: PrimaryButton(
onPressed: requestRestore,
label: "Restore",
),
),
],
),
), ),
), ),
), ),
), ),
),
], ],
), ),
), ),

View file

@ -3,6 +3,10 @@ import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart'; import 'package:stackwallet/widgets/stack_dialog.dart';
class RestoreSucceededDialog extends StatelessWidget { class RestoreSucceededDialog extends StatelessWidget {
@ -10,27 +14,82 @@ class RestoreSucceededDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StackDialog( if (Util.isDesktop) {
title: "Wallet restored", return DesktopDialog(
message: "You can use your wallet now.", child: Column(
icon: SvgPicture.asset( children: [
Assets.svg.checkCircle, const DesktopDialogCloseButton(),
width: 24, const Spacer(
height: 24, flex: 1,
color: Theme.of(context).extension<StackColors>()!.accentColorGreen, ),
), SvgPicture.asset(
rightButton: TextButton( Assets.svg.checkCircle,
style: Theme.of(context) width: 40,
.extension<StackColors>()! height: 40,
.getSecondaryEnabledButtonColor(context), color:
child: Text( Theme.of(context).extension<StackColors>()!.accentColorDark,
"Ok", ),
style: STextStyles.itemSubtitle12(context), const Spacer(
flex: 2,
),
Text(
"Wallet restored",
style: STextStyles.desktopH2(context),
textAlign: TextAlign.center,
),
const SizedBox(
height: 16,
),
Text(
"You can use your wallet now.",
style: STextStyles.desktopTextMedium(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textDark3,
),
textAlign: TextAlign.center,
),
const Spacer(
flex: 2,
),
Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
bottom: 32,
),
child: PrimaryButton(
width: 272.5,
label: "OK",
onPressed: () {
Navigator.of(context).pop();
},
),
),
],
), ),
onPressed: () { );
Navigator.of(context).pop(); } else {
}, return StackDialog(
), title: "Wallet restored",
); message: "You can use your wallet now.",
icon: SvgPicture.asset(
Assets.svg.checkCircle,
width: 24,
height: 24,
color: Theme.of(context).extension<StackColors>()!.accentColorGreen,
),
rightButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Ok",
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
Navigator.of(context).pop();
},
),
);
}
} }
} }

View file

@ -3,6 +3,10 @@ import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart'; import 'package:stackwallet/widgets/stack_dialog.dart';
class RestoringDialog extends StatefulWidget { class RestoringDialog extends StatefulWidget {
@ -50,37 +54,105 @@ class _RestoringDialogState extends State<RestoringDialog>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return WillPopScope( if (Util.isDesktop) {
onWillPop: () async { return DesktopDialog(
return false; child: Column(
}, children: [
child: StackDialog( DesktopDialogCloseButton(
title: "Restoring wallet", onPressedOverride: () async {
message: "This may take a while. Please do not exit this screen.", await onCancel.call();
icon: RotationTransition( if (mounted) {
turns: _spinAnimation, Navigator.of(context).pop();
child: SvgPicture.asset(Assets.svg.arrowRotate3, }
width: 24, },
height: 24, ),
color: const Spacer(
Theme.of(context).extension<StackColors>()!.accentColorDark), flex: 1,
),
RotationTransition(
turns: _spinAnimation,
child: SvgPicture.asset(Assets.svg.arrowRotate3,
width: 40,
height: 40,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
const Spacer(
flex: 2,
),
Text(
"Restoring wallet...",
style: STextStyles.desktopH2(context),
textAlign: TextAlign.center,
),
const SizedBox(
height: 16,
),
Text(
"Restoring your wallet may take a while.\nPlease do not exit this screen.",
style: STextStyles.desktopTextMedium(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textDark3,
),
textAlign: TextAlign.center,
),
const Spacer(
flex: 2,
),
Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
bottom: 32,
),
child: SecondaryButton(
label: "Cancel",
width: 272.5,
onPressed: () async {
await onCancel.call();
if (mounted) {
Navigator.of(context).pop();
}
},
),
),
],
), ),
rightButton: TextButton( );
style: Theme.of(context) } else {
.extension<StackColors>()! return WillPopScope(
.getSecondaryEnabledButtonColor(context), onWillPop: () async {
child: Text( return false;
"Cancel", },
style: STextStyles.itemSubtitle12(context), child: StackDialog(
title: "Restoring wallet",
message: "This may take a while. Please do not exit this screen.",
icon: RotationTransition(
turns: _spinAnimation,
child: SvgPicture.asset(Assets.svg.arrowRotate3,
width: 24,
height: 24,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
rightButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12(context),
),
onPressed: () async {
await onCancel.call();
if (mounted) {
Navigator.of(context).pop();
}
},
), ),
onPressed: () async {
await onCancel.call();
if (mounted) {
Navigator.of(context).pop();
}
},
), ),
), );
); }
} }
} }

View file

@ -56,10 +56,23 @@ class WordTableItem extends ConsumerWidget {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: isDesktop style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith( ? STextStyles.desktopTextExtraSmall(context).copyWith(
color: color: selectedWord == word
Theme.of(context).extension<StackColors>()!.textDark, ? Theme.of(context)
.extension<StackColors>()!
.textSelectedWordTableItem
: Theme.of(context)
.extension<StackColors>()!
.textDark,
) )
: STextStyles.baseXS(context), : STextStyles.baseXS(context).copyWith(
color: selectedWord == word
? Theme.of(context)
.extension<StackColors>()!
.textSelectedWordTableItem
: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
), ),
], ],
), ),

View file

@ -236,6 +236,10 @@ class _VerifyRecoveryPhraseViewState
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if (isDesktop)
const Spacer(
flex: 10,
),
SizedBox( SizedBox(
height: isDesktop ? 24 : 4, height: isDesktop ? 24 : 4,
), ),
@ -349,6 +353,10 @@ class _VerifyRecoveryPhraseViewState
), ),
], ],
), ),
if (isDesktop)
const Spacer(
flex: 15,
),
], ],
), ),
), ),

View file

@ -85,7 +85,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
height: 8, height: 8,
), ),
Text( Text(
"You need to send ${amount.toStringAsFixed(coin == Coin.monero ? 12 : 8)} ${coin.ticker}", "You need to send ${amount.toStringAsFixed(coin == Coin.monero ? Constants.satsPerCoinMonero : coin == Coin.wownero ? Constants.satsPerCoinWownero : Constants.satsPerCoin)} ${coin.ticker}",
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
const SizedBox( const SizedBox(
@ -307,7 +307,11 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
"${Format.localizedStringAsFixed( "${Format.localizedStringAsFixed(
value: snapshot.data!, value: snapshot.data!,
locale: locale, locale: locale,
decimalPlaces: coin == Coin.monero ? 12 : 8, decimalPlaces: coin == Coin.monero
? Constants.satsPerCoinMonero
: coin == Coin.wownero
? Constants.satsPerCoinWownero
: Constants.satsPerCoin,
)} ${coin.ticker}", )} ${coin.ticker}",
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
); );

View file

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
enum StepIndicatorStatus { current, completed, incomplete } enum StepIndicatorStatus { current, completed, incomplete }
@ -39,9 +39,7 @@ class StepIndicator extends StatelessWidget {
case StepIndicatorStatus.current: case StepIndicatorStatus.current:
return Text( return Text(
step.toString(), step.toString(),
style: GoogleFonts.roboto( style: STextStyles.stepIndicator(context).copyWith(
fontWeight: FontWeight.w600,
fontSize: 8,
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.stepIndicatorIconNumber, .stepIndicatorIconNumber,
@ -57,9 +55,7 @@ class StepIndicator extends StatelessWidget {
case StepIndicatorStatus.incomplete: case StepIndicatorStatus.incomplete:
return Text( return Text(
step.toString(), step.toString(),
style: GoogleFonts.roboto( style: STextStyles.stepIndicator(context).copyWith(
fontWeight: FontWeight.w600,
fontSize: 8,
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.stepIndicatorIconInactive, .stepIndicatorIconInactive,

View file

@ -4,7 +4,10 @@ import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.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/managed_favorite.dart'; import 'package:stackwallet/widgets/managed_favorite.dart';
class ManageFavoritesView extends StatelessWidget { class ManageFavoritesView extends StatelessWidget {
@ -15,142 +18,306 @@ class ManageFavoritesView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
return Scaffold(
appBar: AppBar( final isDesktop = Util.isDesktop;
title: Text(
"Favorite wallets", return MasterScaffold(
style: STextStyles.navBarTitle(context), isDesktop: isDesktop,
), appBar: isDesktop
leading: AppBarBackButton( ? DesktopAppBar(
onPressed: () { background: Theme.of(context).extension<StackColors>()!.popupBG,
Navigator.of(context).pop(); isCompactHeight: true,
}, leading: const AppBarBackButton(
), isCompact: true,
), ),
body: Container( center: Expanded(
color: Theme.of(context).extension<StackColors>()!.background, child: Text(
child: Padding( "Favorite wallets",
padding: const EdgeInsets.only( style: STextStyles.desktopH3(context),
left: 12,
right: 12,
top: 4,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
"Drag to change wallet order.",
style: STextStyles.label(context),
),
),
), ),
), ),
const SizedBox( )
height: 8, : AppBar(
title: Text(
"Favorite wallets",
style: STextStyles.navBarTitle(context),
), ),
Expanded( leading: AppBarBackButton(
child: Consumer( onPressed: () {
builder: (_, ref, __) { Navigator.of(context).pop();
final favorites = ref.watch(favoritesProvider); },
return ReorderableListView.builder( ),
key: key, ),
itemCount: favorites.length, body: isDesktop
itemBuilder: (builderContext, index) { ? Consumer(
final walletId = ref.read(favorites[index]).walletId; builder: (_, ref, __) {
return Padding( final favorites = ref.watch(favoritesProvider);
key: Key( final nonFavorites = ref.watch(nonFavoritesProvider);
"manageFavoriteWalletsItem_$walletId",
),
padding: const EdgeInsets.all(4.0),
child: ManagedFavorite(
walletId: walletId,
),
);
},
onReorder: (oldIndex, newIndex) {
ref
.read(walletsServiceChangeNotifierProvider)
.moveFavorite(
fromIndex: oldIndex, toIndex: newIndex);
ref return Column(
.read(favoritesProvider) children: [
.reorder(oldIndex, newIndex, true); const SizedBox(
}, height: 24,
proxyDecorator: (child, index, animation) { ),
return Material( Expanded(
elevation: 15, child: ListView(
color: Colors.transparent, children: [
// shadowColor: Colors.red, Padding(
shape: RoundedRectangleBorder( padding: const EdgeInsets.symmetric(horizontal: 24),
borderRadius: BorderRadius.all( child: Container(
Radius.circular( decoration: BoxDecoration(
Constants.size.circularBorderRadius * 1.5, color: Theme.of(context)
.extension<StackColors>()!
.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
"Drag to change wallet order.",
style:
STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
), ),
), ),
), ),
child: child, const SizedBox(
); height: 5,
}, ),
); ReorderableListView.builder(
}, buildDefaultDragHandles: false,
), shrinkWrap: true,
), primary: false,
Padding( key: key,
padding: const EdgeInsets.only( itemCount: favorites.length,
top: 30, itemBuilder: (builderContext, index) {
bottom: 12, final walletId =
left: 4, ref.read(favorites[index]).walletId;
right: 4, return Padding(
), key: Key(
child: Text( "manageFavoriteWalletsItem_$walletId",
"Add to favorites", ),
style: STextStyles.itemSubtitle12(context).copyWith( padding: const EdgeInsets.symmetric(
color: vertical: 5,
Theme.of(context).extension<StackColors>()!.textDark3, horizontal: 24,
), ),
), child: ReorderableDelayedDragStartListener(
), index: index,
Expanded( child: ManagedFavorite(
child: Consumer( walletId: walletId,
builder: (_, ref, __) { ),
final nonFavorites = ref.watch(nonFavoritesProvider); ),
);
},
onReorder: (oldIndex, newIndex) {
ref
.read(walletsServiceChangeNotifierProvider)
.moveFavorite(
fromIndex: oldIndex, toIndex: newIndex);
return ListView.builder( ref
itemCount: nonFavorites.length, .read(favoritesProvider)
itemBuilder: (buildContext, index) { .reorder(oldIndex, newIndex, true);
// final walletId = ref.watch( },
// nonFavorites[index].select((value) => value.walletId)); proxyDecorator: (child, index, animation) {
final walletId = ref.read(nonFavorites[index]).walletId; return Material(
return Padding( elevation: 15,
key: Key( color: Colors.transparent,
"manageNonFavoriteWalletsItem_$walletId", // shadowColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(
Constants.size.circularBorderRadius * 1.5,
),
),
),
child: child,
);
},
), ),
padding: const EdgeInsets.all(4.0), Padding(
child: ManagedFavorite( padding: const EdgeInsets.only(
walletId: walletId, top: 32,
bottom: 11,
left: 24,
right: 24,
),
child: Text(
"Add to favorites",
style:
STextStyles.itemSubtitle12(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
), ),
); ListView.builder(
}, shrinkWrap: true,
); primary: false,
}, itemCount: nonFavorites.length,
itemBuilder: (buildContext, index) {
// final walletId = ref.watch(
// nonFavorites[index].select((value) => value.walletId));
final walletId =
ref.read(nonFavorites[index]).walletId;
return Padding(
key: Key(
"manageNonFavoriteWalletsItem_$walletId",
),
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 5,
),
child: ManagedFavorite(
walletId: walletId,
),
);
},
)
],
),
),
],
);
},
)
: Container(
color: Theme.of(context).extension<StackColors>()!.background,
child: Padding(
padding: const EdgeInsets.only(
left: 12,
right: 12,
top: 4,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
"Drag to change wallet order.",
style: STextStyles.label(context),
),
),
),
),
const SizedBox(
height: 8,
),
Expanded(
child: Consumer(
builder: (_, ref, __) {
final favorites = ref.watch(favoritesProvider);
return ReorderableListView.builder(
key: key,
itemCount: favorites.length,
itemBuilder: (builderContext, index) {
final walletId =
ref.read(favorites[index]).walletId;
return Padding(
key: Key(
"manageFavoriteWalletsItem_$walletId",
),
padding: const EdgeInsets.all(4.0),
child: ManagedFavorite(
walletId: walletId,
),
);
},
onReorder: (oldIndex, newIndex) {
ref
.read(walletsServiceChangeNotifierProvider)
.moveFavorite(
fromIndex: oldIndex, toIndex: newIndex);
ref
.read(favoritesProvider)
.reorder(oldIndex, newIndex, true);
},
proxyDecorator: (child, index, animation) {
return Material(
elevation: 15,
color: Colors.transparent,
// shadowColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(
Constants.size.circularBorderRadius * 1.5,
),
),
),
child: child,
);
},
);
},
),
),
Padding(
padding: const EdgeInsets.only(
top: 30,
bottom: 12,
left: 4,
right: 4,
),
child: Text(
"Add to favorites",
style: STextStyles.itemSubtitle12(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
),
Expanded(
child: Consumer(
builder: (_, ref, __) {
final nonFavorites = ref.watch(nonFavoritesProvider);
return ListView.builder(
itemCount: nonFavorites.length,
itemBuilder: (buildContext, index) {
// final walletId = ref.watch(
// nonFavorites[index].select((value) => value.walletId));
final walletId =
ref.read(nonFavorites[index]).walletId;
return Padding(
key: Key(
"manageNonFavoriteWalletsItem_$walletId",
),
padding: const EdgeInsets.all(4.0),
child: ManagedFavorite(
walletId: walletId,
),
);
},
);
},
),
),
],
), ),
), ),
], ),
),
),
),
); );
} }
} }

View file

@ -3,7 +3,6 @@ import 'dart:io';
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_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/home_view/home_view.dart'; import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/prefs_provider.dart';
@ -188,7 +187,10 @@ class _CreatePinViewState extends ConsumerState<CreatePinView> {
fieldsCount: Constants.pinLength, fieldsCount: Constants.pinLength,
eachFieldHeight: 12, eachFieldHeight: 12,
eachFieldWidth: 12, eachFieldWidth: 12,
textStyle: GoogleFonts.workSans( textStyle: STextStyles.infoSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle3,
fontSize: 1, fontSize: 1,
), ),
focusNode: _pinPutFocusNode2, focusNode: _pinPutFocusNode2,

View file

@ -90,6 +90,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
break; break;
case Coin.monero: case Coin.monero:
case Coin.wownero:
try { try {
final uri = Uri.parse(formData.host!); final uri = Uri.parse(formData.host!);
if (uri.scheme.startsWith("http")) { if (uri.scheme.startsWith("http")) {
@ -113,12 +114,12 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
break; break;
case Coin.bitcoin: case Coin.bitcoin:
// case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.dogecoin: case Coin.dogecoin:
case Coin.firo: case Coin.firo:
case Coin.namecoin: case Coin.namecoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.firoTestNet: case Coin.firoTestNet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
final client = ElectrumX( final client = ElectrumX(
@ -384,6 +385,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
// strip unused path // strip unused path
String address = formData.host!; String address = formData.host!;
if (coin == Coin.monero || if (coin == Coin.monero ||
coin == Coin.wownero ||
coin == Coin.epicCash) { coin == Coin.epicCash) {
if (address.startsWith("http")) { if (address.startsWith("http")) {
final uri = Uri.parse(address); final uri = Uri.parse(address);
@ -530,15 +532,16 @@ class _NodeFormState extends ConsumerState<NodeForm> {
case Coin.dogecoin: case Coin.dogecoin:
case Coin.firo: case Coin.firo:
case Coin.namecoin: case Coin.namecoin:
// case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.firoTestNet: case Coin.firoTestNet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
return false; return false;
case Coin.epicCash: case Coin.epicCash:
case Coin.monero: case Coin.monero:
case Coin.wownero:
return true; return true;
} }
} }
@ -699,7 +702,9 @@ class _NodeFormState extends ConsumerState<NodeForm> {
focusNode: _hostFocusNode, focusNode: _hostFocusNode,
style: STextStyles.field(context), style: STextStyles.field(context),
decoration: standardInputDecoration( decoration: standardInputDecoration(
(widget.coin != Coin.monero && widget.coin != Coin.epicCash) (widget.coin != Coin.monero &&
widget.coin != Coin.wownero &&
widget.coin != Coin.epicCash)
? "IP address" ? "IP address"
: "Url", : "Url",
_hostFocusNode, _hostFocusNode,
@ -880,7 +885,9 @@ class _NodeFormState extends ConsumerState<NodeForm> {
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
if (widget.coin != Coin.monero && widget.coin != Coin.epicCash) if (widget.coin != Coin.monero &&
widget.coin != Coin.wownero &&
widget.coin != Coin.epicCash)
Row( Row(
children: [ children: [
GestureDetector( GestureDetector(
@ -931,11 +938,15 @@ class _NodeFormState extends ConsumerState<NodeForm> {
), ),
], ],
), ),
if (widget.coin != Coin.monero && widget.coin != Coin.epicCash) if (widget.coin != Coin.monero &&
widget.coin != Coin.wownero &&
widget.coin != Coin.epicCash)
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
if (widget.coin != Coin.monero && widget.coin != Coin.epicCash) if (widget.coin != Coin.monero &&
widget.coin != Coin.wownero &&
widget.coin != Coin.epicCash)
Row( Row(
children: [ children: [
GestureDetector( GestureDetector(

View file

@ -81,6 +81,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
break; break;
case Coin.monero: case Coin.monero:
case Coin.wownero:
try { try {
final uri = Uri.parse(node!.host); final uri = Uri.parse(node!.host);
if (uri.scheme.startsWith("http")) { if (uri.scheme.startsWith("http")) {
@ -102,9 +103,9 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
case Coin.firoTestNet: case Coin.firoTestNet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
// case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.namecoin: case Coin.namecoin:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
final client = ElectrumX( final client = ElectrumX(
host: node!.host, host: node!.host,
port: node.port, port: node.port,

View file

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/security_views/security_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/security_views/security_view.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
@ -168,7 +167,10 @@ class _ChangePinViewState extends State<ChangePinView> {
fieldsCount: Constants.pinLength, fieldsCount: Constants.pinLength,
eachFieldHeight: 12, eachFieldHeight: 12,
eachFieldWidth: 12, eachFieldWidth: 12,
textStyle: GoogleFonts.workSans( textStyle: STextStyles.infoSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle3,
fontSize: 1, fontSize: 1,
), ),
focusNode: _pinPutFocusNode2, focusNode: _pinPutFocusNode2,

View file

@ -12,6 +12,7 @@ import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_net
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'; import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
import 'package:stackwallet/services/coins/monero/monero_wallet.dart'; import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
import 'package:stackwallet/services/event_bus/events/global/blocks_remaining_event.dart'; import 'package:stackwallet/services/event_bus/events/global/blocks_remaining_event.dart';
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart';
@ -205,7 +206,7 @@ class _WalletNetworkSettingsViewState
.getManager(widget.walletId) .getManager(widget.walletId)
.coin; .coin;
if (coin == Coin.monero || coin == Coin.epicCash) { if (coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash) {
_blocksRemainingSubscription = eventBus.on<BlocksRemainingEvent>().listen( _blocksRemainingSubscription = eventBus.on<BlocksRemainingEvent>().listen(
(event) async { (event) async {
if (event.walletId == widget.walletId) { if (event.walletId == widget.walletId) {
@ -271,6 +272,15 @@ class _WalletNetworkSettingsViewState
if (_percent < highestPercent) { if (_percent < highestPercent) {
_percent = highestPercent.clamp(0.0, 1.0); _percent = highestPercent.clamp(0.0, 1.0);
} }
} else if (coin == Coin.wownero) {
double highestPercent = (ref
.read(walletsChangeNotifierProvider)
.getManager(widget.walletId)
.wallet as WowneroWallet)
.highestPercentCached;
if (_percent < highestPercent) {
_percent = highestPercent.clamp(0.0, 1.0);
}
} else if (coin == Coin.epicCash) { } else if (coin == Coin.epicCash) {
double highestPercent = (ref double highestPercent = (ref
.read(walletsChangeNotifierProvider) .read(walletsChangeNotifierProvider)
@ -545,6 +555,7 @@ class _WalletNetworkSettingsViewState
), ),
), ),
if (coin == Coin.monero || if (coin == Coin.monero ||
coin == Coin.wownero ||
coin == Coin.epicCash) coin == Coin.epicCash)
Text( Text(
" (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})", " (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",

View file

@ -241,7 +241,9 @@ class _TransactionDetailsViewState
"$amountPrefix${Format.localizedStringAsFixed( "$amountPrefix${Format.localizedStringAsFixed(
value: coin == Coin.monero value: coin == Coin.monero
? (amount / 10000.toDecimal()).toDecimal() ? (amount / 10000.toDecimal()).toDecimal()
: amount, : coin == Coin.wownero
? (amount / 1000.toDecimal()).toDecimal()
: amount,
locale: ref.watch( locale: ref.watch(
localeServiceChangeNotifierProvider localeServiceChangeNotifierProvider
.select((value) => value.locale), .select((value) => value.locale),
@ -254,7 +256,7 @@ class _TransactionDetailsViewState
height: 2, height: 2,
), ),
SelectableText( SelectableText(
"${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch( "${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
localeServiceChangeNotifierProvider localeServiceChangeNotifierProvider
.select((value) => value.locale), .select((value) => value.locale),
), decimalPlaces: 2)} ${ref.watch( ), decimalPlaces: 2)} ${ref.watch(
@ -298,14 +300,14 @@ class _TransactionDetailsViewState
], ],
), ),
), ),
if (!(coin == Coin.monero && if (!((coin == Coin.monero || coin == Coin.wownero) &&
_transaction.txType.toLowerCase() == "sent") && _transaction.txType.toLowerCase() == "sent") &&
!((coin == Coin.firo || coin == Coin.firoTestNet) && !((coin == Coin.firo || coin == Coin.firoTestNet) &&
_transaction.subType == "mint")) _transaction.subType == "mint"))
const SizedBox( const SizedBox(
height: 12, height: 12,
), ),
if (!(coin == Coin.monero && if (!((coin == Coin.monero || coin == Coin.wownero) &&
_transaction.txType.toLowerCase() == "sent") && _transaction.txType.toLowerCase() == "sent") &&
!((coin == Coin.firo || coin == Coin.firoTestNet) && !((coin == Coin.firo || coin == Coin.firoTestNet) &&
_transaction.subType == "mint")) _transaction.subType == "mint"))
@ -464,7 +466,10 @@ class _TransactionDetailsViewState
? Format.localizedStringAsFixed( ? Format.localizedStringAsFixed(
value: coin == Coin.monero value: coin == Coin.monero
? (fee / 10000.toDecimal()).toDecimal() ? (fee / 10000.toDecimal()).toDecimal()
: fee, : coin == Coin.wownero
? (fee / 1000.toDecimal())
.toDecimal()
: fee,
locale: ref.watch( locale: ref.watch(
localeServiceChangeNotifierProvider localeServiceChangeNotifierProvider
.select((value) => value.locale)), .select((value) => value.locale)),
@ -473,7 +478,9 @@ class _TransactionDetailsViewState
: Format.localizedStringAsFixed( : Format.localizedStringAsFixed(
value: coin == Coin.monero value: coin == Coin.monero
? (fee / 10000.toDecimal()).toDecimal() ? (fee / 10000.toDecimal()).toDecimal()
: fee, : coin == Coin.wownero
? (fee / 1000.toDecimal()).toDecimal()
: fee,
locale: ref.watch( locale: ref.watch(
localeServiceChangeNotifierProvider localeServiceChangeNotifierProvider
.select((value) => value.locale)), .select((value) => value.locale)),

View file

@ -4,7 +4,6 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_rounded_date_picker/flutter_rounded_date_picker.dart'; import 'package:flutter_rounded_date_picker/flutter_rounded_date_picker.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:stackwallet/models/transaction_filter.dart'; import 'package:stackwallet/models/transaction_filter.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/ui/color_theme_provider.dart'; import 'package:stackwallet/providers/ui/color_theme_provider.dart';
@ -122,77 +121,43 @@ class _TransactionSearchViewState
colorArrowNext: Theme.of(context).extension<StackColors>()!.textSubtitle1, colorArrowNext: Theme.of(context).extension<StackColors>()!.textSubtitle1,
colorArrowPrevious: colorArrowPrevious:
Theme.of(context).extension<StackColors>()!.textSubtitle1, Theme.of(context).extension<StackColors>()!.textSubtitle1,
textStyleButtonNegative: GoogleFonts.inter( textStyleButtonNegative: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: baseColor, color: baseColor,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleButtonPositive: GoogleFonts.inter( textStyleButtonPositive: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: baseColor, color: baseColor,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleCurrentDayOnCalendar: GoogleFonts.inter( textStyleCurrentDayOnCalendar: STextStyles.datePicker400(context),
letterSpacing: 0.5, textStyleDayHeader: STextStyles.datePicker600(context),
color: Theme.of(context).extension<StackColors>()!.accentColorDark, textStyleDayOnCalendar: STextStyles.datePicker400(context).copyWith(
fontWeight: FontWeight.w400,
fontSize: 12,
),
textStyleDayHeader: GoogleFonts.inter(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleDayOnCalendar: GoogleFonts.inter(
letterSpacing: 0.5,
color: baseColor, color: baseColor,
fontSize: 12,
fontWeight: FontWeight.w400,
), ),
textStyleDayOnCalendarDisabled: GoogleFonts.inter( textStyleDayOnCalendarDisabled:
letterSpacing: 0.5, STextStyles.datePicker400(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textSubtitle3, color: Theme.of(context).extension<StackColors>()!.textSubtitle3,
fontWeight: FontWeight.w400,
fontSize: 12,
), ),
textStyleDayOnCalendarSelected: GoogleFonts.inter( textStyleDayOnCalendarSelected:
letterSpacing: 0.5, STextStyles.datePicker400(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textWhite, color: Theme.of(context).extension<StackColors>()!.textWhite,
fontWeight: FontWeight.w400,
fontSize: 12,
), ),
textStyleMonthYearHeader: GoogleFonts.inter( textStyleMonthYearHeader: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.textSubtitle1, color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleYearButton: GoogleFonts.inter( textStyleYearButton: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.textWhite, color: Theme.of(context).extension<StackColors>()!.textWhite,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
textStyleButtonAction: GoogleFonts.inter(), // textStyleButtonAction: GoogleFonts.inter(),
); );
} }
MaterialRoundedYearPickerStyle _buildYearPickerStyle() { MaterialRoundedYearPickerStyle _buildYearPickerStyle() {
return MaterialRoundedYearPickerStyle( return MaterialRoundedYearPickerStyle(
backgroundPicker: Theme.of(context).extension<StackColors>()!.popupBG, backgroundPicker: Theme.of(context).extension<StackColors>()!.popupBG,
textStyleYear: GoogleFonts.inter( textStyleYear: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.textSubtitle2, color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
fontWeight: FontWeight.w600,
fontSize: 16, fontSize: 16,
), ),
textStyleYearSelected: GoogleFonts.inter( textStyleYearSelected: STextStyles.datePicker600(context).copyWith(
letterSpacing: 0.5,
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
fontWeight: FontWeight.w600,
fontSize: 18, fontSize: 18,
), ),
); );
@ -790,6 +755,11 @@ class _TransactionSearchViewState
.floor() .floor()
.toBigInt() .toBigInt()
.toInt(); .toInt();
} else if (widget.coin == Coin.wownero) {
amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinWownero))
.floor()
.toBigInt()
.toInt();
} else { } else {
amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoin)) amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoin))
.floor() .floor()

View file

@ -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:stackwallet/pages_desktop_specific/home/desktop_menu.dart'; import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart'; import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
class DesktopHomeView extends ConsumerStatefulWidget { class DesktopHomeView extends ConsumerStatefulWidget {
@ -16,12 +17,9 @@ class DesktopHomeView extends ConsumerStatefulWidget {
class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> { class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
int currentViewIndex = 0; int currentViewIndex = 0;
final List<Widget> contentViews = [ final List<Widget> contentViews = [
// const Navigator( const Navigator(
// onGenerateRoute: RouteGenerator.generateRoute, onGenerateRoute: RouteGenerator.generateRoute,
// initialRoute: MyStackView.routeName, initialRoute: MyStackView.routeName,
// ),
const MyStackView(
key: Key("myStackViewKey"),
), ),
Container( Container(
color: Colors.green, color: Colors.green,

View file

@ -0,0 +1,137 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/manage_favorites_view/manage_favorites_view.dart';
import 'package:stackwallet/pages/wallets_view/sub_widgets/favorite_card.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
class DesktopFavoriteWallets extends ConsumerWidget {
const DesktopFavoriteWallets({Key? key}) : super(key: key);
static const cardWidth = 220.0;
static const cardHeight = 125.0;
static const standardPadding = 16.0;
@override
Widget build(BuildContext context, WidgetRef ref) {
debugPrint("BUILD: $runtimeType");
final favorites = ref.watch(favoritesProvider);
bool hasFavorites = favorites.length > 0;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Favorite wallets",
style: STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconRight,
),
),
BlueTextButton(
text: "Edit",
onTap: () {
Navigator.of(context).pushNamed(ManageFavoritesView.routeName);
},
),
],
),
const SizedBox(
height: 20,
),
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: (cardHeight * 2) + standardPadding,
minHeight: cardHeight,
),
child: hasFavorites
? SingleChildScrollView(
primary: false,
child: Wrap(
spacing: 16,
runSpacing: 16,
children: [
...favorites.map((p0) {
final walletId = ref.read(p0).walletId;
final managerProvider = ref
.read(walletsChangeNotifierProvider)
.getManagerProvider(walletId);
return FavoriteCard(
walletId: walletId,
width: cardWidth,
height: cardHeight,
managerProvider: managerProvider,
);
})
],
),
)
: Container(
height: cardHeight,
width: cardWidth,
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: MaterialButton(
splashColor:
Theme.of(context).extension<StackColors>()!.highlight,
key: const Key("favoriteWalletsAddFavoriteButtonKey"),
padding: const EdgeInsets.all(12),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius),
),
onPressed: () {
Navigator.of(context)
.pushNamed(ManageFavoritesView.routeName);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.svg.plus,
width: 14,
height: 14,
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
const SizedBox(
width: 4,
),
Text(
"Add a favorite",
style: STextStyles.itemSubtitle(context).copyWith(
fontSize: 18,
),
),
],
),
),
),
),
const SizedBox(
height: 40,
),
],
);
}
}

View file

@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/pages/wallets_view/sub_widgets/empty_wallets.dart'; import 'package:stackwallet/pages/wallets_view/sub_widgets/empty_wallets.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_wallets.dart'; import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_wallets.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
@ -24,9 +23,6 @@ class _MyStackViewState extends ConsumerState<MyStackView> {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
final hasWallets = ref.watch(walletsChangeNotifierProvider).hasWallets; final hasWallets = ref.watch(walletsChangeNotifierProvider).hasWallets;
final showFavorites = ref.watch(prefsChangeNotifierProvider
.select((value) => value.showFavoriteWallets));
return Column( return Column(
children: [ children: [
DesktopAppBar( DesktopAppBar(

View file

@ -1,46 +1,32 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart'; import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/desktop_favorite_wallets.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_summary_table.dart'; import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_summary_table.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
class MyWallets extends StatefulWidget { class MyWallets extends ConsumerStatefulWidget {
const MyWallets({Key? key}) : super(key: key); const MyWallets({Key? key}) : super(key: key);
@override @override
State<MyWallets> createState() => _MyWalletsState(); ConsumerState<MyWallets> createState() => _MyWalletsState();
} }
class _MyWalletsState extends State<MyWallets> { class _MyWalletsState extends ConsumerState<MyWallets> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final showFavorites = ref.watch(prefsChangeNotifierProvider
.select((value) => value.showFavoriteWallets));
return Padding( return Padding(
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( if (showFavorites) const DesktopFavoriteWallets(),
"Favorite wallets",
style: STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconRight,
),
),
const SizedBox(
height: 20,
),
// TODO favorites grid
Container(
color: Colors.deepPurpleAccent,
height: 210,
),
const SizedBox(
height: 40,
),
Row( Row(
children: [ children: [
Text( Text(
@ -55,12 +41,14 @@ class _MyWalletsState extends State<MyWallets> {
BlueTextButton( BlueTextButton(
text: "Add new wallet", text: "Add new wallet",
onTap: () { onTap: () {
Navigator.of(context).pushNamed(AddWalletView.routeName); Navigator.of(
context,
rootNavigator: true,
).pushNamed(AddWalletView.routeName);
}, },
), ),
], ],
), ),
const SizedBox( const SizedBox(
height: 20, height: 20,
), ),

File diff suppressed because it is too large Load diff

View file

@ -4,10 +4,12 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart';
import 'package:stackwallet/models/models.dart'; import 'package:stackwallet/models/models.dart';
import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart'; import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart';
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart';
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'; import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/services/coins/monero/monero_wallet.dart'; import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'; import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -98,25 +100,25 @@ abstract class CoinServiceAPI {
tracker: tracker, tracker: tracker,
); );
// case Coin.bitcoincash: case Coin.bitcoincash:
// return BitcoinCashWallet( return BitcoinCashWallet(
// walletId: walletId, walletId: walletId,
// walletName: walletName, walletName: walletName,
// coin: coin, coin: coin,
// client: client, client: client,
// cachedClient: cachedClient, cachedClient: cachedClient,
// tracker: tracker, tracker: tracker,
// ); );
//
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return BitcoinCashWallet( return BitcoinCashWallet(
// walletId: walletId, walletId: walletId,
// walletName: walletName, walletName: walletName,
// coin: coin, coin: coin,
// client: client, client: client,
// cachedClient: cachedClient, cachedClient: cachedClient,
// tracker: tracker, tracker: tracker,
// ); );
case Coin.dogecoin: case Coin.dogecoin:
return DogecoinWallet( return DogecoinWallet(
@ -144,6 +146,14 @@ abstract class CoinServiceAPI {
// tracker: tracker, // tracker: tracker,
); );
case Coin.wownero:
return WowneroWallet(
walletId: walletId,
walletName: walletName,
coin: coin,
// tracker: tracker,
);
case Coin.namecoin: case Coin.namecoin:
return NamecoinWallet( return NamecoinWallet(
walletId: walletId, walletId: walletId,

View file

@ -2443,7 +2443,11 @@ class NamecoinWallet extends CoinServiceAPI {
for (final out in tx["vout"] as List) { for (final out in tx["vout"] as List) {
if (prevOut == out["n"]) { if (prevOut == out["n"]) {
final address = out["scriptPubKey"]["addresses"][0] as String?; String? address = out["scriptPubKey"]["address"] as String?;
if (address == null && out["scriptPubKey"]["addresses"] != null) {
address = out["scriptPubKey"]["addresses"][0] as String?;
}
if (address != null) { if (address != null) {
sendersArray.add(address); sendersArray.add(address);
} }
@ -2454,7 +2458,10 @@ class NamecoinWallet extends CoinServiceAPI {
Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info); Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info);
for (final output in txObject["vout"] as List) { for (final output in txObject["vout"] as List) {
final address = output["scriptPubKey"]["addresses"][0] as String?; String? address = output["scriptPubKey"]["address"] as String?;
if (address == null && output["scriptPubKey"]["addresses"] != null) {
address = output["scriptPubKey"]["addresses"][0] as String?;
}
if (address != null) { if (address != null) {
recipientsArray.add(address); recipientsArray.add(address);
} }
@ -2519,7 +2526,10 @@ class NamecoinWallet extends CoinServiceAPI {
// add up received tx value // add up received tx value
for (final output in txObject["vout"] as List) { for (final output in txObject["vout"] as List) {
final address = output["scriptPubKey"]["addresses"][0]; String? address = output["scriptPubKey"]["address"] as String?;
if (address == null && output["scriptPubKey"]["addresses"] != null) {
address = output["scriptPubKey"]["addresses"][0] as String?;
}
if (address != null) { if (address != null) {
final value = (Decimal.parse(output["value"].toString()) * final value = (Decimal.parse(output["value"].toString()) *
Decimal.fromInt(Constants.satsPerCoin)) Decimal.fromInt(Constants.satsPerCoin))

File diff suppressed because it is too large Load diff

View file

@ -79,8 +79,7 @@ class PriceAPI {
Map<Coin, Tuple2<Decimal, double>> result = {}; Map<Coin, Tuple2<Decimal, double>> result = {};
try { try {
final uri = Uri.parse( final uri = Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"); "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false");
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false");
// final uri = Uri.parse( // final uri = Uri.parse(
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero%2Cbitcoin%2Cepic-cash%2Czcoin%2Cdogecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"); // "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero%2Cbitcoin%2Cepic-cash%2Czcoin%2Cdogecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false");

View file

@ -223,7 +223,7 @@ class Wallets extends ChangeNotifier {
final shouldSetAutoSync = shouldAutoSyncAll || final shouldSetAutoSync = shouldAutoSyncAll ||
walletIdsToEnableAutoSync.contains(manager.walletId); walletIdsToEnableAutoSync.contains(manager.walletId);
if (manager.coin == Coin.monero) { if (manager.coin == Coin.monero || manager.coin == Coin.wownero) {
walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync)); walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
} else { } else {
walletInitFutures.add(manager.initializeExisting().then((value) { walletInitFutures.add(manager.initializeExisting().then((value) {
@ -312,7 +312,7 @@ class Wallets extends ChangeNotifier {
final shouldSetAutoSync = shouldAutoSyncAll || final shouldSetAutoSync = shouldAutoSyncAll ||
walletIdsToEnableAutoSync.contains(manager.walletId); walletIdsToEnableAutoSync.contains(manager.walletId);
if (manager.coin == Coin.monero) { if (manager.coin == Coin.monero || manager.coin == Coin.wownero) {
walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync)); walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
} else { } else {
walletInitFutures.add(manager.initializeExisting().then((value) { walletInitFutures.add(manager.initializeExisting().then((value) {

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_libmonero/monero/monero.dart'; import 'package:flutter_libmonero/monero/monero.dart';
import 'package:flutter_libmonero/wownero/wownero.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'; import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
@ -367,8 +368,13 @@ class WalletsService extends ChangeNotifier {
await DB.instance.delete<dynamic>( await DB.instance.delete<dynamic>(
boxName: DB.boxNameAllWalletsData, boxName: DB.boxNameAllWalletsData,
key: "${walletId}_mnemonicHasBeenVerified"); key: "${walletId}_mnemonicHasBeenVerified");
if (coinFromPrettyName(shell['coin'] as String) == Coin.wownero) {
if (coinFromPrettyName(shell['coin'] as String) == Coin.monero) { final wowService =
wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
await wowService.remove(walletId);
Logging.instance
.log("monero wallet: $walletId deleted", level: LogLevel.Info);
} else if (coinFromPrettyName(shell['coin'] as String) == Coin.monero) {
final xmrService = final xmrService =
monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox); monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
await xmrService.remove(walletId); await xmrService.remove(walletId);

View file

@ -3,7 +3,7 @@ import 'dart:convert';
import 'package:bitcoindart/bitcoindart.dart'; import 'package:bitcoindart/bitcoindart.dart';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:flutter_libepiccash/epic_cash.dart'; import 'package:flutter_libepiccash/epic_cash.dart';
// import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart';
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'; import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
@ -42,8 +42,8 @@ class AddressUtils {
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
return Address.validateAddress(address, bitcoin); return Address.validateAddress(address, bitcoin);
// case Coin.bitcoincash: case Coin.bitcoincash:
// return Address.validateAddress(address, bitcoincash); return Address.validateAddress(address, bitcoincash);
case Coin.dogecoin: case Coin.dogecoin:
return Address.validateAddress(address, dogecoin); return Address.validateAddress(address, dogecoin);
case Coin.epicCash: case Coin.epicCash:
@ -53,12 +53,15 @@ class AddressUtils {
case Coin.monero: case Coin.monero:
return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) || return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
RegExp("[a-zA-Z0-9]{106}").hasMatch(address); RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
case Coin.wownero:
return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
case Coin.namecoin: case Coin.namecoin:
return Address.validateAddress(address, namecoin, namecoin.bech32!); return Address.validateAddress(address, namecoin, namecoin.bech32!);
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return Address.validateAddress(address, testnet); return Address.validateAddress(address, testnet);
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return Address.validateAddress(address, bitcoincashtestnet); return Address.validateAddress(address, bitcoincashtestnet);
case Coin.firoTestNet: case Coin.firoTestNet:
return Address.validateAddress(address, firoTestNetwork); return Address.validateAddress(address, firoTestNetwork);
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:

View file

@ -51,6 +51,7 @@ class _SVG {
String txExchangeFailed(BuildContext context) => String txExchangeFailed(BuildContext context) =>
"assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg"; "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
String get drd => "assets/svg/drd-icon.svg";
String get plus => "assets/svg/plus.svg"; String get plus => "assets/svg/plus.svg";
String get gear => "assets/svg/gear.svg"; String get gear => "assets/svg/gear.svg";
String get bell => "assets/svg/bell.svg"; String get bell => "assets/svg/bell.svg";
@ -127,6 +128,7 @@ class _SVG {
String get epicCash => "assets/svg/coin_icons/EpicCash.svg"; String get epicCash => "assets/svg/coin_icons/EpicCash.svg";
String get firo => "assets/svg/coin_icons/Firo.svg"; String get firo => "assets/svg/coin_icons/Firo.svg";
String get monero => "assets/svg/coin_icons/Monero.svg"; String get monero => "assets/svg/coin_icons/Monero.svg";
String get wownero => "assets/svg/coin_icons/Wownero.svg";
String get namecoin => "assets/svg/coin_icons/Namecoin.svg"; String get namecoin => "assets/svg/coin_icons/Namecoin.svg";
String get chevronRight => "assets/svg/chevron-right.svg"; String get chevronRight => "assets/svg/chevron-right.svg";
@ -145,8 +147,8 @@ class _SVG {
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
return bitcoin; return bitcoin;
// case Coin.bitcoincash: case Coin.bitcoincash:
// return bitcoincash; return bitcoincash;
case Coin.dogecoin: case Coin.dogecoin:
return dogecoin; return dogecoin;
case Coin.epicCash: case Coin.epicCash:
@ -155,12 +157,14 @@ class _SVG {
return firo; return firo;
case Coin.monero: case Coin.monero:
return monero; return monero;
case Coin.wownero:
return wownero;
case Coin.namecoin: case Coin.namecoin:
return namecoin; return namecoin;
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return bitcoinTestnet; return bitcoinTestnet;
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return bitcoincashTestnet; return bitcoincashTestnet;
case Coin.firoTestNet: case Coin.firoTestNet:
return firoTestnet; return firoTestnet;
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
@ -176,6 +180,7 @@ class _PNG {
String get splash => "assets/images/splash.png"; String get splash => "assets/images/splash.png";
String get monero => "assets/images/monero.png"; String get monero => "assets/images/monero.png";
String get wownero => "assets/images/wownero.png";
String get firo => "assets/images/firo.png"; String get firo => "assets/images/firo.png";
String get dogecoin => "assets/images/doge.png"; String get dogecoin => "assets/images/doge.png";
String get bitcoin => "assets/images/bitcoin.png"; String get bitcoin => "assets/images/bitcoin.png";
@ -188,9 +193,9 @@ class _PNG {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return bitcoin; return bitcoin;
// case Coin.bitcoincash: case Coin.bitcoincash:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return bitcoincash; return bitcoincash;
case Coin.dogecoin: case Coin.dogecoin:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
return dogecoin; return dogecoin;
@ -202,6 +207,8 @@ class _PNG {
return firo; return firo;
case Coin.monero: case Coin.monero:
return monero; return monero;
case Coin.wownero:
return wownero;
case Coin.namecoin: case Coin.namecoin:
return namecoin; return namecoin;
} }

View file

@ -18,15 +18,17 @@ Uri getBlockExplorerTransactionUrlFor({
throw UnimplementedError("missing block explorer for epic cash"); throw UnimplementedError("missing block explorer for epic cash");
case Coin.monero: case Coin.monero:
return Uri.parse("https://xmrchain.net/tx/$txid"); return Uri.parse("https://xmrchain.net/tx/$txid");
case Coin.wownero:
return Uri.parse("https://explore.wownero.com/search?value=$txid");
case Coin.firo: case Coin.firo:
return Uri.parse("https://explorer.firo.org/tx/$txid"); return Uri.parse("https://explorer.firo.org/tx/$txid");
case Coin.firoTestNet: case Coin.firoTestNet:
return Uri.parse("https://testexplorer.firo.org/tx/$txid"); return Uri.parse("https://testexplorer.firo.org/tx/$txid");
// case Coin.bitcoincash: case Coin.bitcoincash:
// return Uri.parse("https://blockchair.com/bitcoin-cash/transaction/$txid"); return Uri.parse("https://blockchair.com/bitcoin-cash/transaction/$txid");
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return Uri.parse( return Uri.parse(
// "https://blockexplorer.one/bitcoin-cash/testnet/tx/$txid"); "https://blockexplorer.one/bitcoin-cash/testnet/tx/$txid");
case Coin.namecoin: case Coin.namecoin:
return Uri.parse("https://chainz.cryptoid.info/nmc/tx.dws?$txid.htm"); return Uri.parse("https://chainz.cryptoid.info/nmc/tx.dws?$txid.htm");
} }

View file

@ -18,6 +18,7 @@ abstract class Constants {
//TODO: correct for monero? //TODO: correct for monero?
static const int satsPerCoinMonero = 1000000000000; static const int satsPerCoinMonero = 1000000000000;
static const int satsPerCoinWownero = 100000000000;
static const int satsPerCoin = 100000000; static const int satsPerCoin = 100000000;
static const int decimalPlaces = 8; static const int decimalPlaces = 8;
@ -39,8 +40,8 @@ abstract class Constants {
final List<int> values = []; final List<int> values = [];
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
// case Coin.bitcoincash: case Coin.bitcoincash:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.dogecoin: case Coin.dogecoin:
case Coin.firo: case Coin.firo:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
@ -54,6 +55,9 @@ abstract class Constants {
case Coin.monero: case Coin.monero:
values.addAll([25]); values.addAll([25]);
break; break;
case Coin.wownero:
values.addAll([14]);
break;
} }
return values; return values;
} }
@ -65,9 +69,9 @@ abstract class Constants {
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return 600; return 600;
// case Coin.bitcoincash: case Coin.bitcoincash:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return 600; return 600;
case Coin.dogecoin: case Coin.dogecoin:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
@ -83,6 +87,9 @@ abstract class Constants {
case Coin.monero: case Coin.monero:
return 120; return 120;
case Coin.wownero:
return 120;
case Coin.namecoin: case Coin.namecoin:
return 600; return 600;
} }

View file

@ -13,10 +13,11 @@ abstract class DefaultNodes {
firo, firo,
monero, monero,
epicCash, epicCash,
// bitcoincash, bitcoincash,
namecoin, namecoin,
wownero,
bitcoinTestnet, bitcoinTestnet,
// bitcoincashTestnet, bitcoincashTestnet,
dogecoinTestnet, dogecoinTestnet,
firoTestnet, firoTestnet,
]; ];
@ -33,17 +34,17 @@ abstract class DefaultNodes {
isDown: false, isDown: false,
); );
// static NodeModel get bitcoincash => NodeModel( static NodeModel get bitcoincash => NodeModel(
// host: "bitcoincash.stackwallet.com", host: "bitcoincash.stackwallet.com",
// port: 50002, port: 50002,
// name: defaultName, name: defaultName,
// id: _nodeId(Coin.bitcoincash), id: _nodeId(Coin.bitcoincash),
// useSSL: true, useSSL: true,
// enabled: true, enabled: true,
// coinName: Coin.bitcoincash.name, coinName: Coin.bitcoincash.name,
// isFailover: true, isFailover: true,
// isDown: false, isDown: false,
// ); );
static NodeModel get dogecoin => NodeModel( static NodeModel get dogecoin => NodeModel(
host: "dogecoin.stackwallet.com", host: "dogecoin.stackwallet.com",
@ -83,6 +84,20 @@ abstract class DefaultNodes {
isDown: false, isDown: false,
); );
// TODO: eventually enable ssl and set scheme to https
// currently get certificate failure
static NodeModel get wownero => NodeModel(
host: "http://eu-west-2.wow.xmr.pm",
port: 34568,
name: defaultName,
id: _nodeId(Coin.wownero),
useSSL: false,
enabled: true,
coinName: Coin.wownero.name,
isFailover: true,
isDown: false,
);
static NodeModel get epicCash => NodeModel( static NodeModel get epicCash => NodeModel(
host: "http://epiccash.stackwallet.com", host: "http://epiccash.stackwallet.com",
port: 3413, port: 3413,
@ -143,25 +158,25 @@ abstract class DefaultNodes {
isDown: false, isDown: false,
); );
// static NodeModel get bitcoincashTestnet => NodeModel( static NodeModel get bitcoincashTestnet => NodeModel(
// host: "testnet.hsmiths.com", host: "testnet.hsmiths.com",
// port: 53012, port: 53012,
// name: defaultName, name: defaultName,
// id: _nodeId(Coin.bitcoincash), id: _nodeId(Coin.bitcoincashTestnet),
// useSSL: true, useSSL: true,
// enabled: true, enabled: true,
// coinName: Coin.bitcoincash.name, coinName: Coin.bitcoincashTestnet.name,
// isFailover: true, isFailover: true,
// isDown: false, isDown: false,
// ); );
static NodeModel getNodeFor(Coin coin) { static NodeModel getNodeFor(Coin coin) {
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
return bitcoin; return bitcoin;
//
// case Coin.bitcoincash: case Coin.bitcoincash:
// return bitcoincash; return bitcoincash;
case Coin.dogecoin: case Coin.dogecoin:
return dogecoin; return dogecoin;
@ -175,14 +190,17 @@ abstract class DefaultNodes {
case Coin.monero: case Coin.monero:
return monero; return monero;
case Coin.wownero:
return wownero;
case Coin.namecoin: case Coin.namecoin:
return namecoin; return namecoin;
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return bitcoinTestnet; return bitcoinTestnet;
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return bitcoincashTestnet; return bitcoincashTestnet;
case Coin.firoTestNet: case Coin.firoTestNet:
return firoTestnet; return firoTestnet;

View file

@ -1,4 +1,6 @@
import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as btc; import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as btc;
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'
as bch;
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart' import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
as doge; as doge;
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart' import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'
@ -7,14 +9,16 @@ import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as firo;
import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr; import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr;
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart' import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
as nmc; as nmc;
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart' as wow;
enum Coin { enum Coin {
bitcoin, bitcoin,
// bitcoincash, bitcoincash,
dogecoin, dogecoin,
epicCash, epicCash,
firo, firo,
monero, monero,
wownero,
namecoin, namecoin,
/// ///
@ -22,21 +26,21 @@ enum Coin {
/// ///
bitcoinTestNet, bitcoinTestNet,
// bitcoincashTestnet, bitcoincashTestnet,
dogecoinTestNet, dogecoinTestNet,
firoTestNet, firoTestNet,
} }
// remove firotestnet for now // remove firotestnet for now
const int kTestNetCoinCount = 2; const int kTestNetCoinCount = 3;
extension CoinExt on Coin { extension CoinExt on Coin {
String get prettyName { String get prettyName {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
return "Bitcoin"; return "Bitcoin";
// case Coin.bitcoincash: case Coin.bitcoincash:
// return "Bitcoin Cash"; return "Bitcoin Cash";
case Coin.dogecoin: case Coin.dogecoin:
return "Dogecoin"; return "Dogecoin";
case Coin.epicCash: case Coin.epicCash:
@ -45,12 +49,14 @@ extension CoinExt on Coin {
return "Firo"; return "Firo";
case Coin.monero: case Coin.monero:
return "Monero"; return "Monero";
case Coin.wownero:
return "Wownero";
case Coin.namecoin: case Coin.namecoin:
return "Namecoin"; return "Namecoin";
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return "tBitcoin"; return "tBitcoin";
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return "tBitcoin Cash"; return "tBitcoin Cash";
case Coin.firoTestNet: case Coin.firoTestNet:
return "tFiro"; return "tFiro";
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
@ -62,8 +68,8 @@ extension CoinExt on Coin {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
return "BTC"; return "BTC";
// case Coin.bitcoincash: case Coin.bitcoincash:
// return "BCH"; return "BCH";
case Coin.dogecoin: case Coin.dogecoin:
return "DOGE"; return "DOGE";
case Coin.epicCash: case Coin.epicCash:
@ -72,12 +78,14 @@ extension CoinExt on Coin {
return "FIRO"; return "FIRO";
case Coin.monero: case Coin.monero:
return "XMR"; return "XMR";
case Coin.wownero:
return "WOW";
case Coin.namecoin: case Coin.namecoin:
return "NMC"; return "NMC";
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return "tBTC"; return "tBTC";
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return "tBCH"; return "tBCH";
case Coin.firoTestNet: case Coin.firoTestNet:
return "tFIRO"; return "tFIRO";
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
@ -89,8 +97,8 @@ extension CoinExt on Coin {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
return "bitcoin"; return "bitcoin";
// case Coin.bitcoincash: case Coin.bitcoincash:
// return "bitcoincash"; return "bitcoincash";
case Coin.dogecoin: case Coin.dogecoin:
return "dogecoin"; return "dogecoin";
case Coin.epicCash: case Coin.epicCash:
@ -100,12 +108,14 @@ extension CoinExt on Coin {
return "firo"; return "firo";
case Coin.monero: case Coin.monero:
return "monero"; return "monero";
case Coin.wownero:
return "wownero";
case Coin.namecoin: case Coin.namecoin:
return "namecoin"; return "namecoin";
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return "bitcoin"; return "bitcoin";
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return "bitcoincash"; return "bitcoincash";
case Coin.firoTestNet: case Coin.firoTestNet:
return "firo"; return "firo";
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
@ -116,18 +126,19 @@ extension CoinExt on Coin {
bool get isElectrumXCoin { bool get isElectrumXCoin {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
// case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.dogecoin: case Coin.dogecoin:
case Coin.firo: case Coin.firo:
case Coin.namecoin: case Coin.namecoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.firoTestNet: case Coin.firoTestNet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
return true; return true;
case Coin.epicCash: case Coin.epicCash:
case Coin.monero: case Coin.monero:
case Coin.wownero:
return false; return false;
} }
} }
@ -138,9 +149,9 @@ extension CoinExt on Coin {
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return btc.MINIMUM_CONFIRMATIONS; return btc.MINIMUM_CONFIRMATIONS;
// case Coin.bitcoincash: case Coin.bitcoincash:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return bch.MINIMUM_CONFIRMATIONS; return bch.MINIMUM_CONFIRMATIONS;
case Coin.firo: case Coin.firo:
case Coin.firoTestNet: case Coin.firoTestNet:
@ -155,6 +166,10 @@ extension CoinExt on Coin {
case Coin.monero: case Coin.monero:
return xmr.MINIMUM_CONFIRMATIONS; return xmr.MINIMUM_CONFIRMATIONS;
case Coin.wownero:
return wow.MINIMUM_CONFIRMATIONS;
case Coin.namecoin: case Coin.namecoin:
return nmc.MINIMUM_CONFIRMATIONS; return nmc.MINIMUM_CONFIRMATIONS;
} }
@ -166,10 +181,10 @@ Coin coinFromPrettyName(String name) {
case "Bitcoin": case "Bitcoin":
case "bitcoin": case "bitcoin":
return Coin.bitcoin; return Coin.bitcoin;
// case "Bitcoincash": case "Bitcoincash":
// case "bitcoincash": case "bitcoincash":
// case "Bitcoin Cash": case "Bitcoin Cash":
// return Coin.bitcoincash; return Coin.bitcoincash;
case "Dogecoin": case "Dogecoin":
case "dogecoin": case "dogecoin":
return Coin.dogecoin; return Coin.dogecoin;
@ -190,10 +205,10 @@ Coin coinFromPrettyName(String name) {
case "bitcoinTestNet": case "bitcoinTestNet":
return Coin.bitcoinTestNet; return Coin.bitcoinTestNet;
// case "Bitcoincash Testnet": case "Bitcoincash Testnet":
// case "tBitcoin Cash": case "tBitcoin Cash":
// case "Bitcoin Cash Testnet": case "Bitcoin Cash Testnet":
// return Coin.bitcoincashTestnet; return Coin.bitcoincashTestnet;
case "Firo Testnet": case "Firo Testnet":
case "tFiro": case "tFiro":
case "firoTestNet": case "firoTestNet":
@ -202,6 +217,10 @@ Coin coinFromPrettyName(String name) {
case "tDogecoin": case "tDogecoin":
case "dogecoinTestNet": case "dogecoinTestNet":
return Coin.dogecoinTestNet; return Coin.dogecoinTestNet;
case "Wownero":
case "tWownero":
case "wownero":
return Coin.wownero;
default: default:
throw ArgumentError.value( throw ArgumentError.value(
name, "name", "No Coin enum value with that prettyName"); name, "name", "No Coin enum value with that prettyName");
@ -212,8 +231,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
switch (ticker.toLowerCase()) { switch (ticker.toLowerCase()) {
case "btc": case "btc":
return Coin.bitcoin; return Coin.bitcoin;
// case "bch": case "bch":
// return Coin.bitcoincash; return Coin.bitcoincash;
case "doge": case "doge":
return Coin.dogecoin; return Coin.dogecoin;
case "epic": case "epic":
@ -226,12 +245,14 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
return Coin.namecoin; return Coin.namecoin;
case "tbtc": case "tbtc":
return Coin.bitcoinTestNet; return Coin.bitcoinTestNet;
// case "tbch": case "tbch":
// return Coin.bitcoincashTestnet; return Coin.bitcoincashTestnet;
case "tfiro": case "tfiro":
return Coin.firoTestNet; return Coin.firoTestNet;
case "tdoge": case "tdoge":
return Coin.dogecoinTestNet; return Coin.dogecoinTestNet;
case "wow":
return Coin.wownero;
default: default:
throw ArgumentError.value( throw ArgumentError.value(
ticker, "name", "No Coin enum value with that ticker"); ticker, "name", "No Coin enum value with that ticker");

View file

@ -52,4 +52,8 @@ class ListenableList<T> extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
} }
Iterable<E> map<E>(E Function(T) toElement) {
return _list.map(toElement);
}
} }

File diff suppressed because it is too large Load diff

View file

@ -174,6 +174,7 @@ abstract class StackColorTheme {
Color get loadingOverlayTextColor; Color get loadingOverlayTextColor;
Color get myStackContactIconBG; Color get myStackContactIconBG;
Color get textConfirmTotalAmount; Color get textConfirmTotalAmount;
Color get textSelectedWordTableItem;
} }
class CoinThemeColor { class CoinThemeColor {
@ -193,9 +194,9 @@ class CoinThemeColor {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return bitcoin; return bitcoin;
// case Coin.bitcoincash: case Coin.bitcoincash:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return bitcoincash; return bitcoincash;
case Coin.dogecoin: case Coin.dogecoin:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
return dogecoin; return dogecoin;
@ -208,8 +209,8 @@ class CoinThemeColor {
return monero; return monero;
case Coin.namecoin: case Coin.namecoin:
return namecoin; return namecoin;
// case Coin.wownero: case Coin.wownero:
// return wownero; return wownero;
} }
} }
} }

View file

@ -301,4 +301,6 @@ class DarkColors extends StackColorTheme {
Color get myStackContactIconBG => const Color(0x88747778); Color get myStackContactIconBG => const Color(0x88747778);
@override @override
Color get textConfirmTotalAmount => const Color(0xFF003921); Color get textConfirmTotalAmount => const Color(0xFF003921);
@override
Color get textSelectedWordTableItem => const Color(0xFF00297A);
} }

View file

@ -301,4 +301,6 @@ class LightColors extends StackColorTheme {
Color get myStackContactIconBG => textFieldDefaultBG; Color get myStackContactIconBG => textFieldDefaultBG;
@override @override
Color get textConfirmTotalAmount => const Color(0xFF232323); Color get textConfirmTotalAmount => const Color(0xFF232323);
@override
Color get textSelectedWordTableItem => const Color(0xFF232323);
} }

View file

@ -169,6 +169,7 @@ class StackColors extends ThemeExtension<StackColors> {
final Color loadingOverlayTextColor; final Color loadingOverlayTextColor;
final Color myStackContactIconBG; final Color myStackContactIconBG;
final Color textConfirmTotalAmount; final Color textConfirmTotalAmount;
final Color textSelectedWordTableItem;
StackColors({ StackColors({
required this.themeType, required this.themeType,
@ -300,6 +301,7 @@ class StackColors extends ThemeExtension<StackColors> {
required this.loadingOverlayTextColor, required this.loadingOverlayTextColor,
required this.myStackContactIconBG, required this.myStackContactIconBG,
required this.textConfirmTotalAmount, required this.textConfirmTotalAmount,
required this.textSelectedWordTableItem,
}); });
factory StackColors.fromStackColorTheme(StackColorTheme colorTheme) { factory StackColors.fromStackColorTheme(StackColorTheme colorTheme) {
@ -435,6 +437,7 @@ class StackColors extends ThemeExtension<StackColors> {
loadingOverlayTextColor: colorTheme.loadingOverlayTextColor, loadingOverlayTextColor: colorTheme.loadingOverlayTextColor,
myStackContactIconBG: colorTheme.myStackContactIconBG, myStackContactIconBG: colorTheme.myStackContactIconBG,
textConfirmTotalAmount: colorTheme.textConfirmTotalAmount, textConfirmTotalAmount: colorTheme.textConfirmTotalAmount,
textSelectedWordTableItem: colorTheme.textSelectedWordTableItem,
); );
} }
@ -569,6 +572,7 @@ class StackColors extends ThemeExtension<StackColors> {
Color? loadingOverlayTextColor, Color? loadingOverlayTextColor,
Color? myStackContactIconBG, Color? myStackContactIconBG,
Color? textConfirmTotalAmount, Color? textConfirmTotalAmount,
Color? textSelectedWordTableItem,
}) { }) {
return StackColors( return StackColors(
themeType: themeType ?? this.themeType, themeType: themeType ?? this.themeType,
@ -736,6 +740,8 @@ class StackColors extends ThemeExtension<StackColors> {
myStackContactIconBG: myStackContactIconBG ?? this.myStackContactIconBG, myStackContactIconBG: myStackContactIconBG ?? this.myStackContactIconBG,
textConfirmTotalAmount: textConfirmTotalAmount:
textConfirmTotalAmount ?? this.textConfirmTotalAmount, textConfirmTotalAmount ?? this.textConfirmTotalAmount,
textSelectedWordTableItem:
textSelectedWordTableItem ?? this.textSelectedWordTableItem,
); );
} }
@ -1388,6 +1394,11 @@ class StackColors extends ThemeExtension<StackColors> {
other.textConfirmTotalAmount, other.textConfirmTotalAmount,
t, t,
)!, )!,
textSelectedWordTableItem: Color.lerp(
textSelectedWordTableItem,
other.textSelectedWordTableItem,
t,
)!,
); );
} }
@ -1396,9 +1407,9 @@ class StackColors extends ThemeExtension<StackColors> {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return _coin.bitcoin; return _coin.bitcoin;
// case Coin.bitcoincash: case Coin.bitcoincash:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
// return _coin.bitcoincash; return _coin.bitcoincash;
case Coin.dogecoin: case Coin.dogecoin:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
return _coin.dogecoin; return _coin.dogecoin;
@ -1411,8 +1422,8 @@ class StackColors extends ThemeExtension<StackColors> {
return _coin.monero; return _coin.monero;
case Coin.namecoin: case Coin.namecoin:
return _coin.namecoin; return _coin.namecoin;
// case Coin.wownero: case Coin.wownero:
// return wownero; return _coin.wownero;
} }
} }
@ -1463,6 +1474,13 @@ class StackColors extends ThemeExtension<StackColors> {
), ),
); );
ButtonStyle? getSecondaryDisabledButtonColor(BuildContext context) =>
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
buttonBackSecondaryDisabled,
),
);
ButtonStyle? getSmallSecondaryEnabledButtonColor(BuildContext context) => ButtonStyle? getSmallSecondaryEnabledButtonColor(BuildContext context) =>
Theme.of(context).textButtonTheme.style?.copyWith( Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>( backgroundColor: MaterialStateProperty.all<Color>(

View file

@ -47,9 +47,14 @@ class AppBarIconButton extends StatelessWidget {
} }
class AppBarBackButton extends StatelessWidget { class AppBarBackButton extends StatelessWidget {
const AppBarBackButton({Key? key, this.onPressed}) : super(key: key); const AppBarBackButton({
Key? key,
this.onPressed,
this.isCompact = false,
}) : super(key: key);
final VoidCallback? onPressed; final VoidCallback? onPressed;
final bool isCompact;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -62,15 +67,19 @@ class AppBarBackButton extends StatelessWidget {
) )
: const EdgeInsets.all(10), : const EdgeInsets.all(10),
child: AppBarIconButton( child: AppBarIconButton(
size: isDesktop ? 56 : 32, size: isDesktop
? isCompact
? 42
: 56
: 32,
color: isDesktop color: isDesktop
? Theme.of(context).extension<StackColors>()!.textFieldDefaultBG ? Theme.of(context).extension<StackColors>()!.textFieldDefaultBG
: Theme.of(context).extension<StackColors>()!.background, : Theme.of(context).extension<StackColors>()!.background,
shadows: const [], shadows: const [],
icon: SvgPicture.asset( icon: SvgPicture.asset(
Assets.svg.arrowLeft, Assets.svg.arrowLeft,
width: 24, width: isCompact ? 18 : 24,
height: 24, height: isCompact ? 18 : 24,
color: Theme.of(context).extension<StackColors>()!.topNavIconPrimary, color: Theme.of(context).extension<StackColors>()!.topNavIconPrimary,
), ),
onPressed: onPressed ?? Navigator.of(context).pop, onPressed: onPressed ?? Navigator.of(context).pop,

View file

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
class NumberKey extends StatefulWidget { class NumberKey extends StatefulWidget {
@ -72,12 +72,7 @@ class _NumberKeyState extends State<NumberKey> {
child: Center( child: Center(
child: Text( child: Text(
number, number,
style: GoogleFonts.roboto( style: STextStyles.numberDefault(context),
color:
Theme.of(context).extension<StackColors>()!.numberTextDefault,
fontWeight: FontWeight.w400,
fontSize: 26,
),
), ),
), ),
), ),

View file

@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/util.dart';
class CustomTextButtonBase extends StatelessWidget {
const CustomTextButtonBase({
Key? key,
this.width,
this.height,
this.textButton,
}) : super(key: key);
final double? width;
final double? height;
final TextButton? textButton;
@override
Widget build(BuildContext context) {
final isDesktop = Util.isDesktop;
return SizedBox(
height: isDesktop && height == null ? 70 : height,
width: width,
child: textButton,
);
}
}

View file

@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class DesktopDialog extends StatelessWidget {
const DesktopDialog({Key? key, this.child}) : super(key: key);
final Widget? child;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 641,
maxHeight: 474,
),
child: Material(
borderRadius: BorderRadius.circular(
20,
),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
20,
),
),
child: child,
),
),
),
],
);
}
}

View file

@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
class DesktopDialogCloseButton extends StatelessWidget {
const DesktopDialogCloseButton({
Key? key,
this.onPressedOverride,
}) : super(key: key);
final VoidCallback? onPressedOverride;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
AppBarIconButton(
color:
Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
size: 40,
icon: SvgPicture.asset(
Assets.svg.x,
color: Theme.of(context).extension<StackColors>()!.textDark,
width: 22,
height: 22,
),
onPressed: () {
if (onPressedOverride == null) {
Navigator.of(context).pop();
} else {
onPressedOverride!.call();
}
},
),
],
),
);
}
}

View file

@ -0,0 +1,71 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/custom_text_button.dart';
class PrimaryButton extends StatelessWidget {
const PrimaryButton({
Key? key,
this.width,
this.height,
this.label,
this.icon,
this.onPressed,
this.enabled = true,
}) : super(key: key);
final double? width;
final double? height;
final String? label;
final VoidCallback? onPressed;
final bool enabled;
final Widget? icon;
@override
Widget build(BuildContext context) {
final isDesktop = Util.isDesktop;
return CustomTextButtonBase(
height: height,
width: width,
textButton: TextButton(
onPressed: enabled ? onPressed : null,
style: enabled
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null) icon!,
if (icon != null && label != null)
const SizedBox(
width: 10,
),
if (label != null)
Text(
label!,
style: isDesktop
? enabled
? STextStyles.desktopButtonEnabled(context)
: STextStyles.desktopButtonDisabled(context)
: STextStyles.button(context).copyWith(
color: enabled
? Theme.of(context)
.extension<StackColors>()!
.buttonTextPrimary
: Theme.of(context)
.extension<StackColors>()!
.buttonTextPrimaryDisabled,
),
),
],
),
),
);
}
}

View file

@ -0,0 +1,71 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/custom_text_button.dart';
class SecondaryButton extends StatelessWidget {
const SecondaryButton({
Key? key,
this.width,
this.height,
this.label,
this.icon,
this.onPressed,
this.enabled = true,
}) : super(key: key);
final double? width;
final double? height;
final String? label;
final VoidCallback? onPressed;
final bool enabled;
final Widget? icon;
@override
Widget build(BuildContext context) {
final isDesktop = Util.isDesktop;
return CustomTextButtonBase(
height: height,
width: width,
textButton: TextButton(
onPressed: enabled ? onPressed : null,
style: enabled
? Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getSecondaryDisabledButtonColor(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (icon != null) icon!,
if (icon != null && label != null)
const SizedBox(
width: 10,
),
if (label != null)
Text(
label!,
style: isDesktop
? enabled
? STextStyles.desktopButtonSecondaryEnabled(context)
: STextStyles.desktopButtonSecondaryDisabled(context)
: STextStyles.button(context).copyWith(
color: enabled
? Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary
: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondaryDisabled,
),
),
],
),
),
);
}
}

View file

@ -8,6 +8,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/favorite_toggle.dart'; import 'package:stackwallet/widgets/custom_buttons/favorite_toggle.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -30,8 +31,10 @@ class _ManagedFavoriteCardState extends ConsumerState<ManagedFavorite> {
.select((value) => value.getManager(widget.walletId))); .select((value) => value.getManager(widget.walletId)));
debugPrint("BUILD: $runtimeType with walletId ${widget.walletId}"); debugPrint("BUILD: $runtimeType with walletId ${widget.walletId}");
final isDesktop = Util.isDesktop;
return RoundedWhiteContainer( return RoundedWhiteContainer(
padding: const EdgeInsets.all(4.0), padding: EdgeInsets.all(isDesktop ? 0 : 4.0),
child: RawMaterialButton( child: RawMaterialButton(
onPressed: () { onPressed: () {
final provider = ref final provider = ref
@ -59,7 +62,12 @@ class _ManagedFavoriteCardState extends ConsumerState<ManagedFavorite> {
), ),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8), padding: isDesktop
? const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
)
: const EdgeInsets.all(8),
child: Row( child: Row(
children: [ children: [
Container( Container(
@ -73,7 +81,7 @@ class _ManagedFavoriteCardState extends ConsumerState<ManagedFavorite> {
), ),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(4), padding: EdgeInsets.all(isDesktop ? 6 : 4),
child: SvgPicture.asset( child: SvgPicture.asset(
Assets.svg.iconFor(coin: manager.coin), Assets.svg.iconFor(coin: manager.coin),
width: 20, width: 20,
@ -84,37 +92,79 @@ class _ManagedFavoriteCardState extends ConsumerState<ManagedFavorite> {
const SizedBox( const SizedBox(
width: 12, width: 12,
), ),
Expanded( if (isDesktop)
child: Column( Expanded(
mainAxisAlignment: MainAxisAlignment.spaceBetween, child: Row(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Expanded(
Text( child: Text(
manager.walletName, manager.walletName,
style: STextStyles.titleBold12(context), style: STextStyles.titleBold12(context),
), ),
const SizedBox( ),
height: 2, Expanded(
), child: Text(
Text( "${Format.localizedStringAsFixed(
"${Format.localizedStringAsFixed( value: manager.cachedTotalBalance,
value: manager.cachedTotalBalance, locale: ref.watch(
locale: ref.watch(localeServiceChangeNotifierProvider localeServiceChangeNotifierProvider
.select((value) => value.locale)), .select((value) => value.locale)),
decimalPlaces: 8, decimalPlaces: 8,
)} ${manager.coin.ticker}", )} ${manager.coin.ticker}",
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
], ),
Text(
manager.isFavorite
? "Remove from favorites"
: "Add to favorites",
style:
STextStyles.desktopTextExtraSmall(context).copyWith(
color: manager.isFavorite
? Theme.of(context)
.extension<StackColors>()!
.accentColorRed
: Theme.of(context)
.extension<StackColors>()!
.buttonTextBorderless,
),
)
],
),
), ),
), if (!isDesktop)
FavoriteToggle( Expanded(
borderRadius: BorderRadius.circular( child: Column(
Constants.size.circularBorderRadius, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
manager.walletName,
style: STextStyles.titleBold12(context),
),
const SizedBox(
height: 2,
),
Text(
"${Format.localizedStringAsFixed(
value: manager.cachedTotalBalance,
locale: ref.watch(localeServiceChangeNotifierProvider
.select((value) => value.locale)),
decimalPlaces: 8,
)} ${manager.coin.ticker}",
style: STextStyles.itemSubtitle(context),
),
],
),
),
if (!isDesktop)
FavoriteToggle(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
initialState: manager.isFavorite,
onChanged: null,
), ),
initialState: manager.isFavorite,
onChanged: null,
),
], ],
), ),
), ),

View file

@ -85,6 +85,7 @@ class NodeOptionsSheet extends ConsumerWidget {
break; break;
case Coin.monero: case Coin.monero:
case Coin.wownero:
try { try {
final uri = Uri.parse(node.host); final uri = Uri.parse(node.host);
if (uri.scheme.startsWith("http")) { if (uri.scheme.startsWith("http")) {
@ -106,9 +107,9 @@ class NodeOptionsSheet extends ConsumerWidget {
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
case Coin.firoTestNet: case Coin.firoTestNet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
// case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.namecoin: case Coin.namecoin:
// case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
final client = ElectrumX( final client = ElectrumX(
host: node.host, host: node.host,
port: node.port, port: node.port,

View file

@ -6,10 +6,12 @@ class TableView extends StatefulWidget {
Key? key, Key? key,
required this.rows, required this.rows,
this.rowSpacing = 10.0, this.rowSpacing = 10.0,
this.shrinkWrap = false,
}) : super(key: key); }) : super(key: key);
final List<TableViewRow> rows; final List<TableViewRow> rows;
final double rowSpacing; final double rowSpacing;
final bool shrinkWrap;
@override @override
State<TableView> createState() => _TableViewState(); State<TableView> createState() => _TableViewState();
@ -19,6 +21,7 @@ class _TableViewState extends State<TableView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView( return ListView(
shrinkWrap: widget.shrinkWrap,
children: [ children: [
for (int i = 0; i < widget.rows.length; i++) for (int i = 0; i < widget.rows.length; i++)
Column( Column(

View file

@ -11,6 +11,8 @@ class TableViewRow extends StatelessWidget {
this.decoration, this.decoration,
this.onExpandChanged, this.onExpandChanged,
this.padding = const EdgeInsets.all(0), this.padding = const EdgeInsets.all(0),
this.spacing = 0.0,
this.crossAxisAlignment = CrossAxisAlignment.center,
}) : super(key: key); }) : super(key: key);
final List<TableViewCell> cells; final List<TableViewCell> cells;
@ -18,6 +20,8 @@ class TableViewRow extends StatelessWidget {
final Decoration? decoration; final Decoration? decoration;
final void Function(ExpandableState)? onExpandChanged; final void Function(ExpandableState)? onExpandChanged;
final EdgeInsetsGeometry padding; final EdgeInsetsGeometry padding;
final double spacing;
final CrossAxisAlignment crossAxisAlignment;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,13 +31,18 @@ class TableViewRow extends StatelessWidget {
? Padding( ? Padding(
padding: padding, padding: padding,
child: Row( child: Row(
crossAxisAlignment: crossAxisAlignment,
children: [ children: [
...cells.map( for (int i = 0; i < cells.length; i++) ...[
(e) => Expanded( if (i != 0 && i != cells.length)
flex: e.flex, SizedBox(
child: e, width: spacing,
),
Expanded(
flex: cells[i].flex,
child: cells[i],
), ),
), ],
], ],
), ),
) )
@ -43,12 +52,16 @@ class TableViewRow extends StatelessWidget {
padding: padding, padding: padding,
child: Row( child: Row(
children: [ children: [
...cells.map( for (int i = 0; i < cells.length; i++) ...[
(e) => Expanded( if (i != 0 && i != cells.length)
flex: e.flex, SizedBox(
child: e, width: spacing,
),
Expanded(
flex: cells[i].flex,
child: cells[i],
), ),
), ],
], ],
), ),
), ),

View file

@ -172,7 +172,9 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
builder: (_) { builder: (_) {
final amount = coin == Coin.monero final amount = coin == Coin.monero
? (_transaction.amount ~/ 10000) ? (_transaction.amount ~/ 10000)
: _transaction.amount; : coin == Coin.wownero
? (_transaction.amount ~/ 1000)
: _transaction.amount;
return Text( return Text(
"${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}", "${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
style: style:
@ -212,6 +214,8 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
int value = _transaction.amount; int value = _transaction.amount;
if (coin == Coin.monero) { if (coin == Coin.monero) {
value = (value ~/ 10000); value = (value ~/ 10000);
} else if (coin == Coin.wownero) {
value = (value ~/ 1000);
} }
return Text( return Text(

View file

@ -317,6 +317,13 @@ packages:
relative: true relative: true
source: path source: path
version: "0.0.1" version: "0.0.1"
cw_wownero:
dependency: "direct main"
description:
path: "crypto_plugins/flutter_libmonero/cw_wownero"
relative: true
source: path
version: "0.0.1"
dart_numerics: dart_numerics:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -11,7 +11,7 @@ description: Stack Wallet
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.4.49+64 version: 1.4.52+68
environment: environment:
sdk: ">=2.17.0 <3.0.0" sdk: ">=2.17.0 <3.0.0"
@ -31,6 +31,9 @@ dependencies:
cw_monero: cw_monero:
path: ./crypto_plugins/flutter_libmonero/cw_monero path: ./crypto_plugins/flutter_libmonero/cw_monero
cw_wownero:
path: ./crypto_plugins/flutter_libmonero/cw_wownero
cw_core: cw_core:
path: ./crypto_plugins/flutter_libmonero/cw_core path: ./crypto_plugins/flutter_libmonero/cw_core
@ -189,6 +192,7 @@ flutter:
- assets/svg/clipboard.svg - assets/svg/clipboard.svg
- assets/images/stack.png - assets/images/stack.png
- assets/images/monero.png - assets/images/monero.png
- assets/images/wownero.png
- assets/images/firo.png - assets/images/firo.png
- assets/images/doge.png - assets/images/doge.png
- assets/images/bitcoin.png - assets/images/bitcoin.png
@ -292,6 +296,7 @@ flutter:
- assets/svg/coin_icons/EpicCash.svg - assets/svg/coin_icons/EpicCash.svg
- assets/svg/coin_icons/Firo.svg - assets/svg/coin_icons/Firo.svg
- assets/svg/coin_icons/Monero.svg - assets/svg/coin_icons/Monero.svg
- assets/svg/coin_icons/Wownero.svg
- assets/svg/coin_icons/Namecoin.svg - assets/svg/coin_icons/Namecoin.svg
# lottie animations # lottie animations
- assets/lottie/test.json - assets/lottie/test.json
@ -306,6 +311,7 @@ flutter:
- assets/svg/wallet-fa.svg - assets/svg/wallet-fa.svg
- assets/svg/exchange-3.svg - assets/svg/exchange-3.svg
- assets/svg/message-question-1.svg - assets/svg/message-question-1.svg
- assets/svg/drd-icon.svg
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware. # https://flutter.dev/assets-and-images/#resolution-aware.

View file

@ -1,7 +1,152 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:stackwallet/models/models.dart'; import 'package:stackwallet/models/models.dart';
import '../services/coins/firo/sample_data/transaction_data_samples.dart';
void main() { void main() {
group("TransactionData", () {
test("TransactionData from Json", () {
final txChunk = TransactionChunk.fromJson({
"timestamp": 993260735,
"transactions": [
{
"txid": "txid",
"confirmed_status": true,
"timestamp": 1876352482,
"txType": "txType",
"amount": 10,
"worthNow": "1",
"worthAtBlockTimestamp": "1",
"fees": 1,
"inputSize": 1,
"outputSize": 1,
"inputs": [],
"outputs": [],
"address": "address",
"height": 1,
"confirmations": 1,
"aliens": [],
"subType": "mint",
"isCancelled": false,
"slateId": "slateId",
"otherData": "otherData",
}
]
});
final txdata =
TransactionData.fromJson({"dateTimeChunks": [], "txChunks": []});
txdata.findTransaction("txid");
txdata.getAllTransactions();
});
});
group("Timestamp", () {
test("Timestamp is now", () {
final date = extractDateFromTimestamp(0);
});
test("Timestamp is null", () {
final date = extractDateFromTimestamp(null);
});
test("Timestamp is a random date", () {
final date = extractDateFromTimestamp(1876352482);
});
});
group("Transaction", () {
test("Transaction from Json", () {
final tx = Transaction.fromJson({
"txid": "txid",
"confirmed_status": true,
"timestamp": 1876352482,
"txType": "txType",
"amount": 10,
"worthNow": "1",
"worthAtBlockTimestamp": "1",
"fees": 1,
"inputSize": 1,
"outputSize": 1,
"inputs": [],
"outputs": [],
"address": "address",
"height": 1,
"confirmations": 1,
"aliens": [],
"subType": "mint",
"isCancelled": false,
"slateId": "slateId",
"otherData": "otherData",
});
});
test("Transaction from Lelantus Json", () {
final tx = Transaction.fromLelantusJson({
"txid": "txid",
"confirmed_status": true,
"timestamp": 1876352482,
"txType": "txType",
"amount": 10,
"worthNow": "1",
"worthAtBlockTimestamp": "1",
"fees": 1,
"inputSize": 1,
"outputSize": 1,
"inputs": [],
"outputs": [],
"address": "address",
"height": 1,
"confirmations": 1,
"aliens": [],
"subType": "mint",
"isCancelled": false,
"slateId": "slateId",
"otherData": "otherData",
});
});
test("TransactionChunk", () {
final transactionchunk = TransactionChunk.fromJson({
"timestamp": 45920,
"transactions": [],
});
expect(
transactionchunk.toString(), "timestamp: 45920 transactions: [\n]");
});
test("TransactionChunk with a transaction", () {
final txChunk = TransactionChunk.fromJson({
"timestamp": 993260735,
"transactions": [
{
"txid": "txid",
"confirmed_status": true,
"timestamp": 1876352482,
"txType": "txType",
"amount": 10,
"worthNow": "1",
"worthAtBlockTimestamp": "1",
"fees": 1,
"inputSize": 1,
"outputSize": 1,
"inputs": [],
"outputs": [],
"address": "address",
"height": 1,
"confirmations": 1,
"aliens": [],
"subType": "mint",
"isCancelled": false,
"slateId": "slateId",
"otherData": "otherData",
}
]
});
expect(txChunk.toString(),
"timestamp: 993260735 transactions: [\n {txid: txid, type: txType, subType: mint, value: 10, fee: 1, height: 1, confirm: true, confirmations: 1, address: address, timestamp: 1876352482, worthNow: 1, inputs: [], slateid: slateId } \n]");
});
});
group("Transaction isMinting", () { group("Transaction isMinting", () {
test("Transaction isMinting unconfirmed mint", () { test("Transaction isMinting unconfirmed mint", () {
final tx = Transaction( final tx = Transaction(
@ -94,4 +239,57 @@ void main() {
expect(tx1 == tx2, false); expect(tx1 == tx2, false);
expect(tx2.toString(), tx1.toString()); expect(tx2.toString(), tx1.toString());
}); });
group("Input", () {
test("Input.toString", () {
final input = Input(
txid: "txid",
vout: 1,
prevout: null,
scriptsig: "scriptsig",
scriptsigAsm: "scriptsigAsm",
witness: [],
isCoinbase: false,
sequence: 1,
innerRedeemscriptAsm: "innerRedeemscriptAsm",
); //Input
expect(input.toString(), "{txid: txid}");
});
test("Input.toString", () {
final input = Input.fromJson({
"txid": "txid",
"vout": 1,
"prevout": null,
"scriptSig": {"hex": "somehexString", "asm": "someasmthing"},
"scriptsigAsm": "scriptsigAsm",
"witness": [],
"isCoinbase": false,
"sequence": 1,
"innerRedeemscriptAsm": "innerRedeemscriptAsm",
}); //Input
expect(input.toString(), "{txid: txid}");
});
});
group("Output", () {
test("Output.toString", () {
final output = Output.fromJson({
"scriptPubKey": {
"hex": "somehexSting",
"asm": "someasmthing",
"type": "sometype",
"addresses": "someaddresses",
},
"scriptpubkeyAsm": "scriptpubkeyAsm",
"scriptpubkeyType": "scriptpubkeyType",
"scriptpubkeyAddress": "address",
"value": 2,
}); //Input
expect(output.toString(), "Instance of \'Output\'");
});
});
} }

View file

@ -23,8 +23,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"), "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenAnswer((_) async => Response( })).thenAnswer((_) async => Response(
@ -37,12 +36,10 @@ void main() {
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect(price.toString(), expect(price.toString(),
'{Coin.bitcoin: [1, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}'); '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
// '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
verify(client.get( verify(client.get(
Uri.parse( Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"), "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
headers: {'Content-Type': 'application/json'})).called(1); headers: {'Content-Type': 'application/json'})).called(1);
verifyNoMoreInteractions(client); verifyNoMoreInteractions(client);
@ -53,8 +50,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"), "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenAnswer((_) async => Response( })).thenAnswer((_) async => Response(
@ -72,14 +68,12 @@ void main() {
await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect(cachedPrice.toString(), expect(cachedPrice.toString(),
'{Coin.bitcoin: [1, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}'); '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
// '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
// verify only called once during filling of cache // verify only called once during filling of cache
verify(client.get( verify(client.get(
Uri.parse( Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"), "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
headers: {'Content-Type': 'application/json'})).called(1); headers: {'Content-Type': 'application/json'})).called(1);
verifyNoMoreInteractions(client); verifyNoMoreInteractions(client);
@ -90,7 +84,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"), "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenAnswer((_) async => Response( })).thenAnswer((_) async => Response(
@ -103,8 +97,7 @@ void main() {
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect(price.toString(), expect(price.toString(),
'{Coin.bitcoin: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}'); '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
// '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
}); });
test("no internet available", () async { test("no internet available", () async {
@ -112,8 +105,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"), "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenThrow(const SocketException( })).thenThrow(const SocketException(
@ -124,10 +116,8 @@ void main() {
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect( expect(price.toString(),
price.toString(), '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
// '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
'{Coin.bitcoin: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
}); });
tearDown(() async { tearDown(() async {

View file

@ -32,6 +32,40 @@ final Map<String, List<dynamic>> historyBatchArgs1 = {
"k_0_11": ["9d0163f011c1259568c188c4770606b25c823f8b76bbd262c1c7f3095ed24620"] "k_0_11": ["9d0163f011c1259568c188c4770606b25c823f8b76bbd262c1c7f3095ed24620"]
}; };
final Map<String, List<dynamic>> historyBatchArgs2 = {
"k_0_0": ["e47feb2ab9db7424d044dc5b2f29404ec35682dc7ea2100acab4b85eb15b8a84"],
"k_0_1": ["ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"],
"k_0_2": ["68c84a2f0e8b52769e22270f9cf26bc1e3ffed55fe368e94c5d761403b86a7c5"],
"k_0_3": ["7ec0c8c9b961e481a3fd05b997997929a36c174857ba4f06e8ba55b5a29670fd"],
"k_0_4": ["42adc3dee3f1c8bc25384ab5254a75af64fc94b6e29d3ae6c0ccfb50c7910c88"],
"k_0_5": ["d3e419ee2b5ef5969a76d3e5ae14a15fe2dfa26ac434de95b0616416e4dc8955"],
"k_0_6": ["0cf8f653ae181c1a33d94787f7a34c0a95bd0465003488c1a6e7f81b87063573"],
"k_0_7": ["8c8e647009329da2c508aa08b2b28b2f83932efca4ed5a6c1b29ccec37fda9c1"],
"k_0_8": ["30c063757244ac50049d2604c7f9d671e9cbac53f4e76a9c1147112934336057"],
"k_0_9": ["2440d59c1dc1fd6dde77f52d8cf4f8f799005f53e8027f10828ef1eee739694e"],
"k_0_10": [
"1a2e9fd10dc64048e1bf86c58c37611920facf486e80a36a60e20eb3496c3aad"
],
"k_0_11": ["052e9116071688691bf12f2db3154f72562d957cf058bce2b88a144d67968da0"]
};
final Map<String, List<dynamic>> historyBatchArgs3 = {
"k_0_0": ["4694828a4841338b5921e10f9d97a9c6d2a4ff50593be21572391fefbd2179be"],
"k_0_1": ["1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"],
"k_0_2": ["e96b7f9655acc58d58ffc322626c9742f3941fef790e3d2836d5db74d3708427"],
"k_0_3": ["abc8d1cf0dc8f66678eb0d322eb4f907cb2552cde74ace5201c4978787db91e4"],
"k_0_4": ["421b02221022dd34081669fd21e7a9a83f8761e068f48b5291e0accf9d1b5867"],
"k_0_5": ["1233abcc5848b1bcf6a561984f1f0596d270ef47320c281a5abf7a2098dd5902"],
"k_0_6": ["963f002eddfb35100830f416c97605947a9df7ea885554923d6427b79d519079"],
"k_0_7": ["8b511de883d14c0f40b8eed22c23432b3d9c97ce521c4ad94338189065ae3e94"],
"k_0_8": ["954d176b775a925fcbceb36b717114b0f01af6ac082d89971379e789a4bba613"],
"k_0_9": ["3c8c79404dba45b8228547a5b3da306e1cdc3438e02f9e6ec1c88ba2fb6ef6df"],
"k_0_10": [
"a253190f30e26c482d3864d675da927a9df20c52172826ea630ca3f600da4642"
],
"k_0_11": ["bd39e800a3822ebaa5e33938b29cff5fcf867def7c0ac6d65af350b737357f65"]
};
final Map<String, List<Map<String, dynamic>>> historyBatchResponse = { final Map<String, List<Map<String, dynamic>>> historyBatchResponse = {
"k_0_0": [], "k_0_0": [],
"s_0_0": [{}, {}], "s_0_0": [{}, {}],
@ -117,4 +151,8 @@ final List<String> activeScriptHashes = [
"26f92666caebb9a17b14f5b573b385348cdc80065472b8961091f3226d2f650f", "26f92666caebb9a17b14f5b573b385348cdc80065472b8961091f3226d2f650f",
"2f18558e5d3015cb6578aee1c3e4b645725fa4e1d26ce22cb31c9949f3b4957c", "2f18558e5d3015cb6578aee1c3e4b645725fa4e1d26ce22cb31c9949f3b4957c",
"bf5a6c56814e80eed11e1e459801515f8c2b83da812568aa9dc26e6356f6965b", "bf5a6c56814e80eed11e1e459801515f8c2b83da812568aa9dc26e6356f6965b",
"f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34",
"ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734",
"04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b",
"1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80",
]; ];

View file

@ -1,3 +1,5 @@
// import 'dart:convert';
//
// import 'package:bitcoindart/bitcoindart.dart'; // import 'package:bitcoindart/bitcoindart.dart';
// import 'package:decimal/decimal.dart'; // import 'package:decimal/decimal.dart';
// import 'package:flutter_test/flutter_test.dart'; // import 'package:flutter_test/flutter_test.dart';
@ -43,8 +45,9 @@ void main() {}
// }); // });
// //
// test("bitcoincash DerivePathType enum", () { // test("bitcoincash DerivePathType enum", () {
// expect(DerivePathType.values.length, 1); // expect(DerivePathType.values.length, 2);
// expect(DerivePathType.values.toString(), "[DerivePathType.bip44]"); // expect(DerivePathType.values.toString(),
// "[DerivePathType.bip44, DerivePathType.bip49]");
// }); // });
// //
// group("bip32 node/root", () { // group("bip32 node/root", () {
@ -1270,13 +1273,13 @@ void main() {}
// } // }
// expect(didThrow, false); // expect(didThrow, false);
// //
// verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); // verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(2);
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verifyNever(client?.ping()).called(0); // verifyNever(client?.ping()).called(0);
// //
// expect(secureStore?.interactions, 11); // expect(secureStore?.interactions, 20);
// expect(secureStore?.reads, 7); // expect(secureStore?.reads, 13);
// expect(secureStore?.writes, 4); // expect(secureStore?.writes, 7);
// expect(secureStore?.deletes, 0); // expect(secureStore?.deletes, 0);
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient); // verifyNoMoreInteractions(cachedClient);
@ -1316,9 +1319,9 @@ void main() {}
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verifyNever(client?.ping()).called(0); // verifyNever(client?.ping()).called(0);
// //
// expect(secureStore?.interactions, 8); // expect(secureStore?.interactions, 14);
// expect(secureStore?.reads, 5); // expect(secureStore?.reads, 9);
// expect(secureStore?.writes, 3); // expect(secureStore?.writes, 5);
// expect(secureStore?.deletes, 0); // expect(secureStore?.deletes, 0);
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient); // verifyNoMoreInteractions(cachedClient);
@ -1365,13 +1368,13 @@ void main() {}
// } // }
// expect(didThrow, false); // expect(didThrow, false);
// //
// verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); // verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(2);
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verifyNever(client?.ping()).called(0); // verifyNever(client?.ping()).called(0);
// //
// expect(secureStore?.interactions, 11); // expect(secureStore?.interactions, 20);
// expect(secureStore?.reads, 7); // expect(secureStore?.reads, 13);
// expect(secureStore?.writes, 4); // expect(secureStore?.writes, 7);
// expect(secureStore?.deletes, 0); // expect(secureStore?.deletes, 0);
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient); // verifyNoMoreInteractions(cachedClient);
@ -1412,9 +1415,9 @@ void main() {}
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verifyNever(client?.ping()).called(0); // verifyNever(client?.ping()).called(0);
// //
// expect(secureStore?.interactions, 8); // expect(secureStore?.interactions, 14);
// expect(secureStore?.reads, 5); // expect(secureStore?.reads, 9);
// expect(secureStore?.writes, 3); // expect(secureStore?.writes, 5);
// expect(secureStore?.deletes, 0); // expect(secureStore?.deletes, 0);
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient); // verifyNoMoreInteractions(cachedClient);
@ -1829,6 +1832,10 @@ void main() {}
// .thenAnswer((_) async => emptyHistoryBatchResponse); // .thenAnswer((_) async => emptyHistoryBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs1)) // when(client?.getBatchHistory(args: historyBatchArgs1))
// .thenAnswer((_) async => emptyHistoryBatchResponse); // .thenAnswer((_) async => emptyHistoryBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs2))
// .thenAnswer((_) async => emptyHistoryBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs3))
// .thenAnswer((_) async => emptyHistoryBatchResponse);
// //
// final wallet = await Hive.openBox(testWalletId); // final wallet = await Hive.openBox(testWalletId);
// //
@ -1844,6 +1851,8 @@ void main() {}
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs2)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs3)).called(1);
// //
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient); // verifyNoMoreInteractions(cachedClient);
@ -1982,8 +1991,24 @@ void main() {}
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs1)) // when(client?.getBatchHistory(args: historyBatchArgs1))
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs2))
// .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs3))
// .thenAnswer((_) async => historyBatchResponse);
// //
// final wallet = await Hive.openBox(testWalletId); // List<dynamic> dynamicArgValues = [];
//
// when(client?.getBatchHistory(args: anyNamed("args")))
// .thenAnswer((realInvocation) async {
// if (realInvocation.namedArguments.values.first.length == 1) {
// dynamicArgValues.add(realInvocation.namedArguments.values.first);
// }
//
// return historyBatchResponse;
// });
//
// // final wallet = await Hive.openBox(testWalletId);
// await Hive.openBox<dynamic>(testWalletId);
// //
// bool hasThrown = false; // bool hasThrown = false;
// try { // try {
@ -2000,10 +2025,20 @@ void main() {}
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs2)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs3)).called(1);
// //
// expect(secureStore?.interactions, 6); // for (final arg in dynamicArgValues) {
// expect(secureStore?.writes, 3); // final map = Map<String, List<dynamic>>.from(arg as Map);
// expect(secureStore?.reads, 3); //
// verify(client?.getBatchHistory(args: map)).called(1);
// expect(activeScriptHashes.contains(map.values.first.first as String),
// true);
// }
//
// expect(secureStore?.interactions, 10);
// expect(secureStore?.writes, 5);
// expect(secureStore?.reads, 5);
// expect(secureStore?.deletes, 0); // expect(secureStore?.deletes, 0);
// //
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
@ -2027,10 +2062,34 @@ void main() {}
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs1)) // when(client?.getBatchHistory(args: historyBatchArgs1))
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// // when(client?.getBatchHistory(args: historyBatchArgs2))
// .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs3))
// .thenAnswer((_) async => historyBatchResponse);
// when(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) // when(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash))
// .thenAnswer((realInvocation) async {}); // .thenAnswer((realInvocation) async {});
// //
// when(client?.getBatchHistory(args: {
// "0": [
// "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ]
// })).thenAnswer((_) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ]
// })).thenAnswer((_) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).thenAnswer((_) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).thenAnswer((_) async => {"0": []});
//
// final wallet = await Hive.openBox(testWalletId); // final wallet = await Hive.openBox(testWalletId);
// //
// // restore so we have something to rescan // // restore so we have something to rescan
@ -2046,25 +2105,51 @@ void main() {}
// final preChangeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); // final preChangeAddressesP2PKH = await wallet.get('changeAddressesP2PKH');
// final preReceivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); // final preReceivingIndexP2PKH = await wallet.get('receivingIndexP2PKH');
// final preChangeIndexP2PKH = await wallet.get('changeIndexP2PKH'); // final preChangeIndexP2PKH = await wallet.get('changeIndexP2PKH');
//
// final preReceivingAddressesP2SH =
// await wallet.get('receivingAddressesP2SH');
// final preChangeAddressesP2SH = await wallet.get('changeAddressesP2SH');
// final preReceivingIndexP2SH = await wallet.get('receivingIndexP2PKH');
// final preChangeIndexP2SH = await wallet.get('changeIndexP2SH');
//
// final preUtxoData = await wallet.get('latest_utxo_model'); // final preUtxoData = await wallet.get('latest_utxo_model');
// final preReceiveDerivationsStringP2PKH = await secureStore?.read( // final preReceiveDerivationsStringP2PKH = await secureStore?.read(
// key: "${testWalletId}_receiveDerivationsP2PKH"); // key: "${testWalletId}_receiveDerivationsP2PKH");
// final preChangeDerivationsStringP2PKH = await secureStore?.read( // final preChangeDerivationsStringP2PKH = await secureStore?.read(
// key: "${testWalletId}_changeDerivationsP2PKH"); // key: "${testWalletId}_changeDerivationsP2PKH");
// //
// final preReceiveDerivationsStringP2SH = await secureStore?.read(
// key: "${testWalletId}_receiveDerivationsP2SH");
// final preChangeDerivationsStringP2SH =
// await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
//
// // destroy the data that the rescan will fix // // destroy the data that the rescan will fix
// await wallet.put( // await wallet.put(
// 'receivingAddressesP2PKH', ["some address", "some other address"]); // 'receivingAddressesP2PKH', ["some address", "some other address"]);
// await wallet // await wallet
// .put('changeAddressesP2PKH', ["some address", "some other address"]); // .put('changeAddressesP2PKH', ["some address", "some other address"]);
// //
// await wallet.put(
// 'receivingAddressesP2SH', ["some address", "some other address"]);
// await wallet
// .put('changeAddressesP2SH', ["some address", "some other address"]);
//
// await wallet.put('receivingIndexP2PKH', 123); // await wallet.put('receivingIndexP2PKH', 123);
// await wallet.put('changeIndexP2PKH', 123); // await wallet.put('changeIndexP2PKH', 123);
//
// await wallet.put('receivingIndexP2SH', 123);
// await wallet.put('changeIndexP2SH', 123);
//
// await secureStore?.write( // await secureStore?.write(
// key: "${testWalletId}_receiveDerivationsP2PKH", value: "{}"); // key: "${testWalletId}_receiveDerivationsP2PKH", value: "{}");
// await secureStore?.write( // await secureStore?.write(
// key: "${testWalletId}_changeDerivationsP2PKH", value: "{}"); // key: "${testWalletId}_changeDerivationsP2PKH", value: "{}");
// //
// await secureStore?.write(
// key: "${testWalletId}_receiveDerivationsP2SH", value: "{}");
// await secureStore?.write(
// key: "${testWalletId}_changeDerivationsP2SH", value: "{}");
//
// bool hasThrown = false; // bool hasThrown = false;
// try { // try {
// await bch?.fullRescan(2, 1000); // await bch?.fullRescan(2, 1000);
@ -2079,29 +2164,73 @@ void main() {}
// final changeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); // final changeAddressesP2PKH = await wallet.get('changeAddressesP2PKH');
// final receivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); // final receivingIndexP2PKH = await wallet.get('receivingIndexP2PKH');
// final changeIndexP2PKH = await wallet.get('changeIndexP2PKH'); // final changeIndexP2PKH = await wallet.get('changeIndexP2PKH');
//
// final receivingAddressesP2SH = await wallet.get('receivingAddressesP2SH');
// final changeAddressesP2SH = await wallet.get('changeAddressesP2SH');
// final receivingIndexP2SH = await wallet.get('receivingIndexP2SH');
// final changeIndexP2SH = await wallet.get('changeIndexP2SH');
//
// final utxoData = await wallet.get('latest_utxo_model'); // final utxoData = await wallet.get('latest_utxo_model');
// final receiveDerivationsStringP2PKH = await secureStore?.read( // final receiveDerivationsStringP2PKH = await secureStore?.read(
// key: "${testWalletId}_receiveDerivationsP2PKH"); // key: "${testWalletId}_receiveDerivationsP2PKH");
// final changeDerivationsStringP2PKH = await secureStore?.read( // final changeDerivationsStringP2PKH = await secureStore?.read(
// key: "${testWalletId}_changeDerivationsP2PKH"); // key: "${testWalletId}_changeDerivationsP2PKH");
// //
// final receiveDerivationsStringP2SH = await secureStore?.read(
// key: "${testWalletId}_receiveDerivationsP2SH");
// final changeDerivationsStringP2SH =
// await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
//
// expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH); // expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH);
// expect(preChangeAddressesP2PKH, changeAddressesP2PKH); // expect(preChangeAddressesP2PKH, changeAddressesP2PKH);
// expect(preReceivingIndexP2PKH, receivingIndexP2PKH); // expect(preReceivingIndexP2PKH, receivingIndexP2PKH);
// expect(preChangeIndexP2PKH, changeIndexP2PKH); // expect(preChangeIndexP2PKH, changeIndexP2PKH);
//
// expect(preReceivingAddressesP2SH, receivingAddressesP2SH);
// expect(preChangeAddressesP2SH, changeAddressesP2SH);
// expect(preReceivingIndexP2SH, receivingIndexP2SH);
// expect(preChangeIndexP2SH, changeIndexP2SH);
//
// expect(preUtxoData, utxoData); // expect(preUtxoData, utxoData);
//
// expect(preReceiveDerivationsStringP2PKH, receiveDerivationsStringP2PKH); // expect(preReceiveDerivationsStringP2PKH, receiveDerivationsStringP2PKH);
// expect(preChangeDerivationsStringP2PKH, changeDerivationsStringP2PKH); // expect(preChangeDerivationsStringP2PKH, changeDerivationsStringP2PKH);
// //
// expect(preReceiveDerivationsStringP2SH, receiveDerivationsStringP2SH);
// expect(preChangeDerivationsStringP2SH, changeDerivationsStringP2SH);
//
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs0)).called(2); // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(2);
// verify(client?.getBatchHistory(args: historyBatchArgs1)).called(2); // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(2);
// verify(client?.getBatchHistory(args: historyBatchArgs2)).called(2);
// verify(client?.getBatchHistory(args: historyBatchArgs3)).called(2);
// verify(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) // verify(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash))
// .called(1); // .called(1);
// //
// expect(secureStore?.writes, 9); // verify(client?.getBatchHistory(args: {
// expect(secureStore?.reads, 12); // "0": [
// expect(secureStore?.deletes, 2); // "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ]
// })).called(2);
// verify(client?.getBatchHistory(args: {
// "0": [
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ]
// })).called(2);
// verify(client?.getBatchHistory(args: {
// "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).called(2);
// verify(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).called(2);
//
// expect(secureStore?.writes, 17);
// expect(secureStore?.reads, 22);
// expect(secureStore?.deletes, 4);
// //
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient); // verifyNoMoreInteractions(cachedClient);
@ -2125,19 +2254,33 @@ void main() {}
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs1)) // when(client?.getBatchHistory(args: historyBatchArgs1))
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs2))
// .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs3))
// .thenAnswer((_) async => historyBatchResponse);
// when(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash))
// .thenAnswer((realInvocation) async {});
//
// when(client?.getBatchHistory(args: { // when(client?.getBatchHistory(args: {
// "0": [ // "0": [
// "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b" // "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ] // ]
// })).thenAnswer((realInvocation) async => {"0": []}); // })).thenAnswer((realInvocation) async => {"0": []});
//
// when(client?.getBatchHistory(args: { // when(client?.getBatchHistory(args: {
// "0": [ // "0": [
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34" // "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ] // ]
// })).thenAnswer((realInvocation) async => {"0": []}); // })).thenAnswer((_) async => {"0": []});
// when(cachedClient?.clearSharedTransactionCache(coin: Coin.dogecoin)) // when(client?.getBatchHistory(args: {
// .thenAnswer((realInvocation) async {}); // "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).thenAnswer((_) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).thenAnswer((_) async => {"0": []});
// //
// final wallet = await Hive.openBox(testWalletId); // final wallet = await Hive.openBox(testWalletId);
// //
@ -2195,13 +2338,36 @@ void main() {}
// //
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs0)).called(2); // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(2);
// verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(2);
// verify(client?.getBatchHistory(args: historyBatchArgs2)).called(2);
// verify(client?.getBatchHistory(args: historyBatchArgs3)).called(2);
// verify(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) // verify(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash))
// .called(1); // .called(1);
// //
// expect(secureStore?.writes, 7); // verify(client?.getBatchHistory(args: {
// expect(secureStore?.reads, 12); // "0": [
// expect(secureStore?.deletes, 4); // "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ]
// })).called(1);
// verify(client?.getBatchHistory(args: {
// "0": [
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ]
// })).called(2);
// verify(client?.getBatchHistory(args: {
// "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).called(2);
// verify(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).called(2);
//
// expect(secureStore?.writes, 13);
// expect(secureStore?.reads, 18);
// expect(secureStore?.deletes, 8);
// }); // });
// //
// // // test("fetchBuildTxData succeeds", () async { // // // test("fetchBuildTxData succeeds", () async {
@ -2686,17 +2852,30 @@ void main() {}
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs1)) // when(client?.getBatchHistory(args: historyBatchArgs1))
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs2))
// .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs3))
// .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: { // when(client?.getBatchHistory(args: {
// "0": [ // "0": [
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34" // "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ] // ]
// })).thenAnswer((realInvocation) async => {"0": []}); // })).thenAnswer((realInvocation) async => {"0": []});
//
// when(client?.getBatchHistory(args: { // when(client?.getBatchHistory(args: {
// "0": [ // "0": [
// "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b" // "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ] // ]
// })).thenAnswer((realInvocation) async => {"0": []}); // })).thenAnswer((realInvocation) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).thenAnswer((realInvocation) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).thenAnswer((realInvocation) async => {"0": []});
// //
// final wallet = await Hive.openBox(testWalletId); // final wallet = await Hive.openBox(testWalletId);
// // recover to fill data // // recover to fill data
@ -2713,10 +2892,33 @@ void main() {}
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs2)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs3)).called(1);
// //
// expect(secureStore?.interactions, 6); // verify(client?.getBatchHistory(args: {
// expect(secureStore?.writes, 3); // "0": [
// expect(secureStore?.reads, 3); // "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ]
// })).called(1);
// verify(client?.getBatchHistory(args: {
// "0": [
// "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ]
// })).called(1);
// verify(client?.getBatchHistory(args: {
// "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).called(1);
// verify(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).called(1);
//
// expect(secureStore?.interactions, 10);
// expect(secureStore?.writes, 5);
// expect(secureStore?.reads, 5);
// expect(secureStore?.deletes, 0); // expect(secureStore?.deletes, 0);
// //
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);
@ -2741,17 +2943,32 @@ void main() {}
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: historyBatchArgs1)) // when(client?.getBatchHistory(args: historyBatchArgs1))
// .thenAnswer((_) async => historyBatchResponse); // .thenAnswer((_) async => historyBatchResponse);
// when(client?.getBatchHistory(args: { // when(client?.getBatchHistory(args: historyBatchArgs2))
// "0": [ // .thenAnswer((_) async => historyBatchResponse);
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34" // when(client?.getBatchHistory(args: historyBatchArgs3))
// ] // .thenAnswer((_) async => historyBatchResponse);
// })).thenAnswer((realInvocation) async => {"0": []});
// //
// when(client?.getBatchHistory(args: { // when(client?.getBatchHistory(args: {
// "0": [ // "0": [
// "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b" // "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ] // ]
// })).thenAnswer((realInvocation) async => {"0": []}); // })).thenAnswer((realInvocation) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ]
// })).thenAnswer((realInvocation) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).thenAnswer((realInvocation) async => {"0": []});
// when(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).thenAnswer((realInvocation) async => {"0": []});
//
// when(client?.getHistory(scripthash: anyNamed("scripthash"))) // when(client?.getHistory(scripthash: anyNamed("scripthash")))
// .thenThrow(Exception("some exception")); // .thenThrow(Exception("some exception"));
// //
@ -2769,12 +2986,36 @@ void main() {}
// verify(client?.getServerFeatures()).called(1); // verify(client?.getServerFeatures()).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs2)).called(1);
// verify(client?.getBatchHistory(args: historyBatchArgs3)).called(1);
//
// verify(client?.getBatchHistory(args: {
// "0": [
// "04818da846fe5e03ac993d2e0c1ccc3848ff6073c3aba6a572df4efc5432ae8b"
// ]
// })).called(1);
// verify(client?.getBatchHistory(args: {
// "0": [
// "f0c86f888f2aca0efaf1705247dbd1ebc02347c183e197310c9062ea2c9d2e34"
// ]
// })).called(1);
// verify(client?.getBatchHistory(args: {
// "0": [
// "ff7f0d2a4b8e2805706ece77f4e672550fe4c505a150c781639814338eda1734"
// ]
// })).called(1);
// verify(client?.getBatchHistory(args: {
// "0": [
// "1c2336c32dc62f00862ee6a75643e01017c86edece10b5a9d7defbd5f66b0a80"
// ]
// })).called(1);
//
// verify(client?.getBlockHeadTip()).called(1); // verify(client?.getBlockHeadTip()).called(1);
// verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); // verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1);
// //
// expect(secureStore?.interactions, 6); // expect(secureStore?.interactions, 10);
// expect(secureStore?.writes, 3); // expect(secureStore?.writes, 5);
// expect(secureStore?.reads, 3); // expect(secureStore?.reads, 5);
// expect(secureStore?.deletes, 0); // expect(secureStore?.deletes, 0);
// //
// verifyNoMoreInteractions(client); // verifyNoMoreInteractions(client);