Merge branch 'xmr-sync' into paynyms

# Conflicts:
#	lib/utilities/enums/coin_enum.dart
This commit is contained in:
julian 2023-01-02 13:47:10 -06:00
commit f9491f8215
51 changed files with 2931 additions and 3299 deletions

5
.gitignore vendored
View file

@ -50,3 +50,8 @@ test/services/coins/particl/particl_wallet_test_parameters.dart
coverage
scripts/**/build
/lib/external_api_keys.dart
libcw_monero.dll
libcw_wownero.dll
libepic_cash_wallet.dll
libmobileliblelantus.dll

@ -1 +1 @@
Subproject commit 9a150d8cd2c3625424b0059e6b7306f3659fdbe0
Subproject commit 0309140a95a51388df0effcc39ff0a25b2752b29

@ -1 +1 @@
Subproject commit db928e6f11844138ce87de2b8c1abe3305ec589e
Subproject commit 6864d7c0d4fa68c371e3f0c067afd50b0d59cc9b

@ -1 +1 @@
Subproject commit de29931dacc9aefaf42a9ca139a8754a42adc40d
Subproject commit 66eaa2f3c7133f1dbf0b1fc950e7a9e3cc611185

View file

@ -2,10 +2,10 @@ FROM ubuntu:20.04 as base
COPY . /stack_wallet
WORKDIR /stack_wallet/scripts/linux
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y git=1:2.25.1-1ubuntu3.6 make=4.2.1-1.2 curl=7.68.0-1ubuntu2.14 cargo=0.62.0ubuntu0libgit2-0ubuntu0.20.04.1 \
file=1:5.38-4 ca-certificates=20211016~20.04.1 cmake=3.16.3-1ubuntu1.20.04.1 cmake-data=3.16.3-1ubuntu1.20.04.1 g++=4:9.3.0-1ubuntu2 libgmp-dev=2:6.2.0+dfsg-4ubuntu0.1 libssl-dev=1.1.1f-1ubuntu2.16 libclang-dev=1:10.0-50~exp1 \
unzip=6.0-25ubuntu1.1 python3=3.8.2-0ubuntu2 pkg-config=0.29.1-0ubuntu4 libglib2.0-dev=2.64.6-1~ubuntu20.04.4 libgcrypt20-dev=1.8.5-5ubuntu1.1 gettext-base=0.19.8.1-10build1 libgirepository1.0-dev=1.64.1-1~ubuntu20.04.1 \
valac=0.48.6-0ubuntu1 xsltproc=1.1.34-4ubuntu0.20.04.1 docbook-xsl=1.79.1+dfsg-2 python3-pip=20.0.2-5ubuntu1.6 ninja-build=1.10.0-1build1 clang=1:10.0-50~exp1 libgtk-3-dev=3.24.20-0ubuntu1.1 \
libunbound-dev=1.9.4-2ubuntu1.4 libzmq3-dev=4.3.2-2ubuntu1 libtool=2.4.6-14 autoconf=2.69-11.1 automake=1:1.16.1-4ubuntu6 bison=2:3.5.1+dfsg-1 \
file=1:5.38-4 ca-certificates=20211016ubuntu0.20.04.1 cmake=3.16.3-1ubuntu1.20.04.1 cmake-data=3.16.3-1ubuntu1.20.04.1 g++=4:9.3.0-1ubuntu2 libgmp-dev=2:6.2.0+dfsg-4ubuntu0.1 libssl-dev=1.1.1f-1ubuntu2.16 \
libclang-dev=1:10.0-50~exp1 unzip=6.0-25ubuntu1.1 python3=3.8.2-0ubuntu2 pkg-config=0.29.1-0ubuntu4 libglib2.0-dev=2.64.6-1~ubuntu20.04.4 libgcrypt20-dev=1.8.5-5ubuntu1.1 gettext-base=0.19.8.1-10build1 \
libgirepository1.0-dev=1.64.1-1~ubuntu20.04.1 valac=0.48.6-0ubuntu1 xsltproc=1.1.34-4ubuntu0.20.04.1 docbook-xsl=1.79.1+dfsg-2 python3-pip=20.0.2-5ubuntu1.6 ninja-build=1.10.0-1build1 clang=1:10.0-50~exp1 \
libgtk-3-dev=3.24.20-0ubuntu1.1 libunbound-dev=1.9.4-2ubuntu1.4 libzmq3-dev=4.3.2-2ubuntu1 libtool=2.4.6-14 autoconf=2.69-11.1 automake=1:1.16.1-4ubuntu6 bison=2:3.5.1+dfsg-1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& pip3 install --upgrade meson==0.64.1 markdown==3.4.1 markupsafe==2.1.1 jinja2==3.1.2 pygments==2.13.0 toml==0.10.2 typogrify==2.0.7 tomli==2.0.1 && cd .. && ./prebuild.sh && cd linux && ./build_all.sh

View file

