spark coins ui view

This commit is contained in:
julian 2023-12-16 14:26:23 -06:00
parent 8336712a23
commit c1640331af
4 changed files with 325 additions and 24 deletions

View file

@ -19,6 +19,7 @@ import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_set
import 'package:stackwallet/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart';
import 'package:stackwallet/pages_desktop_specific/lelantus_coins/lelantus_coins_view.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
import 'package:stackwallet/pages_desktop_specific/spark_coins/spark_coins_view.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart';
@ -32,7 +33,8 @@ enum _WalletOptions {
deleteWallet,
changeRepresentative,
showXpub,
lelantusCoins;
lelantusCoins,
sparkCoins;
String get prettyName {
switch (this) {
@ -46,6 +48,8 @@ enum _WalletOptions {
return "Show xPub";
case _WalletOptions.lelantusCoins:
return "Lelantus Coins";
case _WalletOptions.sparkCoins:
return "Spark Coins";
}
}
}
@ -89,6 +93,9 @@ class WalletOptionsButton extends StatelessWidget {
onFiroShowLelantusCoins: () async {
Navigator.of(context).pop(_WalletOptions.lelantusCoins);
},
onFiroShowSparkCoins: () async {
Navigator.of(context).pop(_WalletOptions.sparkCoins);
},
walletId: walletId,
);
},
@ -191,6 +198,15 @@ class WalletOptionsButton extends StatelessWidget {
),
);
break;
case _WalletOptions.sparkCoins:
unawaited(
Navigator.of(context).pushNamed(
SparkCoinsView.routeName,
arguments: walletId,
),
);
break;
}
}
},
@ -224,6 +240,7 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
required this.onShowXpubPressed,
required this.onChangeRepPressed,
required this.onFiroShowLelantusCoins,
required this.onFiroShowSparkCoins,
required this.walletId,
}) : super(key: key);
@ -232,6 +249,7 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
final VoidCallback onShowXpubPressed;
final VoidCallback onChangeRepPressed;
final VoidCallback onFiroShowLelantusCoins;
final VoidCallback onFiroShowSparkCoins;
final String walletId;
@override
@ -374,6 +392,43 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
),
),
),
if (firoDebug)
const SizedBox(
height: 8,
),
if (firoDebug)
TransparentButton(
onPressed: onFiroShowSparkCoins,
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SvgPicture.asset(
Assets.svg.eye,
width: 20,
height: 20,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconLeft,
),
const SizedBox(width: 14),
Expanded(
child: Text(
_WalletOptions.sparkCoins.prettyName,
style: STextStyles.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
),
),
],
),
),
),
if (xpubEnabled)
const SizedBox(
height: 8,

View file

@ -0,0 +1,236 @@
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:isar/isar.dart';
import 'package:stackwallet/providers/db/main_db_provider.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
class SparkCoinsView extends ConsumerStatefulWidget {
const SparkCoinsView({
Key? key,
required this.walletId,
}) : super(key: key);
static const String routeName = "/sparkCoinsView";
final String walletId;
@override
ConsumerState<SparkCoinsView> createState() => _SparkCoinsViewState();
}
class _SparkCoinsViewState extends ConsumerState<SparkCoinsView> {
List<SparkCoin> _coins = [];
Stream<List<SparkCoin>>? sparkCoinsCollectionWatcher;
void _onSparkCoinsCollectionWatcherEvent(List<SparkCoin> coins) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
setState(() {
_coins = coins;
});
}
});
}
@override
void initState() {
sparkCoinsCollectionWatcher = ref
.read(mainDBProvider)
.isar
.sparkCoins
.where()
.walletIdEqualToAnyLTagHash(widget.walletId)
.sortByHeightDesc()
.watch(fireImmediately: true);
sparkCoinsCollectionWatcher!
.listen((data) => _onSparkCoinsCollectionWatcherEvent(data));
super.initState();
}
@override
void dispose() {
sparkCoinsCollectionWatcher = null;
super.dispose();
}
@override
Widget build(BuildContext context) {
return DesktopScaffold(
appBar: DesktopAppBar(
background: Theme.of(context).extension<StackColors>()!.popupBG,
leading: Expanded(
child: Row(
children: [
const SizedBox(
width: 32,
),
AppBarIconButton(
size: 32,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
shadows: const [],
icon: SvgPicture.asset(
Assets.svg.arrowLeft,
width: 18,
height: 18,
color: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: Navigator.of(context).pop,
),
const SizedBox(
width: 12,
),
Text(
"Spark Coins",
style: STextStyles.desktopH3(context),
),
const Spacer(),
],
),
),
useSpacers: false,
isCompactHeight: true,
),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(4),
child: RoundedWhiteContainer(
child: Row(
children: [
Expanded(
flex: 9,
child: Text(
"TXID",
style: STextStyles.itemSubtitle(context),
textAlign: TextAlign.left,
),
),
Expanded(
flex: 3,
child: Text(
"Value (sats)",
style: STextStyles.itemSubtitle(context),
textAlign: TextAlign.right,
),
),
Expanded(
flex: 2,
child: Text(
"Height",
style: STextStyles.itemSubtitle(context),
textAlign: TextAlign.right,
),
),
Expanded(
flex: 2,
child: Text(
"Type",
style: STextStyles.itemSubtitle(context),
textAlign: TextAlign.right,
),
),
Expanded(
flex: 2,
child: Text(
"Used",
style: STextStyles.itemSubtitle(context),
textAlign: TextAlign.right,
),
),
],
),
),
),
Expanded(
child: ListView.separated(
shrinkWrap: true,
itemCount: _coins.length,
separatorBuilder: (_, __) => Container(
height: 1,
color: Theme.of(context)
.extension<StackColors>()!
.backgroundAppBar,
),
itemBuilder: (_, index) => Padding(
padding: const EdgeInsets.all(4),
child: RoundedWhiteContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 9,
child: SelectableText(
_coins[index].txHash,
style: STextStyles.itemSubtitle12(context),
),
),
Expanded(
flex: 3,
child: SelectableText(
_coins[index].value.toString(),
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
),
Expanded(
flex: 2,
child: SelectableText(
_coins[index].height.toString(),
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
),
Expanded(
flex: 2,
child: SelectableText(
_coins[index].type.name,
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
),
Expanded(
flex: 2,
child: SelectableText(
_coins[index].isUsed.toString(),
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
),
],
),
),
),
),
),
],
),
),
);
}
}

