mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 17:57:40 +00:00
spark coins ui view
This commit is contained in:
parent
8336712a23
commit
c1640331af
4 changed files with 325 additions and 24 deletions
|
@ -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,
|
||||
|
|
236
lib/pages_desktop_specific/spark_coins/spark_coins_view.dart
Normal file
236
lib/pages_desktop_specific/spark_coins/spark_coins_view.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -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).
|
||||
|
|
Loading…
Reference in a new issue