@ -7,7 +7,7 @@ import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.d
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
// import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
import 'package:stackwallet/utilities/logger.dart';
class ExchangeFormState extends ChangeNotifier {
@ -53,8 +53,8 @@ class ExchangeFormState extends ChangeNotifier {
return _from?.ticker;
case ExchangeRateType.fixed:
switch (exchange?.name) {
case SimpleSwapExchange.exchangeName:
return _from?.ticker;
// case SimpleSwapExchange.exchangeName:
// return _from?.ticker;
case ChangeNowExchange.exchangeName:
return market?.from;
default:
@ -69,8 +69,8 @@ class ExchangeFormState extends ChangeNotifier {
return _to?.ticker;
case ExchangeRateType.fixed:
switch (exchange?.name) {
case SimpleSwapExchange.exchangeName:
return _to?.ticker;
// case SimpleSwapExchange.exchangeName:
// return _to?.ticker;
case ChangeNowExchange.exchangeName:
return market?.to;
default:
@ -296,9 +296,9 @@ class ExchangeFormState extends ChangeNotifier {
}
Future<void> updateRanges({required bool shouldNotifyListeners}) async {
if (exchange?.name == SimpleSwapExchange.exchangeName) {
reversed = false;
}
// if (exchange?.name == SimpleSwapExchange.exchangeName) {
// reversed = false;
// }
final _fromTicker = reversed ? toTicker : fromTicker;
final _toTicker = reversed ? fromTicker : toTicker;
if (_fromTicker == null || _toTicker == null) {
@ -340,9 +340,9 @@ class ExchangeFormState extends ChangeNotifier {
required bool shouldNotifyListeners,
required bool reversed,
}) async {
if (exchange?.name == SimpleSwapExchange.exchangeName) {
reversed = false;
}
// if (exchange?.name == SimpleSwapExchange.exchangeName) {
// reversed = false;
// }
final amount = reversed ? toAmount : fromAmount;
if (fromTicker == null ||
toTicker == null ||

View file

@ -380,8 +380,9 @@ class Output {
factory Output.fromJson(Map<String, dynamic> json) {
// TODO determine if any of this code is needed.
// Particl has different tx types that need to be detected and handled here
if (json.containsKey('scriptPubKey') as bool) {
try {
// Particl has different tx types that need to be detected and handled here
// if (json.containsKey('scriptPubKey') as bool) {
// output is transparent
final address = json["scriptPubKey"]["addresses"] == null
? json['scriptPubKey']['type'] as String
@ -397,17 +398,30 @@ class Output {
.toBigInt()
.toInt(),
);
} /* else if (json.containsKey('ct_fee') as bool) {
// or type: data
// output is blinded (CT)
} else if (json.containsKey('rangeproof') as bool) {
// or valueCommitment or type: anon
// output is private (RingCT)
} */
else {
// TODO detect staking
// TODO handle CT, RingCT, and staking accordingly
// print("transaction not supported: ${json}");
// } /* else if (json.containsKey('ct_fee') as bool) {
// // or type: data
// // output is blinded (CT)
// } else if (json.containsKey('rangeproof') as bool) {
// // or valueCommitment or type: anon
// // output is private (RingCT)
// } */
// else {
// // TODO detect staking
// // TODO handle CT, RingCT, and staking accordingly
// // print("transaction not supported: ${json}");
// return Output(
// // Return output object with null values; allows wallet history to be built
// scriptpubkey: "",
// scriptpubkeyAsm: "",
// scriptpubkeyType: "",
// scriptpubkeyAddress: "",
// value: (Decimal.parse(0.toString()) *
// Decimal.fromInt(Constants.satsPerCoin(Coin
// .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
// .toBigInt()
// .toInt());
// }
} catch (s, e) {
return Output(
// Return output object with null values; allows wallet history to be built
scriptpubkey: "",

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/add_wallet_text.dart';
@ -37,11 +39,19 @@ class _AddWalletViewState extends State<AddWalletView> {
final List<Coin> coins = [...Coin.values];
final bool isDesktop = Util.isDesktop;
@override
void initState() {
_searchFieldController = TextEditingController();
_searchFocusNode = FocusNode();
coins.remove(Coin.firoTestNet);
if (isDesktop) {
coins.remove(Coin.wownero);
if (Platform.isWindows) {
coins.remove(Coin.monero);
}
}
super.initState();
}
@ -56,7 +66,7 @@ class _AddWalletViewState extends State<AddWalletView> {
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
if (Util.isDesktop) {
if (isDesktop) {
return DesktopScaffold(
appBar: const DesktopAppBar(
isCompactHeight: false,

View file

@ -33,9 +33,9 @@ class SearchableCoinList extends ConsumerWidget {
_coins.remove(Coin.firoTestNet);
// Kidgloves for Wownero on desktop
if(isDesktop) {
_coins.remove(Coin.wownero);
}
// if(isDesktop) {
// _coins.remove(Coin.wownero);
// }
return _coins;
}

View file

@ -19,6 +19,7 @@ import 'package:stackwallet/utilities/logger.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/conditional_parent.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';
@ -105,8 +106,25 @@ class _NewWalletRecoveryPhraseWarningViewState
)
],
),
body: Padding(
padding: EdgeInsets.all(isDesktop ? 0 : 16),
body: ConditionalParent(
condition: !isDesktop,
builder: (child) => LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: constraints.maxHeight,
),
child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(16),
child: child,
),
),
),
);
},
),
child: Column(
crossAxisAlignment: isDesktop
? CrossAxisAlignment.center
@ -315,9 +333,11 @@ class _NewWalletRecoveryPhraseWarningViewState
const SizedBox(
width: 20,
),
Text(
"Do not show them to anyone.",
style: STextStyles.navBarTitle(context),
Expanded(
child: Text(
"Do not show them to anyone.",
style: STextStyles.navBarTitle(context),
),
),
],
),
@ -327,6 +347,10 @@ class _NewWalletRecoveryPhraseWarningViewState
),
),
if (!isDesktop) const Spacer(),
if (!isDesktop)
const SizedBox(
height: 16,
),
if (isDesktop)
const SizedBox(
height: 32,

View file

@ -23,8 +23,6 @@ import 'package:stackwallet/utilities/util.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_date_picker/flutter_rounded_date_picker_widget.dart'
as datePicker;
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:tuple/tuple.dart';
@ -154,10 +152,46 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
await Future<void>.delayed(const Duration(milliseconds: 125));
}
final date = await datePicker.showRoundedDatePicker(
final date = await showRoundedDatePicker(
context: context,
initialDate: DateTime.now(),
height: height * 0.5,
height: height / 3.0,
theme: ThemeData(
primarySwatch: Util.createMaterialColor(fetchedColor),
),
//TODO pick a better initial date
// 2007 chosen as that is just before bitcoin launched
firstDate: DateTime(2007),
lastDate: DateTime.now(),
borderRadius: Constants.size.circularBorderRadius * 2,
textPositiveButton: "SELECT",
styleDatePicker: _buildDatePickerStyle(),
styleYearPicker: _buildYearPickerStyle(),
);
if (date != null) {
_restoreFromDate = date;
_dateController.text = Format.formatDate(date);
}
}
Future<void> chooseDesktopDate() async {
final height = MediaQuery.of(context).size.height;
final fetchedColor =
Theme.of(context).extension<StackColors>()!.accentColorDark;
// check and hide keyboard
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(const Duration(milliseconds: 125));
}
final now = DateTime.now();
final date = await showRoundedDatePicker(
context: context,
initialDate: DateTime.now(),
height: height / 3.0,
theme: ThemeData(
primarySwatch: Util.createMaterialColor(fetchedColor),
),
@ -283,15 +317,22 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
(coin == Coin.wownero &&
ref.watch(mnemonicWordCountStateProvider.state).state ==
25))
// if (!isDesktop)
RestoreFromDatePicker(
onTap: chooseDate,
controller: _dateController,
),
// if (isDesktop)
// // TODO desktop date picker
if (!isDesktop)
RestoreFromDatePicker(
onTap: chooseDate,
controller: _dateController,
),
if (coin == Coin.monero ||
coin == Coin.epicCash ||
(coin == Coin.wownero &&
ref.watch(mnemonicWordCountStateProvider.state).state ==
25))
if (isDesktop)
// TODO desktop date picker
RestoreFromDatePicker(
onTap: chooseDesktopDate,
controller: _dateController,
),
if (coin == Coin.monero ||
coin == Coin.epicCash ||
(coin == Coin.wownero &&
@ -412,7 +453,6 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
isDesktop: isDesktop,
onPressed: _nextEnabled ? nextPressed : null,
),
if (isDesktop)
const Spacer(
flex: 15,

View file

@ -736,6 +736,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
child: Column(
children: [
TextFormField(
autocorrect: !isDesktop,
enableSuggestions: !isDesktop,
textCapitalization:
TextCapitalization.none,
key: Key(
@ -831,6 +833,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
child: Column(
children: [
TextFormField(
autocorrect: !isDesktop,
enableSuggestions: !isDesktop,
textCapitalization:
TextCapitalization.none,
key: Key(
@ -954,6 +958,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
padding:
const EdgeInsets.symmetric(vertical: 4),
child: TextFormField(
autocorrect: !isDesktop,
enableSuggestions: !isDesktop,
textCapitalization:
TextCapitalization.none,
key: Key("restoreMnemonicFormField_$i"),

View file

@ -161,7 +161,7 @@ class _VerifyRecoveryPhraseViewState
result.insert(random.nextInt(wordsToShow), chosenWord);
//todo: this prints sensitive info
// debugPrint("Mnemonic game correct word: $chosenWord");
debugPrint("Mnemonic game correct word: $chosenWord");
return Tuple2(result, chosenWord);
}

View file

@ -20,7 +20,7 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/rate_type_toggle.dar
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
// import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -69,17 +69,21 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
bool _swapLock = false;
void sendFieldOnChanged(String value) async {
final newFromAmount = Decimal.tryParse(value);
if (_sendFocusNode.hasFocus) {
final newFromAmount = Decimal.tryParse(value);
ref.read(exchangeFormStateProvider).fromAmount =
newFromAmount ?? Decimal.zero;
await ref
.read(exchangeFormStateProvider)
.setFromAmountAndCalculateToAmount(
newFromAmount ?? Decimal.zero, true);
if (newFromAmount == null) {
_receiveController.text =
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
ExchangeRateType.estimated
? "-"
: "";
if (newFromAmount == null) {
_receiveController.text =
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
ExchangeRateType.estimated
? "-"
: "";
}
}
}
@ -101,11 +105,11 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
currencies =
ref.read(availableChangeNowCurrenciesProvider).currencies;
break;
case SimpleSwapExchange.exchangeName:
currencies = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies;
break;
// case SimpleSwapExchange.exchangeName:
// currencies = ref
// .read(availableSimpleswapCurrenciesProvider)
// .floatingRateCurrencies;
// break;
default:
currencies = [];
}
@ -116,6 +120,31 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
fromTicker: fromTicker,
onSelected: (from) =>
ref.read(exchangeFormStateProvider).updateFrom(from, true));
unawaited(
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (_) => WillPopScope(
onWillPop: () async => false,
child: Container(
color: Theme.of(context)
.extension<StackColors>()!
.overlay
.withOpacity(0.6),
child: const CustomLoadingOverlay(
message: "Updating exchange rate",
eventBus: null,
),
),
),
),
);
await Future<void>.delayed(const Duration(milliseconds: 300));
Navigator.of(context, rootNavigator: true).pop();
} else {
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
@ -170,17 +199,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
},
);
break;
case SimpleSwapExchange.exchangeName:
await _showFloatingRateSelectionSheet(
currencies: ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies,
excludedTicker:
ref.read(exchangeFormStateProvider).toTicker ?? "-",
fromTicker: fromTicker,
onSelected: (from) =>
ref.read(exchangeFormStateProvider).updateFrom(from, true));
break;
// case SimpleSwapExchange.exchangeName:
// await _showFloatingRateSelectionSheet(
// currencies: ref
// .read(availableSimpleswapCurrenciesProvider)
// .fixedRateCurrencies,
// excludedTicker:
// ref.read(exchangeFormStateProvider).toTicker ?? "-",
// fromTicker: fromTicker,
// onSelected: (from) =>
// ref.read(exchangeFormStateProvider).updateFrom(from, true));
// break;
default:
// TODO show error?
}
@ -204,11 +233,11 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
currencies =
ref.read(availableChangeNowCurrenciesProvider).currencies;
break;
case SimpleSwapExchange.exchangeName:
currencies = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies;
break;
// case SimpleSwapExchange.exchangeName:
// currencies = ref
// .read(availableSimpleswapCurrenciesProvider)
// .floatingRateCurrencies;
// break;
default:
currencies = [];
}
@ -272,17 +301,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
},
);
break;
case SimpleSwapExchange.exchangeName:
await _showFloatingRateSelectionSheet(
currencies: ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies,
excludedTicker:
ref.read(exchangeFormStateProvider).fromTicker ?? "",
fromTicker: ref.read(exchangeFormStateProvider).fromTicker ?? "",
onSelected: (to) =>
ref.read(exchangeFormStateProvider).updateTo(to, true));
break;
// case SimpleSwapExchange.exchangeName:
// await _showFloatingRateSelectionSheet(
// currencies: ref
// .read(availableSimpleswapCurrenciesProvider)
// .fixedRateCurrencies,
// excludedTicker:
// ref.read(exchangeFormStateProvider).fromTicker ?? "",
// fromTicker: ref.read(exchangeFormStateProvider).fromTicker ?? "",
// onSelected: (to) =>
// ref.read(exchangeFormStateProvider).updateTo(to, true));
// break;
default:
// TODO show error?
}
@ -374,12 +403,12 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
case ChangeNowExchange.exchangeName:
allPairs = ref.read(availableChangeNowCurrenciesProvider).pairs;
break;
case SimpleSwapExchange.exchangeName:
allPairs = ref.read(exchangeFormStateProvider).exchangeType ==
ExchangeRateType.fixed
? ref.read(availableSimpleswapCurrenciesProvider).fixedRatePairs
: ref.read(availableSimpleswapCurrenciesProvider).floatingRatePairs;
break;
// case SimpleSwapExchange.exchangeName:
// allPairs = ref.read(exchangeFormStateProvider).exchangeType ==
// ExchangeRateType.fixed
// ? ref.read(availableSimpleswapCurrenciesProvider).fixedRatePairs
// : ref.read(availableSimpleswapCurrenciesProvider).floatingRatePairs;
// break;
default:
allPairs = [];
}
@ -486,18 +515,18 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
.currencies
.where((e) => e.ticker.toUpperCase() == ticker.toUpperCase());
break;
case SimpleSwapExchange.exchangeName:
possibleCurrencies = [
...ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies
.where((e) => e.ticker.toUpperCase() == ticker.toUpperCase()),
...ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies
.where((e) => e.ticker.toUpperCase() == ticker.toUpperCase()),
];
break;
// case SimpleSwapExchange.exchangeName:
// possibleCurrencies = [
// ...ref
// .read(availableSimpleswapCurrenciesProvider)
// .fixedRateCurrencies
// .where((e) => e.ticker.toUpperCase() == ticker.toUpperCase()),
// ...ref
// .read(availableSimpleswapCurrenciesProvider)
// .floatingRateCurrencies
// .where((e) => e.ticker.toUpperCase() == ticker.toUpperCase()),
// ];
// break;
default:
possibleCurrencies = [];
}
@ -655,12 +684,12 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
.pairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
case SimpleSwapExchange.exchangeName:
available = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRatePairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
// case SimpleSwapExchange.exchangeName:
// available = ref
// .read(availableSimpleswapCurrenciesProvider)
// .floatingRatePairs
// .where((e) => e.to == toTicker && e.from == fromTicker);
// break;
default:
available = [];
}
@ -675,13 +704,13 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
.where(
(e) => e.ticker == fromTicker || e.ticker == toTicker);
break;
case SimpleSwapExchange.exchangeName:
availableCurrencies = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRateCurrencies
.where(
(e) => e.ticker == fromTicker || e.ticker == toTicker);
break;
// case SimpleSwapExchange.exchangeName:
// availableCurrencies = ref
// .read(availableSimpleswapCurrenciesProvider)
// .floatingRateCurrencies
// .where(
// (e) => e.ticker == fromTicker || e.ticker == toTicker);
// break;
default:
availableCurrencies = [];
}
@ -763,47 +792,47 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
Navigator.of(context, rootNavigator: isDesktop).pop();
}
return;
case SimpleSwapExchange.exchangeName:
final available = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRatePairs
.where((e) => e.to == toTicker && e.from == fromTicker);
if (available.isNotEmpty) {
final availableCurrencies = ref
.read(availableSimpleswapCurrenciesProvider)
.fixedRateCurrencies
.where(
(e) => e.ticker == fromTicker || e.ticker == toTicker);
if (availableCurrencies.length > 1) {
final from = availableCurrencies
.firstWhere((e) => e.ticker == fromTicker);
final to = availableCurrencies
.firstWhere((e) => e.ticker == toTicker);
final newFromAmount = Decimal.tryParse(_sendController.text);
ref.read(exchangeFormStateProvider).fromAmount =
newFromAmount ?? Decimal.zero;
if (newFromAmount == null) {
_receiveController.text = "";
}
await ref.read(exchangeFormStateProvider).updateTo(to, false);
await ref
.read(exchangeFormStateProvider)
.updateFrom(from, true);
_receiveController.text =
ref.read(exchangeFormStateProvider).toAmountString.isEmpty
? "-"
: ref.read(exchangeFormStateProvider).toAmountString;
if (mounted) {
Navigator.of(context, rootNavigator: isDesktop).pop();
}
return;
}
}
break;
// case SimpleSwapExchange.exchangeName:
// final available = ref
// .read(availableSimpleswapCurrenciesProvider)
// .floatingRatePairs
// .where((e) => e.to == toTicker && e.from == fromTicker);
// if (available.isNotEmpty) {
// final availableCurrencies = ref
// .read(availableSimpleswapCurrenciesProvider)
// .fixedRateCurrencies
// .where(
// (e) => e.ticker == fromTicker || e.ticker == toTicker);
// if (availableCurrencies.length > 1) {
// final from = availableCurrencies
// .firstWhere((e) => e.ticker == fromTicker);
// final to = availableCurrencies
// .firstWhere((e) => e.ticker == toTicker);
//
// final newFromAmount = Decimal.tryParse(_sendController.text);
// ref.read(exchangeFormStateProvider).fromAmount =
// newFromAmount ?? Decimal.zero;
// if (newFromAmount == null) {
// _receiveController.text = "";
// }
//
// await ref.read(exchangeFormStateProvider).updateTo(to, false);
// await ref
// .read(exchangeFormStateProvider)
// .updateFrom(from, true);
//
// _receiveController.text =
// ref.read(exchangeFormStateProvider).toAmountString.isEmpty
// ? "-"
// : ref.read(exchangeFormStateProvider).toAmountString;
// if (mounted) {
// Navigator.of(context, rootNavigator: isDesktop).pop();
// }
// return;
// }
// }
//
// break;
default:
//
}
@ -844,12 +873,12 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
.pairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
case SimpleSwapExchange.exchangeName:
availableFloatingPairs = ref
.read(availableSimpleswapCurrenciesProvider)
.floatingRatePairs
.where((e) => e.to == toTicker && e.from == fromTicker);
break;
// case SimpleSwapExchange.exchangeName:
// availableFloatingPairs = ref
// .read(availableSimpleswapCurrenciesProvider)
// .floatingRatePairs
// .where((e) => e.to == toTicker && e.from == fromTicker);
// break;
default:
availableFloatingPairs = [];
}
@ -1117,38 +1146,43 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
: ref.read(exchangeFormStateProvider).toAmountString;
}
_sendFocusNode.addListener(() async {
if (!_sendFocusNode.hasFocus) {
final newFromAmount = Decimal.tryParse(_sendController.text);
await ref
.read(exchangeFormStateProvider)
.setFromAmountAndCalculateToAmount(
newFromAmount ?? Decimal.zero, true);
if (newFromAmount == null) {
_receiveController.text =
ref.read(prefsChangeNotifierProvider).exchangeRateType ==
ExchangeRateType.estimated
? "-"
: "";
}
}
});
_receiveFocusNode.addListener(() async {
if (!_receiveFocusNode.hasFocus) {
final newToAmount = Decimal.tryParse(_receiveController.text);
if (ref.read(prefsChangeNotifierProvider).exchangeRateType !=
ExchangeRateType.estimated) {
await ref
.read(exchangeFormStateProvider)
.setToAmountAndCalculateFromAmount(
newToAmount ?? Decimal.zero, true);
}
if (newToAmount == null) {
_sendController.text = "";
}
}
});
// _sendFocusNode.addListener(() async {
// if (!_sendFocusNode.hasFocus) {
// final newFromAmount = Decimal.tryParse(_sendController.text);
// await ref
// .read(exchangeFormStateProvider)
// .setFromAmountAndCalculateToAmount(
// newFromAmount ?? Decimal.zero, true);
//
// debugPrint("SendFocusNode has fired");
//
// if (newFromAmount == null) {
// _receiveController.text =
// ref.read(prefsChangeNotifierProvider).exchangeRateType ==
// ExchangeRateType.estimated
// ? "-"
// : "";
// }
// }
// });
//
// _receiveFocusNode.addListener(() async {
// if (!_receiveFocusNode.hasFocus) {
// final newToAmount = Decimal.tryParse(_receiveController.text);
// if (ref.read(prefsChangeNotifierProvider).exchangeRateType !=
// ExchangeRateType.estimated) {
// await ref
// .read(exchangeFormStateProvider)
// .setToAmountAndCalculateFromAmount(
// newToAmount ?? Decimal.zero, true);
//
// debugPrint("ReceiveFocusNode has fired");
// }
// if (newToAmount == null) {
// _sendController.text = "";
// }
// }
// });
super.initState();
}
@ -1164,6 +1198,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
// provider for simpleswap; not called rn
ref.listen<String>(currentExchangeNameStateProvider, (previous, next) {
ref.read(exchangeFormStateProvider).exchange = ref.read(exchangeProvider);
});
@ -1176,12 +1211,9 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
exchangeFormStateProvider.select((value) => value.toAmountString),
(previous, String next) {
if (!_receiveFocusNode.hasFocus) {
_receiveController.text = isEstimated &&
ref.watch(exchangeProvider).name ==
SimpleSwapExchange.exchangeName &&
next.isEmpty
? "-"
: next;
// ref.watch(exchangeProvider).name ==
// SimpleSwapExchange.exchangeName &&
_receiveController.text = isEstimated && next.isEmpty ? "-" : next;
//todo: check if print needed
// debugPrint("RECEIVE AMOUNT LISTENER ACTIVATED");
if (_swapLock) {
@ -1334,10 +1366,11 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
ticker: ref.watch(
exchangeFormStateProvider.select((value) => value.toTicker)),
readOnly: ref.watch(prefsChangeNotifierProvider
.select((value) => value.exchangeRateType)) ==
ExchangeRateType.estimated ||
ref.watch(exchangeProvider).name ==
SimpleSwapExchange.exchangeName,
.select((value) => value.exchangeRateType)) ==
ExchangeRateType.estimated,
// ||
// ref.watch(exchangeProvider).name ==
// SimpleSwapExchange.exchangeName,
),
if (ref
.watch(
@ -1359,13 +1392,15 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
onChanged: onRateTypeChanged,
),
),
if (ref.read(exchangeFormStateProvider).fromAmount != null &&
ref.read(exchangeFormStateProvider).fromAmount != Decimal.zero)
// these reads should be watch
if (ref.watch(exchangeFormStateProvider).fromAmount != null &&
ref.watch(exchangeFormStateProvider).fromAmount != Decimal.zero)
SizedBox(
height: isDesktop ? 20 : 12,
),
if (ref.read(exchangeFormStateProvider).fromAmount != null &&
ref.read(exchangeFormStateProvider).fromAmount != Decimal.zero)
// these reads should be watch
if (ref.watch(exchangeFormStateProvider).fromAmount != null &&
ref.watch(exchangeFormStateProvider).fromAmount != Decimal.zero)
ExchangeProviderOptions(
from: ref.watch(exchangeFormStateProvider).fromTicker,
to: ref.watch(exchangeFormStateProvider).toTicker,

View file

@ -7,7 +7,6 @@ import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart';
import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -78,35 +77,43 @@ class ExchangeProviderOptions extends ConsumerWidget {
SizedBox(
width: 20,
height: 20,
child: Radio(
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: ChangeNowExchange.exchangeName,
groupValue: ref
.watch(currentExchangeNameStateProvider.state)
.state,
onChanged: (value) {
if (value is String) {
ref
.read(currentExchangeNameStateProvider.state)
.state = value;
ref.read(exchangeFormStateProvider).exchange =
Exchange.fromName(ref
.read(currentExchangeNameStateProvider
.state)
.state);
}
},
child: Padding(
padding:
EdgeInsets.only(top: isDesktop ? 20.0 : 15.0),
child: Radio(
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: ChangeNowExchange.exchangeName,
groupValue: ref
.watch(currentExchangeNameStateProvider.state)
.state,
onChanged: (value) {
if (value is String) {
ref
.read(
currentExchangeNameStateProvider.state)
.state = value;
ref.read(exchangeFormStateProvider).exchange =
Exchange.fromName(ref
.read(currentExchangeNameStateProvider
.state)
.state);
}
},
),
),
),
const SizedBox(
width: 14,
),
SvgPicture.asset(
Assets.exchange.changeNow,
width: isDesktop ? 32 : 24,
height: isDesktop ? 32 : 24,
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: SvgPicture.asset(
Assets.exchange.changeNow,
width: isDesktop ? 32 : 24,
height: isDesktop ? 32 : 24,
),
),
const SizedBox(
width: 10,
@ -250,207 +257,207 @@ class ExchangeProviderOptions extends ConsumerWidget {
height: 1,
color: Theme.of(context).extension<StackColors>()!.background,
),
if (!isDesktop)
const SizedBox(
height: 16,
),
ConditionalParent(
condition: isDesktop,
builder: (child) => MouseRegion(
cursor: SystemMouseCursors.click,
child: child,
),
child: GestureDetector(
onTap: () {
if (ref.read(currentExchangeNameStateProvider.state).state !=
SimpleSwapExchange.exchangeName) {
ref.read(currentExchangeNameStateProvider.state).state =
SimpleSwapExchange.exchangeName;
ref.read(exchangeFormStateProvider).exchange =
Exchange.fromName(ref
.read(currentExchangeNameStateProvider.state)
.state);
}
},
child: Container(
color: Colors.transparent,
child: Padding(
padding: isDesktop
? const EdgeInsets.all(16)
: const EdgeInsets.all(0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 20,
height: 20,
child: Radio(
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: SimpleSwapExchange.exchangeName,
groupValue: ref
.watch(currentExchangeNameStateProvider.state)
.state,
onChanged: (value) {
if (value is String) {
ref
.read(currentExchangeNameStateProvider.state)
.state = value;
ref.read(exchangeFormStateProvider).exchange =
Exchange.fromName(ref
.read(currentExchangeNameStateProvider
.state)
.state);
}
},
),
),
const SizedBox(
width: 14,
),
SvgPicture.asset(
Assets.exchange.simpleSwap,
width: isDesktop ? 32 : 24,
height: isDesktop ? 32 : 24,
),
const SizedBox(
width: 10,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
SimpleSwapExchange.exchangeName,
style: STextStyles.titleBold12(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark2,
),
),
if (from != null &&
to != null &&
toAmount != null &&
toAmount! > Decimal.zero &&
fromAmount != null &&
fromAmount! > Decimal.zero)
FutureBuilder(
future: SimpleSwapExchange().getEstimate(
from!,
to!,
// reversed ? toAmount! : fromAmount!,
fromAmount!,
fixedRate,
// reversed,
false,
),
builder: (context,
AsyncSnapshot<ExchangeResponse<Estimate>>
snapshot) {
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
final estimate = snapshot.data?.value;
if (estimate != null) {
Decimal rate = (estimate.estimatedAmount /
fromAmount!)
.toDecimal(
scaleOnInfinitePrecision: 12);
Coin coin;
try {
coin =
coinFromTickerCaseInsensitive(to!);
} catch (_) {
coin = Coin.bitcoin;
}
return Text(
"1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
value: rate,
locale: ref.watch(
localeServiceChangeNotifierProvider
.select(
(value) => value.locale),
),
decimalPlaces:
Constants.decimalPlacesForCoin(
coin),
)} ${to!.toUpperCase()}",
style:
STextStyles.itemSubtitle12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
);
} else {
Logging.instance.log(
"$runtimeType failed to fetch rate for SimpleSwap: ${snapshot.data}",
level: LogLevel.Warning,
);
return Text(
"Failed to fetch rate",
style:
STextStyles.itemSubtitle12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
);
}
} else {
return AnimatedText(
stringsToLoopThrough: const [
"Loading",
"Loading.",
"Loading..",
"Loading...",
],
style: STextStyles.itemSubtitle12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
);
}
},
),
// if (!(from != null &&
// to != null &&
// (reversed
// ? toAmount != null && toAmount! > Decimal.zero
// : fromAmount != null &&
// fromAmount! > Decimal.zero)))
if (!(from != null &&
to != null &&
toAmount != null &&
toAmount! > Decimal.zero &&
fromAmount != null &&
fromAmount! > Decimal.zero))
Text(
"n/a",
style: STextStyles.itemSubtitle12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
],
),
),
],
),
),
),
),
),
// if (!isDesktop)
// const SizedBox(
// height: 16,
// ),
// ConditionalParent(
// condition: isDesktop,
// builder: (child) => MouseRegion(
// cursor: SystemMouseCursors.click,
// child: child,
// ),
// child: GestureDetector(
// onTap: () {
// if (ref.read(currentExchangeNameStateProvider.state).state !=
// SimpleSwapExchange.exchangeName) {
// // ref.read(currentExchangeNameStateProvider.state).state =
// // SimpleSwapExchange.exchangeName;
// ref.read(exchangeFormStateProvider).exchange =
// Exchange.fromName(ref
// .read(currentExchangeNameStateProvider.state)
// .state);
// }
// },
// child: Container(
// color: Colors.transparent,
// child: Padding(
// padding: isDesktop
// ? const EdgeInsets.all(16)
// : const EdgeInsets.all(0),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// SizedBox(
// width: 20,
// height: 20,
// child: Radio(
// activeColor: Theme.of(context)
// .extension<StackColors>()!
// .radioButtonIconEnabled,
// value: SimpleSwapExchange.exchangeName,
// groupValue: ref
// .watch(currentExchangeNameStateProvider.state)
// .state,
// onChanged: (value) {
// if (value is String) {
// ref
// .read(currentExchangeNameStateProvider.state)
// .state = value;
// ref.read(exchangeFormStateProvider).exchange =
// Exchange.fromName(ref
// .read(currentExchangeNameStateProvider
// .state)
// .state);
// }
// },
// ),
// ),
// const SizedBox(
// width: 14,
// ),
// // SvgPicture.asset(
// // Assets.exchange.simpleSwap,
// // width: isDesktop ? 32 : 24,
// // height: isDesktop ? 32 : 24,
// // ),
// // const SizedBox(
// // width: 10,
// // ),
// // Expanded(
// // child: Column(
// // mainAxisAlignment: MainAxisAlignment.start,
// // mainAxisSize: MainAxisSize.min,
// // crossAxisAlignment: CrossAxisAlignment.start,
// // children: [
// // Text(
// // SimpleSwapExchange.exchangeName,
// // style: STextStyles.titleBold12(context).copyWith(
// // color: Theme.of(context)
// // .extension<StackColors>()!
// // .textDark2,
// // ),
// // ),
// // if (from != null &&
// // to != null &&
// // toAmount != null &&
// // toAmount! > Decimal.zero &&
// // fromAmount != null &&
// // fromAmount! > Decimal.zero)
// // FutureBuilder(
// // future: SimpleSwapExchange().getEstimate(
// // from!,
// // to!,
// // // reversed ? toAmount! : fromAmount!,
// // fromAmount!,
// // fixedRate,
// // // reversed,
// // false,
// // ),
// // builder: (context,
// // AsyncSnapshot<ExchangeResponse<Estimate>>
// // snapshot) {
// // if (snapshot.connectionState ==
// // ConnectionState.done &&
// // snapshot.hasData) {
// // final estimate = snapshot.data?.value;
// // if (estimate != null) {
// // Decimal rate = (estimate.estimatedAmount /
// // fromAmount!)
// // .toDecimal(
// // scaleOnInfinitePrecision: 12);
// //
// // Coin coin;
// // try {
// // coin =
// // coinFromTickerCaseInsensitive(to!);
// // } catch (_) {
// // coin = Coin.bitcoin;
// // }
// // return Text(
// // "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
// // value: rate,
// // locale: ref.watch(
// // localeServiceChangeNotifierProvider
// // .select(
// // (value) => value.locale),
// // ),
// // decimalPlaces:
// // Constants.decimalPlacesForCoin(
// // coin),
// // )} ${to!.toUpperCase()}",
// // style:
// // STextStyles.itemSubtitle12(context)
// // .copyWith(
// // color: Theme.of(context)
// // .extension<StackColors>()!
// // .textSubtitle1,
// // ),
// // );
// // } else {
// // Logging.instance.log(
// // "$runtimeType failed to fetch rate for SimpleSwap: ${snapshot.data}",
// // level: LogLevel.Warning,
// // );
// // return Text(
// // "Failed to fetch rate",
// // style:
// // STextStyles.itemSubtitle12(context)
// // .copyWith(
// // color: Theme.of(context)
// // .extension<StackColors>()!
// // .textSubtitle1,
// // ),
// // );
// // }
// // } else {
// // return AnimatedText(
// // stringsToLoopThrough: const [
// // "Loading",
// // "Loading.",
// // "Loading..",
// // "Loading...",
// // ],
// // style: STextStyles.itemSubtitle12(context)
// // .copyWith(
// // color: Theme.of(context)
// // .extension<StackColors>()!
// // .textSubtitle1,
// // ),
// // );
// // }
// // },
// // ),
// // // if (!(from != null &&
// // // to != null &&
// // // (reversed
// // // ? toAmount != null && toAmount! > Decimal.zero
// // // : fromAmount != null &&
// // // fromAmount! > Decimal.zero)))
// // if (!(from != null &&
// // to != null &&
// // toAmount != null &&
// // toAmount! > Decimal.zero &&
// // fromAmount != null &&
// // fromAmount! > Decimal.zero))
// // Text(
// // "n/a",
// // style: STextStyles.itemSubtitle12(context)
// // .copyWith(
// // color: Theme.of(context)
// // .extension<StackColors>()!
// // .textSubtitle1,
// // ),
// // ),
// // ],
// // ),
// // ),
// ],
// ),
// ),
// ),
// ),
// ),
],
),
);