View file

@ -175,6 +175,7 @@ import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/nodes_
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/security_settings.dart';
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/syncing_preferences_settings.dart';
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart';
import 'package:stackwallet/pages_desktop_specific/spark_coins/spark_coins_view.dart';
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
@ -1858,6 +1859,20 @@ class RouteGenerator {
}
return _routeError("${settings.name} invalid args: ${args.toString()}");
case SparkCoinsView.routeName:
if (args is String) {
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,
builder: (_) => SparkCoinsView(
walletId: args,
),
settings: RouteSettings(
name: settings.name,
),
);
}
return _routeError("${settings.name} invalid args: ${args.toString()}");
case DesktopCoinControlView.routeName:
if (args is String) {
return getRoute(

View file

@ -715,34 +715,29 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
txb.setLockTime(await chainHeight);
txb.setVersion(1);
// Create a mint script.
final mintScript = bscript.compile([
0xd1, // OP_SPARKMINT.
Uint8List(0),
]);
// Add inputs.
for (final utxo in txData.utxos!) {
txb.addInput(
utxo.txid,
utxo.vout,
0xffffffff,
mintScript,
);
}
final signingData = await fetchBuildTxData(txData.utxos!.toList());
// Create the serial context.
//
// "...serial_context is a byte array, which should be unique for each
// transaction, and for that we serialize and put all inputs into
// serial_context vector."
List<int> serialContext = [];
for (final utxo in txData.utxos!) {
serialContext.addAll(
bscript.compile([
utxo.txid,
utxo.vout,
]),
final serialContext = LibSpark.serializeMintContext(
inputs: signingData
.map((e) => (
e.utxo.txid,
e.utxo.vout,
))
.toList(),
);
// Add inputs.
for (final sd in signingData) {
txb.addInput(
sd.utxo.txid,
sd.utxo.vout,
null,
sd.output,
);
}
@ -756,7 +751,7 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
))
.toList(),
serialContext: Uint8List.fromList(serialContext),
// generate: true // TODO is this needed?
generate: true,
);
// Add mint output(s).