View file

@ -409,8 +409,9 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
height: 1.8,
)
: STextStyles.field(context),
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
keyboardType: Util.isDesktop
? null
: const TextInputType.numberWithOptions(decimal: true),
onChanged: (_) => setState(() {}),
decoration: standardInputDecoration(
"Amount",

View file

@ -1111,10 +1111,12 @@ class _SendViewState extends ConsumerState<SendView> {
const Key("amountInputFieldCryptoTextFieldKey"),
controller: cryptoAmountController,
focusNode: _cryptoFocus,
keyboardType: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
keyboardType: Util.isDesktop
? null
: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
textAlign: TextAlign.right,
inputFormatters: [
// regex to validate a crypto amount with 8 decimal places
@ -1168,11 +1170,12 @@ class _SendViewState extends ConsumerState<SendView> {
const Key("amountInputFieldFiatTextFieldKey"),
controller: baseAmountController,
focusNode: _baseFocus,
keyboardType:
const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
keyboardType: Util.isDesktop
? null
: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
textAlign: TextAlign.right,
inputFormatters: [
// regex to validate a fiat amount with 2 decimal places

View file

@ -20,7 +20,6 @@ import 'package:stackwallet/providers/global/debug_service_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/stack_file_system.dart';
import 'package:stackwallet/utilities/text_styles.dart';

View file

@ -391,7 +391,8 @@ class _EpiBoxInfoFormState extends ConsumerState<EpicBoxInfoForm> {
enableSuggestions: Util.isDesktop ? false : true,
controller: portController,
decoration: const InputDecoration(hintText: "Port"),
keyboardType: const TextInputType.numberWithOptions(),
keyboardType:
Util.isDesktop ? null : const TextInputType.numberWithOptions(),
),
const SizedBox(
height: 8,

View file

@ -57,7 +57,7 @@ class DeleteWalletWarningView extends ConsumerWidget {
.extension<StackColors>()!
.warningBackground,
child: Text(
"You are going to permanently delete you wallet.\n\nIf you delete your wallet, the only way you can have access to your funds is by using your backup key.\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet.\n\nPLEASE SAVE YOUR BACKUP KEY.",
"You are going to permanently delete your wallet.\n\nIf you delete your wallet, the only way you can have access to your funds is by using your backup key.\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet.\n\nPLEASE SAVE YOUR BACKUP KEY.",
style: STextStyles.baseXS(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!

View file

@ -739,10 +739,12 @@ class _TransactionSearchViewState
controller: _amountTextEditingController,
focusNode: amountTextFieldFocusNode,
onChanged: (_) => setState(() {}),
keyboardType: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
keyboardType: Util.isDesktop
? null
: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
inputFormatters: [
// regex to validate a crypto amount with 8 decimal places
TextInputFormatter.withFunction((oldValue, newValue) =>

View file

@ -60,6 +60,14 @@ class CoinWalletsTable extends ConsumerWidget {
ref.read(currentWalletIdProvider.state).state =
walletIds[i];
final manager = ref
.read(walletsChangeNotifierProvider)
.getManager(walletIds[i]);
if (manager.coin == Coin.monero ||
manager.coin == Coin.wownero) {
await manager.initializeExisting();
}
await Navigator.of(context).pushNamed(
DesktopWalletView.routeName,
arguments: walletIds[i],

View file

@ -42,6 +42,9 @@ class _ContactListItemState extends ConsumerState<ContactListItem> {
final contact = ref.watch(addressBookServiceProvider
.select((value) => value.getContactById(contactId)));
// hack fix until we use a proper database (not Hive)
int i = 0;
return RoundedWhiteContainer(
padding: const EdgeInsets.all(0),
borderColor: Theme.of(context).extension<StackColors>()!.background,
@ -70,7 +73,8 @@ class _ContactListItemState extends ConsumerState<ContactListItem> {
filterByCoin != null ? e.coin == filterByCoin! : true)
.map(
(e) => Column(
key: Key("contactAddress_${e.address}_${e.label}_key"),
key: Key(
"contactAddress_${e.address}_${e.label}_${++i}_key"),
mainAxisSize: MainAxisSize.min,
children: [
Container(

View file

@ -66,7 +66,7 @@ class _DesktopAttentionDeleteWallet
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
"You are going to permanently delete you wallet.\n\nIf you delete your wallet, "
"You are going to permanently delete your wallet.\n\nIf you delete your wallet, "
"the only way you can have access to your funds is by using your backup key."
"\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet."
"\n\nPLEASE SAVE YOUR BACKUP KEY.",
@ -74,7 +74,7 @@ class _DesktopAttentionDeleteWallet
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
.snackBarTextError,
),
),
),

View file

@ -140,17 +140,21 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
const SizedBox(
height: 40,
),
Padding(
padding: const EdgeInsets.only(
right: 32,
),
child: SecondaryButton(
buttonHeight: ButtonHeight.l,
label: "Ok",
onPressed: () {
Navigator.of(context).pop();
},
),
Row(
children: [
Expanded(
child: SecondaryButton(
buttonHeight: ButtonHeight.l,
label: "Ok",
onPressed: () {
Navigator.of(context).pop();
},
),
),
const SizedBox(
width: 32,
),
],
),
],
),
@ -319,13 +323,13 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
}
if (!wasCancelled && mounted) {
txData["note"] = _note ?? "";
txData["address"] = _address;
// pop building dialog
Navigator.of(
context,
rootNavigator: true,
).pop();
txData["note"] = _note;
txData["address"] = _address;
unawaited(
showDialog(
@ -394,22 +398,24 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
const SizedBox(
height: 40,
),
Padding(
padding: const EdgeInsets.only(
right: 32,
),
child: Expanded(
child: SecondaryButton(
buttonHeight: ButtonHeight.l,
label: "Yes",
onPressed: () {
Navigator.of(
context,
rootNavigator: true,
).pop();
},
Row(
children: [
Expanded(
child: SecondaryButton(
buttonHeight: ButtonHeight.l,
label: "Ok",
onPressed: () {
Navigator.of(
context,
rootNavigator: true,
).pop();
},
),
),
),
const SizedBox(
width: 32,
),
],
),
],
),
@ -1002,10 +1008,12 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
key: const Key("amountInputFieldCryptoTextFieldKey"),
controller: cryptoAmountController,
focusNode: _cryptoFocus,
keyboardType: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
keyboardType: Util.isDesktop
? null
: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
textAlign: TextAlign.right,
inputFormatters: [
// regex to validate a crypto amount with 8 decimal places
@ -1056,10 +1064,12 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
key: const Key("amountInputFieldFiatTextFieldKey"),
controller: baseAmountController,
focusNode: _baseFocus,
keyboardType: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
keyboardType: Util.isDesktop
? null
: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
textAlign: TextAlign.right,
inputFormatters: [
// regex to validate a fiat amount with 2 decimal places

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
@ -46,10 +48,18 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
.toList();
}
final bool isDesktop = Util.isDesktop;
@override
void initState() {
_coins = _coins.toList();
_coins.remove(Coin.firoTestNet);
if (isDesktop) {
_coins.remove(Coin.wownero);
if (Platform.isWindows) {
_coins.remove(Coin.monero);
}
}
searchNodeController = TextEditingController();
searchNodeFocusNode = FocusNode();
@ -128,8 +138,8 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
Constants.size.circularBorderRadius,
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
autocorrect: !isDesktop,
enableSuggestions: !isDesktop,
controller: searchNodeController,
focusNode: searchNodeFocusNode,
onChanged: (newString) {

View file

@ -1297,7 +1297,7 @@ class BitcoinWallet extends CoinServiceAPI {
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /

View file

@ -1174,7 +1174,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
@ -2666,8 +2666,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
], // dust limit is the minimum amount a change output should be
))["vSize"] as int;
//todo: check if print needed
debugPrint("vSizeForOneOutput $vSizeForOneOutput");
debugPrint("vSizeForTwoOutPuts $vSizeForTwoOutPuts");
// debugPrint("vSizeForOneOutput $vSizeForOneOutput");
// debugPrint("vSizeForTwoOutPuts $vSizeForTwoOutPuts");
// Assume 1 output, only for recipient and no change
var feeForOneOutput = estimateTxFee(

View file

@ -178,7 +178,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
secureStorage: secureStorageInterface,
// tracker: tracker,
);
@ -197,7 +197,7 @@ abstract class CoinServiceAPI {
walletId: walletId,
walletName: walletName,
coin: coin,
secureStore: secureStorageInterface,
secureStorage: secureStorageInterface,
// tracker: tracker,
);

View file

@ -1063,7 +1063,7 @@ class DogecoinWallet extends CoinServiceAPI {
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /

View file

@ -883,7 +883,7 @@ class FiroWallet extends CoinServiceAPI {
@override
Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async {
final currentPrice = await firoPrice;
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
@ -2756,7 +2756,7 @@ class FiroWallet extends CoinServiceAPI {
var price = await firoPrice;
var builtHex = txb.build();
// return builtHex;
final locale = await Devicelocale.currentLocale;
final locale =Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
return {
"transaction": builtHex,
"txid": txId,
@ -2810,7 +2810,7 @@ class FiroWallet extends CoinServiceAPI {
final currentPrice = await firoPrice;
// Grab the most recent information on all the joinsplits
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final updatedJSplit = await getJMintTransactions(cachedElectrumXClient,
joinsplits, _prefs.currency, coin, currentPrice, locale!);
@ -3249,7 +3249,7 @@ class FiroWallet extends CoinServiceAPI {
final currentPrice = await firoPrice;
final List<Map<String, dynamic>> midSortedArray = [];
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
Logging.instance.log("refresh the txs", level: LogLevel.Info);
for (final txObject in allTransactions) {
@ -4324,7 +4324,7 @@ class FiroWallet extends CoinServiceAPI {
currency,
coin,
currentPrice,
(await Devicelocale.currentLocale)!);
(Platform.isWindows ? "en_US" : await Devicelocale.currentLocale)!);
Logging.instance.log(spendTxs, level: LogLevel.Info);
for (var element in spendTxs) {
transactionMap[element.txid] = element;
@ -4375,7 +4375,7 @@ class FiroWallet extends CoinServiceAPI {
final lelantusEntry = await _getLelantusEntry();
final anonymitySets = await fetchAnonymitySets();
final locktime = await getBlockHead(electrumXClient);
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
ReceivePort receivePort = await getIsolate({
"function": "createJoinSplit",

View file

@ -1299,7 +1299,7 @@ class LitecoinWallet extends CoinServiceAPI {
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /

File diff suppressed because it is too large Load diff

View file

@ -1287,7 +1287,7 @@ class NamecoinWallet extends CoinServiceAPI {
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /

View file

@ -1200,7 +1200,7 @@ class ParticlWallet extends CoinServiceAPI {
final priceData =
await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final locale = await Devicelocale.currentLocale;
final locale = Platform.isWindows ? "en_US" : await Devicelocale.currentLocale;
final String worthNow = Format.localizedStringAsFixed(
value:
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
@ -2241,8 +2241,10 @@ class ParticlWallet extends CoinServiceAPI {
}
}
Logging.instance.log("addAddresses: $allAddresses", level: LogLevel.Info);
Logging.instance.log("allTxHashes: $allTxHashes", level: LogLevel.Info);
Logging.instance.log("addAddresses: $allAddresses",
level: LogLevel.Info, printFullLength: true);
Logging.instance.log("allTxHashes: $allTxHashes",
level: LogLevel.Info, printFullLength: true);
Logging.instance.log("allTransactions length: ${allTransactions.length}",
level: LogLevel.Info);
@ -2286,7 +2288,7 @@ class ParticlWallet extends CoinServiceAPI {
for (final out in tx["vout"] as List) {
if (prevOut == out["n"]) {
final address = out["scriptPubKey"]["address"] as String?;
final address = out["scriptPubKey"]["addresses"][0] as String?;
if (address != null) {
sendersArray.add(address);
}
@ -2300,7 +2302,7 @@ class ParticlWallet extends CoinServiceAPI {
// Particl has different tx types that need to be detected and handled here
if (output.containsKey('scriptPubKey') as bool) {
// Logging.instance.log("output is transparent", level: LogLevel.Info);
final address = output["scriptPubKey"]["address"] as String?;
final address = output["scriptPubKey"]["addresses"][0] as String?;
if (address != null) {
recipientsArray.add(address);
}
@ -2356,20 +2358,26 @@ class ParticlWallet extends CoinServiceAPI {
for (final output in txObject["vout"] as List) {
// Particl has different tx types that need to be detected and handled here
if (output.containsKey('scriptPubKey') as bool) {
// Logging.instance.log("output is transparent", level: LogLevel.Info);
final String address = output["scriptPubKey"]!["address"] as String;
final value = output["value"]!;
final _value = (Decimal.parse(value.toString()) *
Decimal.fromInt(Constants.satsPerCoin(coin)))
.toBigInt()
.toInt();
totalOutput += _value;
if (changeAddresses.contains(address)) {
inputAmtSentFromWallet -= _value;
} else {
// change address from 'sent from' to the 'sent to' address
txObject["address"] = address;
try {
final String address =
output["scriptPubKey"]!["addresses"][0] as String;
final value = output["value"]!;
final _value = (Decimal.parse(value.toString()) *
Decimal.fromInt(Constants.satsPerCoin(coin)))
.toBigInt()
.toInt();
totalOutput += _value;
if (changeAddresses.contains(address)) {
inputAmtSentFromWallet -= _value;
} else {
// change address from 'sent from' to the 'sent to' address
txObject["address"] = address;
}
} catch (s, e) {
Logging.instance.log(s.toString(), level: LogLevel.Warning);
}
// Logging.instance.log("output is transparent", level: LogLevel.Info);
} else if (output.containsKey('ct_fee') as bool) {
// or type: data
// TODO handle CT tx
@ -2408,16 +2416,20 @@ class ParticlWallet extends CoinServiceAPI {
// add up received tx value
for (final output in txObject["vout"] as List) {
final address = output["scriptPubKey"]["address"];
if (address != null) {
final value = (Decimal.parse(output["value"].toString()) *
Decimal.fromInt(Constants.satsPerCoin(coin)))
.toBigInt()
.toInt();
totalOut += value;
if (allAddresses.contains(address)) {
outputAmtAddressedToWallet += value;
try {
final address = output["scriptPubKey"]["addresses"][0];
if (address != null) {
final value = (Decimal.parse(output["value"].toString()) *
Decimal.fromInt(Constants.satsPerCoin(coin)))
.toBigInt()
.toInt();
totalOut += value;
if (allAddresses.contains(address)) {
outputAmtAddressedToWallet += value;
}
}
} catch (s, e) {
Logging.instance.log(s.toString(), level: LogLevel.Info);
}
}
@ -2574,7 +2586,6 @@ class ParticlWallet extends CoinServiceAPI {
final List<UtxoObject> availableOutputs = utxos ?? outputsList;
final List<UtxoObject> spendableOutputs = [];
int spendableSatoshiValue = 0;
print("AVAILABLE UTXOS IS ::::: ${availableOutputs}");
// Build list of spendable outputs and totaling their satoshi amount
for (var i = 0; i < availableOutputs.length; i++) {
if (availableOutputs[i].blocked == false &&
@ -2907,8 +2918,6 @@ class ParticlWallet extends CoinServiceAPI {
Map<String, dynamic> results = {};
Map<String, List<String>> addressTxid = {};
print("CALLING FETCH BUILD TX DATA");
// addresses to check
List<String> addressesP2PKH = [];
List<String> addressesP2WPKH = [];
@ -2925,8 +2934,7 @@ class ParticlWallet extends CoinServiceAPI {
for (final output in tx["vout"] as List) {
final n = output["n"];
if (n != null && n == utxosToUse[i].vout) {
print("SCRIPT PUB KEY IS ${output["scriptPubKey"]}");
final address = output["scriptPubKey"]["address"] as String;
final address = output["scriptPubKey"]["addresses"][0] as String;
if (!addressTxid.containsKey(address)) {
addressTxid[address] = <String>[];
}
@ -3088,6 +3096,7 @@ class ParticlWallet extends CoinServiceAPI {
// Add transaction inputs
for (var i = 0; i < utxosToUse.length; i++) {
final txid = utxosToUse[i].txid;
txb.addInput(txid, utxosToUse[i].vout, null,
utxoSigningData[txid]["output"] as Uint8List, '');
}

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,4 @@
import 'dart:io';
import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/material.dart';
@ -7,7 +8,7 @@ class LocaleService extends ChangeNotifier {
String get locale => _locale;
Future<void> loadLocale({bool notify = true}) async {
_locale = await Devicelocale.currentLocale ?? "en_US";
_locale =Platform.isWindows ? "en_US" : await Devicelocale.currentLocale ?? "en_US";
if (notify) {
notifyListeners();
}

View file

@ -51,6 +51,7 @@ class NotesService extends ChangeNotifier {
_notes[txid] = note;
await DB.instance
.put<dynamic>(boxName: walletId, key: 'notes', value: _notes);
//todo: check if this is needed
Logging.instance.log("editOrAddNote: tx note saved", level: LogLevel.Info);
await _refreshNotes();
}

View file

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

View file

@ -14,7 +14,6 @@ import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
import 'package:stackwallet/services/coins/particl/particl_wallet.dart'
as particl;
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart' as wow;
import 'package:stackwallet/utilities/util.dart';
enum Coin {
bitcoin,
@ -40,7 +39,7 @@ enum Coin {
firoTestNet,
}
final int kTestNetCoinCount = Util.isDesktop ? 5 : 4;
final int kTestNetCoinCount = 4; // Util.isDesktop ? 5 : 4;
extension CoinExt on Coin {
String get prettyName {

View file

@ -15,8 +15,7 @@ abstract class StackFileSystem {
} else if (Platform.isLinux) {
appDirectory = Directory("${Platform.environment['HOME']}/.stackwallet");
} else if (Platform.isWindows) {
// TODO: windows root .stackwallet dir location
throw Exception("Unsupported platform");
appDirectory = await getApplicationSupportDirectory();
} else if (Platform.isMacOS) {
// currently run in ipad mode??
throw Exception("Unsupported platform");

View file

@ -4,6 +4,7 @@ import 'package:flutter_svg/svg.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/util.dart';
import 'package:stackwallet/widgets/loading_indicator.dart';
class ExchangeTextField extends StatefulWidget {
@ -62,6 +63,8 @@ class _ExchangeTextFieldState extends State<ExchangeTextField> {
late final void Function(String)? onChanged;
late final void Function(String)? onSubmitted;
final isDesktop = Util.isDesktop;
@override
void initState() {
borderRadius = widget.borderRadius;
@ -100,10 +103,12 @@ class _ExchangeTextFieldState extends State<ExchangeTextField> {
enableSuggestions: false,
autocorrect: false,
readOnly: widget.readOnly,
keyboardType: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
keyboardType: isDesktop
? null
: const TextInputType.numberWithOptions(
signed: false,
decimal: true,
),
decoration: InputDecoration(
contentPadding: const EdgeInsets.only(
top: 12,

View file

@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
import 'package:tuple/tuple.dart';
@ -31,7 +32,14 @@ class WalletSheetCard extends ConsumerWidget {
Constants.size.circularBorderRadius,
),
),
onPressed: () {
onPressed: () async {
final manager = ref
.read(walletsChangeNotifierProvider)
.getManager(walletId);
if (manager.coin == Coin.monero ||
manager.coin == Coin.wownero) {
await manager.initializeExisting();
}
if (popPrevious) Navigator.of(context).pop();
Navigator.of(context).pushNamed(
WalletView.routeName,

View file

@ -55,7 +55,7 @@
/* Begin PBXFileReference section */
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* firo_wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = firo_wallet.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10ED2044A3C60003C045 /* Stack Wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stack Wallet.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
@ -112,7 +112,7 @@
33CC10EE2044A3C60003C045 /* Products */ = {
isa = PBXGroup;
children = (
33CC10ED2044A3C60003C045 /* firo_wallet.app */,
33CC10ED2044A3C60003C045 /* Stack Wallet.app */,
);
name = Products;
sourceTree = "<group>";
@ -193,7 +193,7 @@
);
name = Runner;
productName = Runner;
productReference = 33CC10ED2044A3C60003C045 /* firo_wallet.app */;
productReference = 33CC10ED2044A3C60003C045 /* Stack Wallet.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */

View file

@ -15,7 +15,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "firo_wallet.app"
BuildableName = "Stack Wallet.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
@ -31,7 +31,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "firo_wallet.app"
BuildableName = "Stack Wallet.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
@ -54,7 +54,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "firo_wallet.app"
BuildableName = "Stack Wallet.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
@ -71,7 +71,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "firo_wallet.app"
BuildableName = "Stack Wallet.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>

View file

@ -5,10 +5,10 @@
// 'flutter create' template.
// The application's name. By default this is also the title of the Flutter window.
PRODUCT_NAME = firo_wallet
PRODUCT_NAME = Stack Wallet
// The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.firoWallet
PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stack_wallet
// The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2022 com.cypherstack. All rights reserved.

View file

@ -11,7 +11,7 @@ description: Stack Wallet
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.5.25+98
version: 1.5.27+100
environment:
sdk: ">=2.17.0 <3.0.0"

View file

@ -1,3 +1,5 @@
#!/bin/bash
# Create template lib/external_api_keys.dart file if it doesn't already exist
KEYS=../lib/external_api_keys.dart
if ! test -f "$KEYS"; then
@ -6,13 +8,14 @@ if ! test -f "$KEYS"; then
fi
# Create template wallet test parameter files if they don't already exist
declare -a coins=("bitcoin" "bitcoincash" "dogecoin" "namecoin" "firo" "particl") # TODO add monero and wownero when those tests are updated to use the .gitignored test wallet setup: when doing that, make sure to update the test vectors for a new, private development seed
declare -a coins
coins=("bitcoin" "bitcoincash" "dogecoin" "namecoin" "firo" "particl") # TODO add monero and wownero when those tests are updated to use the .gitignored test wallet setup: when doing that, make sure to update the test vectors for a new, private development seed
for coin in "${coins[@]}"
do
WALLETTESTPARAMFILE="../test/services/coins/${coin}/${coin}_wallet_test_parameters.dart"
if ! test -f "$WALLETTESTPARAMFILE"; then
echo "prebuild.sh: creating template test/services/coins/${coin}/${coin}_wallet_test_parameters.dart file"
printf 'const TEST_MNEMONIC = "";\nconst ROOT_WIF = "";\nconst NODE_WIF_84 = "";\n' > $WALLETTESTPARAMFILE
printf 'const TEST_MNEMONIC = "";\nconst ROOT_WIF = "";\nconst NODE_WIF_84 = "";\n' > "$WALLETTESTPARAMFILE"
fi
done

9
scripts/windows/build_all.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
mkdir -p build
(cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) &
(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) &
wait
echo "Done building"

View file

@ -43,6 +43,9 @@ void main() {
mockito
.when(wallets.getManagerProvider("wallet id"))
.thenAnswer((realInvocation) => managerProvider);
mockito
.when(wallets.getManager("wallet id"))
.thenAnswer((realInvocation) => manager);
final navigator = mockingjay.MockNavigator();
mockingjay

View file

@ -90,12 +90,12 @@ BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "com.cypherstack" "\0"
VALUE "FileDescription", "firo_wallet" "\0"
VALUE "FileDescription", "Stack Wallet" "\0"
VALUE "FileVersion", VERSION_AS_STRING "\0"
VALUE "InternalName", "firo_wallet" "\0"
VALUE "InternalName", "Stack Wallet" "\0"
VALUE "LegalCopyright", "Copyright (C) 2022 com.cypherstack. All rights reserved." "\0"
VALUE "OriginalFilename", "firo_wallet.exe" "\0"
VALUE "ProductName", "firo_wallet" "\0"
VALUE "OriginalFilename", "Stack Wallet.exe" "\0"
VALUE "ProductName", "Stack Wallet" "\0"
VALUE "ProductVersion", VERSION_AS_STRING "\0"
END
END