diff --git a/assets/lottie/arrow_rotate.json b/assets/lottie/arrow_rotate.json
new file mode 100644
index 000000000..c729d2e7a
--- /dev/null
+++ b/assets/lottie/arrow_rotate.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":30,"ip":0,"op":60,"w":30,"h":30,"nm":"arrow-rotate","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"arrow-rotate","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":44,"s":[200]},{"t":60,"s":[360]}],"ix":10},"p":{"a":0,"k":[15,15,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.828],[0,0],[3.389,0],[1.441,-4.074],[-0.781,-0.277],[-0.276,0.778],[-3.22,0],[-1.369,-1.823],[0,0],[0,-0.83],[-0.83,0],[0,0],[-0.023,0],[0,0],[0,0.83],[0,0],[0.83,0]],"o":[[0,0],[-1.964,-2.437],[-4.533,0],[-0.276,0.741],[0.781,0.277],[1.031,-2.916],[2.494,0],[0,0],[-0.83,0],[0,0.83],[0,0],[0.023,0],[0,0],[0.83,0],[0,0],[0,-0.828],[-0.83,0]],"v":[[8.25,-8.25],[8.25,-6.497],[-0.042,-10.5],[-9.902,-3.502],[-8.988,-1.584],[-7.073,-2.498],[-0.042,-7.5],[6,-4.5],[4.5,-4.5],[3,-3],[4.5,-1.5],[8.452,-1.5],[8.522,-1.5],[9.75,-1.5],[11.25,-3],[11.25,-8.25],[9.75,-9.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.828,0],[0,0.83],[0,0],[-3.347,0],[-1.439,4.073],[0.783,0.277],[0.277,-0.778],[3.262,0],[1.411,1.823],[0,0],[0,0.83],[0.83,0],[0,0],[0,-0.83]],"o":[[0,0.83],[0.828,0],[0,0],[1.922,2.438],[4.575,0],[0.277,-0.783],[-0.778,-0.277],[-1.031,2.916],[-2.452,0],[0,0],[0.83,0],[0,-0.83],[0,0],[-0.828,0],[0,0]],"v":[[-11.25,8.25],[-9.75,9.75],[-8.25,8.25],[-8.25,6.497],[0,10.5],[9.9,3.502],[8.986,1.584],[7.073,2.498],[0,7.5],[-6.042,4.5],[-4.5,4.5],[-3,3],[-4.5,1.5],[-9.75,1.5],[-11.25,3]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.137254908681,0.137254908681,0.137254908681,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"ct":1,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/assets/svg/rotate-exclamation.svg b/assets/svg/rotate-exclamation.svg
deleted file mode 100644
index 6b6064125..000000000
--- a/assets/svg/rotate-exclamation.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/docs/building.md b/docs/building.md
index a2de91aa9..879008f09 100644
--- a/docs/building.md
+++ b/docs/building.md
@@ -9,7 +9,7 @@ Here you will find instructions on how to install the necessary tools for buildi
The following prerequisites can be installed with the setup script [`scripts/setup.sh`](./../scripts/setup.sh) or manually as described below:
-- Flutter 3.7.6 [(install manually or with git, do not install with snap)](https://docs.flutter.dev/get-started/install)
+- Flutter 3.7.11 [(install manually or with git, do not install with snap)](https://docs.flutter.dev/get-started/install)
- Dart SDK Requirement (>=2.19.0, up until <3.0.0) (normally included with a flutter install)
- Android setup ([Android Studio](https://developer.android.com/studio) and subsequent dependencies)
@@ -41,11 +41,17 @@ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-
Install [Rust](https://www.rust-lang.org/tools/install) with command:
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+rustup install 1.67.1
+rustup default 1.67.1
```
Install the additional components for Rust:
```
-cargo install cargo-ndk
+cargo install cargo-ndk --version 2.12.7
+```
+Android specific dependencies:
+```
+sudo apt-get install libc6-dev-i386
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
```
Linux desktop specific dependencies:
@@ -134,4 +140,4 @@ Use Tools > SDK Manager to install the SDK Tools > Android SDK (API 30), SDK Too
Then install the Flutter plugin and restart the IDE. In Android Studio's options for the Flutter language, enable auto format on save to match the project's code style. If you have problems with the Dart SDK, make sure to run `flutter` in a terminal to download it (use `source ~/.bashrc` to update your environment variables if you're still using the same terminal from which you ran `setup.sh`)
-Make a Pixel 4 (API 30) x86_64 emulator with 2GB of storage space for emulation
\ No newline at end of file
+Make a Pixel 4 (API 30) x86_64 emulator with 2GB of storage space for emulation
diff --git a/lib/models/paynym/paynym_account.dart b/lib/models/paynym/paynym_account.dart
index 4be59dc0c..133edc25d 100644
--- a/lib/models/paynym/paynym_account.dart
+++ b/lib/models/paynym/paynym_account.dart
@@ -4,6 +4,7 @@ import 'package:stackwallet/models/paynym/paynym_code.dart';
class PaynymAccount {
final String nymID;
final String nymName;
+ final bool segwit;
final List codes;
@@ -13,9 +14,13 @@ class PaynymAccount {
/// list of nymId
final List following;
+ PaynymCode get nonSegwitPaymentCode =>
+ codes.firstWhere((element) => !element.segwit);
+
PaynymAccount(
this.nymID,
this.nymName,
+ this.segwit,
this.codes,
this.followers,
this.following,
@@ -24,6 +29,7 @@ class PaynymAccount {
PaynymAccount.fromMap(Map map)
: nymID = map["nymID"] as String,
nymName = map["nymName"] as String,
+ segwit = map["segwit"] as bool,
codes = (map["codes"] as List)
.map((e) => PaynymCode.fromMap(Map.from(e as Map)))
.toList(),
@@ -39,6 +45,7 @@ class PaynymAccount {
PaynymAccount copyWith({
String? nymID,
String? nymName,
+ bool? segwit,
List? codes,
List? followers,
List? following,
@@ -46,6 +53,7 @@ class PaynymAccount {
return PaynymAccount(
nymID ?? this.nymID,
nymName ?? this.nymName,
+ segwit ?? this.segwit,
codes ?? this.codes,
followers ?? this.followers,
following ?? this.following,
@@ -55,6 +63,7 @@ class PaynymAccount {
Map toMap() => {
"nymID": nymID,
"nymName": nymName,
+ "segwit": segwit,
"codes": codes.map((e) => e.toMap()),
"followers": followers.map((e) => e.toMap()),
"following": followers.map((e) => e.toMap()),
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart b/lib/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart
index e3630b922..79cdcd34f 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart
@@ -1,9 +1,8 @@
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/animated_widgets/rotating_arrows.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
@@ -21,37 +20,15 @@ class RestoringDialog extends StatefulWidget {
State createState() => _RestoringDialogState();
}
-class _RestoringDialogState extends State
- with TickerProviderStateMixin {
- late AnimationController? _spinController;
- late Animation _spinAnimation;
-
+class _RestoringDialogState extends State {
late final Future Function() onCancel;
@override
void initState() {
onCancel = widget.onCancel;
- _spinController = AnimationController(
- duration: const Duration(seconds: 2),
- vsync: this,
- )..repeat();
-
- _spinAnimation = CurvedAnimation(
- parent: _spinController!,
- curve: Curves.linear,
- );
-
super.initState();
}
- @override
- void dispose() {
- _spinController?.dispose();
- _spinController = null;
-
- super.dispose();
- }
-
@override
Widget build(BuildContext context) {
if (Util.isDesktop) {
@@ -69,14 +46,9 @@ class _RestoringDialogState extends State
const Spacer(
flex: 1,
),
- RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(Assets.svg.arrowRotate3,
- width: 40,
- height: 40,
- color: Theme.of(context)
- .extension()!
- .accentColorDark),
+ const RotatingArrows(
+ width: 40,
+ height: 40,
),
const Spacer(
flex: 2,
@@ -127,14 +99,9 @@ class _RestoringDialogState extends State
child: StackDialog(
title: "Restoring wallet",
message: "This may take a while. Please do not exit this screen.",
- icon: RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(Assets.svg.arrowRotate3,
- width: 24,
- height: 24,
- color: Theme.of(context)
- .extension()!
- .accentColorDark),
+ icon: const RotatingArrows(
+ width: 24,
+ height: 24,
),
rightButton: TextButton(
style: Theme.of(context)
diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 6a13e0b63..fff02cb7d 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -109,7 +109,7 @@ class _ConfirmChangeNowSendViewState
time,
]);
- sendProgressController.triggerSuccess();
+ sendProgressController.triggerSuccess?.call();
await Future.delayed(const Duration(seconds: 5));
txid = results.first as String;
diff --git a/lib/pages/paynym/add_new_paynym_follow_view.dart b/lib/pages/paynym/add_new_paynym_follow_view.dart
index 68473fc7c..d89c3db92 100644
--- a/lib/pages/paynym/add_new_paynym_follow_view.dart
+++ b/lib/pages/paynym/add_new_paynym_follow_view.dart
@@ -447,7 +447,7 @@ class _AddNewPaynymFollowViewState
child: PaynymCard(
key: UniqueKey(),
label: _searchResult!.nymName,
- paymentCodeString: _searchResult!.codes.first.code,
+ paymentCodeString: _searchResult!.nonSegwitPaymentCode.code,
walletId: widget.walletId,
),
),
diff --git a/lib/pages/paynym/dialogs/claiming_paynym_dialog.dart b/lib/pages/paynym/dialogs/claiming_paynym_dialog.dart
index 2a24fd4c8..7d42a35d4 100644
--- a/lib/pages/paynym/dialogs/claiming_paynym_dialog.dart
+++ b/lib/pages/paynym/dialogs/claiming_paynym_dialog.dart
@@ -1,9 +1,8 @@
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/animated_widgets/rotating_arrows.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
@@ -18,34 +17,7 @@ class ClaimingPaynymDialog extends StatefulWidget {
State createState() => _RestoringDialogState();
}
-class _RestoringDialogState extends State
- with TickerProviderStateMixin {
- late AnimationController? _spinController;
- late Animation _spinAnimation;
-
- @override
- void initState() {
- _spinController = AnimationController(
- duration: const Duration(seconds: 2),
- vsync: this,
- )..repeat();
-
- _spinAnimation = CurvedAnimation(
- parent: _spinController!,
- curve: Curves.linear,
- );
-
- super.initState();
- }
-
- @override
- void dispose() {
- _spinController?.dispose();
- _spinController = null;
-
- super.dispose();
- }
-
+class _RestoringDialogState extends State {
@override
Widget build(BuildContext context) {
if (Util.isDesktop) {
@@ -62,15 +34,9 @@ class _RestoringDialogState extends State
),
],
),
- RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(
- Assets.svg.arrowRotate,
- color:
- Theme.of(context).extension()!.accentColorDark,
- width: 40,
- height: 40,
- ),
+ const RotatingArrows(
+ width: 40,
+ height: 40,
),
Padding(
padding: const EdgeInsets.all(40),
@@ -115,15 +81,9 @@ class _RestoringDialogState extends State
child: StackDialog(
title: "Claiming PayNym",
message: "We are generating your PayNym",
- icon: RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(
- Assets.svg.arrowRotate,
- color:
- Theme.of(context).extension()!.accentColorDark,
- width: 24,
- height: 24,
- ),
+ icon: const RotatingArrows(
+ width: 24,
+ height: 24,
),
rightButton: SecondaryButton(
label: "Cancel",
diff --git a/lib/pages/paynym/dialogs/paynym_qr_popup.dart b/lib/pages/paynym/dialogs/paynym_qr_popup.dart
index 3ad985472..0f36436fa 100644
--- a/lib/pages/paynym/dialogs/paynym_qr_popup.dart
+++ b/lib/pages/paynym/dialogs/paynym_qr_popup.dart
@@ -55,7 +55,7 @@ class PaynymQrPopup extends StatelessWidget {
child: Row(
children: [
PayNymBot(
- paymentCodeString: paynymAccount.codes.first.code,
+ paymentCodeString: paynymAccount.nonSegwitPaymentCode.code,
size: isDesktop ? 56 : 36,
),
const SizedBox(
@@ -108,7 +108,7 @@ class PaynymQrPopup extends StatelessWidget {
height: 6,
),
Text(
- paynymAccount.codes.first.code,
+ paynymAccount.nonSegwitPaymentCode.code,
style: isDesktop
? STextStyles.desktopTextSmall(context)
: STextStyles.infoSmall(context).copyWith(
@@ -127,7 +127,7 @@ class PaynymQrPopup extends StatelessWidget {
onTap: () async {
await Clipboard.setData(
ClipboardData(
- text: paynymAccount.codes.first.code,
+ text: paynymAccount.nonSegwitPaymentCode.code,
),
);
unawaited(
@@ -150,7 +150,7 @@ class PaynymQrPopup extends StatelessWidget {
QrImage(
padding: const EdgeInsets.all(0),
size: 130,
- data: paynymAccount.codes.first.code,
+ data: paynymAccount.nonSegwitPaymentCode.code,
foregroundColor:
Theme.of(context).extension()!.textDark,
),
diff --git a/lib/pages/paynym/paynym_claim_view.dart b/lib/pages/paynym/paynym_claim_view.dart
index 8a66aa26d..7944688da 100644
--- a/lib/pages/paynym/paynym_claim_view.dart
+++ b/lib/pages/paynym/paynym_claim_view.dart
@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/models/paynym/paynym_account.dart';
import 'package:stackwallet/pages/paynym/dialogs/claiming_paynym_dialog.dart';
import 'package:stackwallet/pages/paynym/paynym_home_view.dart';
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
@@ -11,7 +12,6 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart';
import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart';
import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
@@ -36,6 +36,29 @@ class PaynymClaimView extends ConsumerStatefulWidget {
}
class _PaynymClaimViewState extends ConsumerState {
+ Future _addSegwitCode(PaynymAccount myAccount) async {
+ final manager =
+ ref.read(walletsChangeNotifierProvider).getManager(widget.walletId);
+
+ // get wallet to access paynym calls
+ final wallet = manager.wallet as PaynymWalletInterface;
+
+ final token = await ref
+ .read(paynymAPIProvider)
+ .token(myAccount.nonSegwitPaymentCode.code);
+ final signature = await wallet.signStringWithNotificationKey(token.value!);
+
+ final pCodeSegwit = await wallet.getPaymentCode(isSegwit: true);
+ final addResult = await ref.read(paynymAPIProvider).add(
+ token.value!,
+ signature,
+ myAccount.nymID,
+ pCodeSegwit.toString(),
+ );
+
+ return addResult.value ?? false;
+ }
+
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
@@ -169,8 +192,7 @@ class _PaynymClaimViewState extends ConsumerState {
if (shouldCancel) return;
// get payment code
- final pCode = await wallet.getPaymentCode(
- DerivePathTypeExt.primaryFor(manager.coin));
+ final pCode = await wallet.getPaymentCode(isSegwit: false);
if (shouldCancel) return;
@@ -185,6 +207,18 @@ class _PaynymClaimViewState extends ConsumerState {
if (created.value!.claimed) {
// payment code already claimed
debugPrint("pcode already claimed!!");
+
+ final account =
+ await ref.read(paynymAPIProvider).nym(pCode.toString());
+ if (!account.value!.segwit) {
+ for (int i = 0; i < 100; i++) {
+ final result = await _addSegwitCode(account.value!);
+ if (result == true) {
+ break;
+ }
+ }
+ }
+
if (mounted) {
if (isDesktop) {
Navigator.of(context, rootNavigator: true).pop();
@@ -223,6 +257,14 @@ class _PaynymClaimViewState extends ConsumerState {
if (claim.value?.claimed == pCode.toString()) {
final account =
await ref.read(paynymAPIProvider).nym(pCode.toString());
+ if (!account.value!.segwit) {
+ for (int i = 0; i < 100; i++) {
+ final result = await _addSegwitCode(account.value!);
+ if (result == true) {
+ break;
+ }
+ }
+ }
ref.read(myPaynymAccountStateProvider.state).state =
account.value!;
diff --git a/lib/pages/paynym/paynym_home_view.dart b/lib/pages/paynym/paynym_home_view.dart
index b989ba9c5..f0cb108cb 100644
--- a/lib/pages/paynym/paynym_home_view.dart
+++ b/lib/pages/paynym/paynym_home_view.dart
@@ -275,8 +275,7 @@ class _PaynymHomeViewState extends ConsumerState {
paymentCodeString: ref
.watch(myPaynymAccountStateProvider.state)
.state!
- .codes
- .first
+ .nonSegwitPaymentCode
.code,
),
),
@@ -298,8 +297,7 @@ class _PaynymHomeViewState extends ConsumerState {
ref
.watch(myPaynymAccountStateProvider.state)
.state!
- .codes
- .first
+ .nonSegwitPaymentCode
.code,
12,
5),
@@ -330,8 +328,7 @@ class _PaynymHomeViewState extends ConsumerState {
text: ref
.read(myPaynymAccountStateProvider.state)
.state!
- .codes
- .first
+ .nonSegwitPaymentCode
.code,
),
);
@@ -376,8 +373,7 @@ class _PaynymHomeViewState extends ConsumerState {
ref
.read(myPaynymAccountStateProvider.state)
.state!
- .codes
- .first
+ .nonSegwitPaymentCode
.code,
sharePositionOrigin: sharePositionOrigin);
},
@@ -447,8 +443,7 @@ class _PaynymHomeViewState extends ConsumerState {
paymentCodeString: ref
.watch(myPaynymAccountStateProvider.state)
.state!
- .codes
- .first
+ .nonSegwitPaymentCode
.code,
),
),
@@ -473,8 +468,7 @@ class _PaynymHomeViewState extends ConsumerState {
ref
.watch(myPaynymAccountStateProvider.state)
.state!
- .codes
- .first
+ .nonSegwitPaymentCode
.code,
12,
5),
@@ -501,8 +495,7 @@ class _PaynymHomeViewState extends ConsumerState {
text: ref
.read(myPaynymAccountStateProvider.state)
.state!
- .codes
- .first
+ .nonSegwitPaymentCode
.code,
),
);
diff --git a/lib/pages/paynym/subwidgets/paynym_followers_list.dart b/lib/pages/paynym/subwidgets/paynym_followers_list.dart
index d8583954d..1237b2c4a 100644
--- a/lib/pages/paynym/subwidgets/paynym_followers_list.dart
+++ b/lib/pages/paynym/subwidgets/paynym_followers_list.dart
@@ -8,7 +8,6 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart';
import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -75,7 +74,7 @@ class _PaynymFollowersListState extends ConsumerState {
// get payment code
final pCode = await wallet.getPaymentCode(
- DerivePathTypeExt.primaryFor(manager.coin),
+ isSegwit: false,
);
// get account from api
diff --git a/lib/pages/paynym/subwidgets/paynym_following_list.dart b/lib/pages/paynym/subwidgets/paynym_following_list.dart
index 4d9df16ac..f12d30cdf 100644
--- a/lib/pages/paynym/subwidgets/paynym_following_list.dart
+++ b/lib/pages/paynym/subwidgets/paynym_following_list.dart
@@ -8,7 +8,6 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart';
import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -75,7 +74,7 @@ class _PaynymFollowingListState extends ConsumerState {
// get payment code
final pCode = await wallet.getPaymentCode(
- DerivePathTypeExt.primaryFor(manager.coin),
+ isSegwit: false,
);
// get account from api
diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart
index e46badfd3..b74dc5a33 100644
--- a/lib/pages/receive_view/receive_view.dart
+++ b/lib/pages/receive_view/receive_view.dart
@@ -233,6 +233,7 @@ class _ReceiveViewState extends ConsumerState {
children: [
GestureDetector(
onTap: () {
+ HapticFeedback.lightImpact();
clipboard.setData(
ClipboardData(text: receivingAddress),
);
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index d54b7b8cf..a6dd1bcc0 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -135,7 +135,7 @@ class _ConfirmTransactionViewState
time,
]);
- sendProgressController.triggerSuccess();
+ sendProgressController.triggerSuccess?.call();
await Future.delayed(const Duration(seconds: 5));
txid = results.first as String;
diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart
index 12896b87a..479c931ae 100644
--- a/lib/pages/send_view/send_view.dart
+++ b/lib/pages/send_view/send_view.dart
@@ -453,11 +453,12 @@ class _SendViewState extends ConsumerState {
final wallet = manager.wallet as PaynymWalletInterface;
final paymentCode = PaymentCode.fromPaymentCode(
widget.accountLite!.code,
- wallet.networkType,
+ networkType: wallet.networkType,
);
final feeRate = ref.read(feeRateTypeStateProvider);
txDataFuture = wallet.preparePaymentCodeSend(
paymentCode: paymentCode,
+ isSegwit: widget.accountLite!.segwit,
amount: amount,
args: {
"feeRate": feeRate,
diff --git a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
index 8bd800cad..f95fe7bed 100644
--- a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
+++ b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/color_theme.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/animated_widgets/rotating_arrows.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -23,38 +23,16 @@ class BuildingTransactionDialog extends StatefulWidget {
State createState() => _RestoringDialogState();
}
-class _RestoringDialogState extends State
- with TickerProviderStateMixin {
- late AnimationController? _spinController;
- late Animation _spinAnimation;
-
+class _RestoringDialogState extends State {
late final VoidCallback onCancel;
@override
void initState() {
onCancel = widget.onCancel;
- _spinController = AnimationController(
- duration: const Duration(seconds: 2),
- vsync: this,
- )..repeat();
-
- _spinAnimation = CurvedAnimation(
- parent: _spinController!,
- curve: Curves.linear,
- );
-
super.initState();
}
- @override
- void dispose() {
- _spinController?.dispose();
- _spinController = null;
-
- super.dispose();
- }
-
@override
Widget build(BuildContext context) {
final isChans = Theme.of(context).extension()!.themeType ==
@@ -80,15 +58,9 @@ class _RestoringDialogState extends State
),
),
if (!isChans)
- RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(
- Assets.svg.arrowRotate,
- color:
- Theme.of(context).extension()!.accentColorDark,
- width: 24,
- height: 24,
- ),
+ const RotatingArrows(
+ width: 40,
+ height: 40,
),
const SizedBox(
height: 40,
@@ -151,16 +123,9 @@ class _RestoringDialogState extends State
)
: StackDialog(
title: "Generating transaction",
- icon: RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(
- Assets.svg.arrowRotate,
- color: Theme.of(context)
- .extension()!
- .accentColorDark,
- width: 24,
- height: 24,
- ),
+ icon: const RotatingArrows(
+ width: 24,
+ height: 24,
),
rightButton: TextButton(
style: Theme.of(context)
diff --git a/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart b/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
index 4b0c56728..85dc6fc6f 100644
--- a/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
+++ b/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
@@ -113,7 +113,7 @@ class _RestoringDialogState extends State {
}
class ProgressAndSuccessController {
- late VoidCallback triggerSuccess;
+ VoidCallback? triggerSuccess;
}
class ProgressAndSuccess extends StatefulWidget {
diff --git a/lib/pages/settings_views/global_settings_view/global_settings_view.dart b/lib/pages/settings_views/global_settings_view/global_settings_view.dart
index 627961bed..ded2dd325 100644
--- a/lib/pages/settings_views/global_settings_view/global_settings_view.dart
+++ b/lib/pages/settings_views/global_settings_view/global_settings_view.dart
@@ -162,7 +162,7 @@ class GlobalSettingsView extends StatelessWidget {
height: 8,
),
SettingsListButton(
- iconAssetName: Assets.svg.arrowRotate3,
+ iconAssetName: Assets.svg.arrowRotate,
iconSize: 18,
title: "Syncing preferences",
onPressed: () {
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
index 5172144be..3a286d6d2 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
@@ -214,7 +214,7 @@ class _StackRestoreProgressViewState
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
- _restore();
+ unawaited(_restore());
});
super.initState();
}
@@ -325,7 +325,7 @@ class _StackRestoreProgressViewState
: null,
)
: RoundedContainer(
- padding: EdgeInsets.all(0),
+ padding: EdgeInsets.zero,
color: Theme.of(context)
.extension()!
.popupBG,
@@ -411,7 +411,7 @@ class _StackRestoreProgressViewState
: null,
)
: RoundedContainer(
- padding: EdgeInsets.all(0),
+ padding: EdgeInsets.zero,
color: Theme.of(context)
.extension()!
.popupBG,
@@ -497,7 +497,7 @@ class _StackRestoreProgressViewState
: null,
)
: RoundedContainer(
- padding: EdgeInsets.all(0),
+ padding: EdgeInsets.zero,
color: Theme.of(context)
.extension()!
.popupBG,
@@ -548,44 +548,42 @@ class _StackRestoreProgressViewState
final state = ref.watch(stackRestoringUIStateProvider
.select((value) => value.trades));
return !isDesktop
- ? Container(
- child: RestoringItemCard(
- left: SizedBox(
- width: 32,
- height: 32,
- child: RoundedContainer(
- padding: const EdgeInsets.all(0),
- color: Theme.of(context)
- .extension()!
- .buttonBackSecondary,
- child: Center(
- child: SvgPicture.asset(
- Assets.svg.arrowRotate2,
- width: 16,
- height: 16,
- color: Theme.of(context)
- .extension()!
- .accentColorDark,
- ),
+ ? RestoringItemCard(
+ left: SizedBox(
+ width: 32,
+ height: 32,
+ child: RoundedContainer(
+ padding: const EdgeInsets.all(0),
+ color: Theme.of(context)
+ .extension()!
+ .buttonBackSecondary,
+ child: Center(
+ child: SvgPicture.asset(
+ Assets.svg.arrowsTwoWay,
+ width: 16,
+ height: 16,
+ color: Theme.of(context)
+ .extension()!
+ .accentColorDark,
),
),
),
- right: SizedBox(
- width: 20,
- height: 20,
- child: _getIconForState(state),
- ),
- title: "Exchange history",
- subTitle: state == StackRestoringStatus.failed
- ? Text(
- "Something went wrong",
- style: STextStyles.errorSmall(context),
- )
- : null,
),
+ right: SizedBox(
+ width: 20,
+ height: 20,
+ child: _getIconForState(state),
+ ),
+ title: "Exchange history",
+ subTitle: state == StackRestoringStatus.failed
+ ? Text(
+ "Something went wrong",
+ style: STextStyles.errorSmall(context),
+ )
+ : null,
)
: RoundedContainer(
- padding: EdgeInsets.all(0),
+ padding: EdgeInsets.zero,
color: Theme.of(context)
.extension()!
.popupBG,
@@ -603,7 +601,7 @@ class _StackRestoreProgressViewState
.buttonBackSecondary,
child: Center(
child: SvgPicture.asset(
- Assets.svg.arrowRotate2,
+ Assets.svg.arrowsTwoWay,
width: 16,
height: 16,
color: Theme.of(context)
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart
index 0435d023b..ac30cb5e7 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart
@@ -1,8 +1,6 @@
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/animated_widgets/rotating_arrows.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -66,18 +64,12 @@ class _RescanningDialogState extends State
maxWidth: 500,
child: child,
),
- child: StackDialog(
+ child: const StackDialog(
title: "Rescanning blockchain",
message: "This may take a while. Please do not exit this screen.",
- icon: RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(
- Assets.svg.arrowRotate3,
- width: 24,
- height: 24,
- color:
- Theme.of(context).extension()!.accentColorDark,
- ),
+ icon: RotatingArrows(
+ width: 24,
+ height: 24,
),
// rightButton: TextButton(
// style: Theme.of(context).textButtonTheme.style?.copyWith(
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
index 592630b12..9df35cb7c 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
@@ -269,7 +269,7 @@ class _WalletSettingsViewState extends State {
height: 8,
),
SettingsListButton(
- iconAssetName: Assets.svg.arrowRotate3,
+ iconAssetName: Assets.svg.arrowRotate,
title: "Syncing preferences",
onPressed: () {
Navigator.of(context).pushNamed(
diff --git a/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart b/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart
index b1541617c..a4b6a34de 100644
--- a/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart
+++ b/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart
@@ -3,15 +3,14 @@ import 'dart:async';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/token_view/token_view.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
-import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/animated_widgets/rotating_arrows.dart';
/// [eventBus] should only be set during testing
class WalletRefreshButton extends ConsumerStatefulWidget {
@@ -36,30 +35,16 @@ class WalletRefreshButton extends ConsumerStatefulWidget {
ConsumerState createState() => _RefreshButtonState();
}
-class _RefreshButtonState extends ConsumerState
- with TickerProviderStateMixin {
+class _RefreshButtonState extends ConsumerState {
late final EventBus eventBus;
- late AnimationController? _spinController;
- late Animation _spinAnimation;
+ late RotatingArrowsController _spinController;
late StreamSubscription _syncStatusSubscription;
@override
void initState() {
- _spinController = AnimationController(
- duration: const Duration(seconds: 2),
- vsync: this,
- );
-
- _spinAnimation = CurvedAnimation(
- parent: _spinController!,
- curve: Curves.linear,
- );
-
- if (widget.initialSyncStatus == WalletSyncStatus.syncing) {
- _spinController?.repeat();
- }
+ _spinController = RotatingArrowsController();
eventBus =
widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
@@ -71,26 +56,26 @@ class _RefreshButtonState extends ConsumerState
widget.tokenContractAddress == null) {
switch (event.newStatus) {
case WalletSyncStatus.unableToSync:
- _spinController?.stop();
+ _spinController.stop?.call();
break;
case WalletSyncStatus.synced:
- _spinController?.stop();
+ _spinController.stop?.call();
break;
case WalletSyncStatus.syncing:
- unawaited(_spinController?.repeat());
+ _spinController.repeat?.call();
break;
}
} else if (widget.tokenContractAddress != null &&
event.walletId == widget.walletId + widget.tokenContractAddress!) {
switch (event.newStatus) {
case WalletSyncStatus.unableToSync:
- _spinController?.stop();
+ _spinController.stop?.call();
break;
case WalletSyncStatus.synced:
- _spinController?.stop();
+ _spinController.stop?.call();
break;
case WalletSyncStatus.syncing:
- unawaited(_spinController?.repeat());
+ _spinController.repeat?.call();
break;
}
}
@@ -102,9 +87,6 @@ class _RefreshButtonState extends ConsumerState
@override
void dispose() {
- _spinController?.dispose();
- _spinController = null;
-
_syncStatusSubscription.cancel();
super.dispose();
@@ -117,62 +99,56 @@ class _RefreshButtonState extends ConsumerState
return SizedBox(
height: isDesktop ? 22 : 36,
width: isDesktop ? 22 : 36,
- child: Semantics(
- label: "Refresh Button. Refreshes The Values In Page.",
- excludeSemantics: true,
- child: MaterialButton(
- color: isDesktop
- ? Theme.of(context).extension()!.buttonBackSecondary
- : null,
- splashColor: Theme.of(context).extension()!.highlight,
- onPressed: () {
- if (widget.tokenContractAddress == null) {
- final managerProvider = ref
- .read(walletsChangeNotifierProvider)
- .getManagerProvider(widget.walletId);
- final isRefreshing = ref.read(managerProvider).isRefreshing;
- if (!isRefreshing) {
- _spinController?.repeat();
- ref
- .read(managerProvider)
- .refresh()
- .then((_) => _spinController?.stop());
- }
- } else {
- if (!ref.read(tokenServiceProvider)!.isRefreshing) {
- ref.read(tokenServiceProvider)!.refresh();
- }
+ child: MaterialButton(
+ color: isDesktop
+ ? Theme.of(context).extension()!.buttonBackSecondary
+ : null,
+ splashColor: Theme.of(context).extension()!.highlight,
+ onPressed: () {
+ if (widget.tokenContractAddress == null) {
+ final managerProvider = ref
+ .read(walletsChangeNotifierProvider)
+ .getManagerProvider(widget.walletId);
+ final isRefreshing = ref.read(managerProvider).isRefreshing;
+ if (!isRefreshing) {
+ _spinController.repeat?.call();
+ ref
+ .read(managerProvider)
+ .refresh()
+ .then((_) => _spinController.stop?.call());
}
- },
- elevation: 0,
- highlightElevation: 0,
- hoverElevation: 0,
- padding: EdgeInsets.zero,
- materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius,
- ),
- ),
- child: RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(
- Assets.svg.arrowRotate,
- width: isDesktop ? 12 : 24,
- height: isDesktop ? 12 : 24,
- color: widget.overrideIconColor != null
- ? widget.overrideIconColor!
- : isDesktop
- ? Theme.of(context)
- .extension()!
- .textFieldDefaultSearchIconRight
- : Theme.of(context)
- .extension()!
- .textFavoriteCard,
- ),
+ } else {
+ if (!ref.read(tokenServiceProvider)!.isRefreshing) {
+ ref.read(tokenServiceProvider)!.refresh();
+ }
+ }
+ },
+ elevation: 0,
+ highlightElevation: 0,
+ hoverElevation: 0,
+ padding: EdgeInsets.zero,
+ materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
),
),
- )
+ child: RotatingArrows(
+ spinByDefault: widget.initialSyncStatus == WalletSyncStatus.syncing,
+ width: isDesktop ? 12 : 24,
+ height: isDesktop ? 12 : 24,
+ controller: _spinController,
+ color: widget.overrideIconColor != null
+ ? widget.overrideIconColor!
+ : isDesktop
+ ? Theme.of(context)
+ .extension()!
+ .textFieldDefaultSearchIconRight
+ : Theme.of(context)
+ .extension()!
+ .textFavoriteCard,
+ ),
+ ),
);
}
}
diff --git a/lib/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart b/lib/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart
index 7d737ab41..810579e6c 100644
--- a/lib/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart
+++ b/lib/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart
@@ -1,7 +1,5 @@
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/animated_widgets/rotating_arrows.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class CancellingTransactionProgressDialog extends StatefulWidget {
@@ -13,51 +11,19 @@ class CancellingTransactionProgressDialog extends StatefulWidget {
}
class _CancellingTransactionProgressDialogState
- extends State
- with TickerProviderStateMixin {
- late AnimationController? _spinController;
- late Animation _spinAnimation;
-
- @override
- void initState() {
- _spinController = AnimationController(
- duration: const Duration(seconds: 2),
- vsync: this,
- )..repeat();
-
- _spinAnimation = CurvedAnimation(
- parent: _spinController!,
- curve: Curves.linear,
- );
-
- super.initState();
- }
-
- @override
- void dispose() {
- _spinController?.dispose();
- _spinController = null;
-
- super.dispose();
- }
-
+ extends State {
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false;
},
- child: StackDialog(
+ child: const StackDialog(
title: "Cancelling transaction",
message: "This may take a while. Please do not exit this screen.",
- icon: RotationTransition(
- turns: _spinAnimation,
- child: SvgPicture.asset(
- Assets.svg.arrowRotate3,
- width: 24,
- height: 24,
- color: Theme.of(context).extension()!.accentColorDark,
- ),
+ icon: RotatingArrows(
+ width: 24,
+ height: 24,
),
// rightButton: TextButton(
// style: Theme.of(context).textButtonTheme.style?.copyWith(
diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart
index 7d43acfbd..649464722 100644
--- a/lib/pages/wallet_view/wallet_view.dart
+++ b/lib/pages/wallet_view/wallet_view.dart
@@ -43,7 +43,6 @@ import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/show_loading.dart';
@@ -912,7 +911,8 @@ class _WalletViewState extends ConsumerState {
manager.wallet as PaynymWalletInterface;
final code = await paynymInterface.getPaymentCode(
- DerivePathTypeExt.primaryFor(manager.coin));
+ isSegwit: false,
+ );
final account = await ref
.read(paynymAPIProvider)
@@ -928,7 +928,8 @@ class _WalletViewState extends ConsumerState {
// check if account exists and for matching code to see if claimed
if (account.value != null &&
- account.value!.codes.first.claimed) {
+ account.value!.nonSegwitPaymentCode.claimed &&
+ account.value!.segwit) {
ref.read(myPaynymAccountStateProvider.state).state =
account.value!;
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 664fe0103..cf2ca1582 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -262,11 +262,12 @@ class _DesktopSendState extends ConsumerState {
final wallet = manager.wallet as PaynymWalletInterface;
final paymentCode = PaymentCode.fromPaymentCode(
widget.accountLite!.code,
- wallet.networkType,
+ networkType: wallet.networkType,
);
final feeRate = ref.read(feeRateTypeStateProvider);
txDataFuture = wallet.preparePaymentCodeSend(
paymentCode: paymentCode,
+ isSegwit: widget.accountLite!.segwit,
amount: amount,
args: {
"feeRate": feeRate,
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart
index 089c0e19f..aef5b8f00 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart
@@ -21,7 +21,6 @@ import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -271,8 +270,7 @@ class _DesktopWalletFeaturesState extends ConsumerState {
final wallet = manager.wallet as PaynymWalletInterface;
- final code =
- await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(manager.coin));
+ final code = await wallet.getPaymentCode(isSegwit: false);
final account = await ref.read(paynymAPIProvider).nym(code.toString());
@@ -285,7 +283,9 @@ class _DesktopWalletFeaturesState extends ConsumerState {
Navigator.of(context, rootNavigator: true).pop();
// check if account exists and for matching code to see if claimed
- if (account.value != null && account.value!.codes.first.claimed) {
+ if (account.value != null &&
+ account.value!.nonSegwitPaymentCode.claimed &&
+ account.value!.segwit) {
ref.read(myPaynymAccountStateProvider.state).state = account.value!;
await Navigator.of(context).pushNamed(
diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart
index 0625957f6..ba49eefc0 100644
--- a/lib/services/coins/bitcoin/bitcoin_wallet.dart
+++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart
@@ -164,6 +164,7 @@ class BitcoinWallet extends CoinServiceAPI
// _checkP2PKHChangeAddressForTransactions,
dustLimitP2PKH: DUST_LIMIT_P2PKH.raw.toInt(),
minConfirms: MINIMUM_CONFIRMATIONS,
+ dustLimit: DUST_LIMIT.raw.toInt(),
);
}
@@ -422,7 +423,7 @@ class BitcoinWallet extends CoinServiceAPI
level: LogLevel.Info);
}
- Future, DerivePathType>> _checkGaps(
+ Future, DerivePathType, int>> _checkGaps(
int maxNumberOfIndexesToCheck,
int maxUnusedAddressGap,
int txCountBatchSize,
@@ -432,6 +433,8 @@ class BitcoinWallet extends CoinServiceAPI
) async {
List addressArray = [];
int gapCounter = 0;
+ int highestIndexWithHistory = 0;
+
for (int index = 0;
index < maxNumberOfIndexesToCheck && gapCounter < maxUnusedAddressGap;
index += txCountBatchSize) {
@@ -505,6 +508,9 @@ class BitcoinWallet extends CoinServiceAPI
if (count > 0) {
iterationsAddressArray.add(txCountCallArgs["${_id}_$k"]!);
+ // update highest
+ highestIndexWithHistory = index + k;
+
// reset counter
gapCounter = 0;
}
@@ -517,7 +523,7 @@ class BitcoinWallet extends CoinServiceAPI
// cache all the transactions while waiting for the current function to finish.
unawaited(getTransactionCacheEarly(iterationsAddressArray));
}
- return Tuple2(addressArray, type);
+ return Tuple3(addressArray, type, highestIndexWithHistory);
}
Future getTransactionCacheEarly(List allAddresses) async {
@@ -561,9 +567,9 @@ class BitcoinWallet extends CoinServiceAPI
DerivePathType.bip84,
];
- final List, DerivePathType>>>
+ final List, DerivePathType, int>>>
receiveFutures = [];
- final List, DerivePathType>>>
+ final List, DerivePathType, int>>>
changeFutures = [];
const receiveChain = 0;
@@ -622,6 +628,7 @@ class BitcoinWallet extends CoinServiceAPI
final List addressesToStore = [];
+ int highestReceivingIndexWithHistory = 0;
// If restoring a wallet that never received any funds, then set receivingArray manually
// If we didn't do this, it'd store an empty array
for (final tuple in receiveResults) {
@@ -633,10 +640,13 @@ class BitcoinWallet extends CoinServiceAPI
);
addressesToStore.add(address);
} else {
+ highestReceivingIndexWithHistory =
+ max(tuple.item3, highestReceivingIndexWithHistory);
addressesToStore.addAll(tuple.item1);
}
}
+ int highestChangeIndexWithHistory = 0;
// If restoring a wallet that never sent any funds with change, then set changeArray
// manually. If we didn't do this, it'd store an empty array.
for (final tuple in changeResults) {
@@ -648,10 +658,20 @@ class BitcoinWallet extends CoinServiceAPI
);
addressesToStore.add(address);
} else {
+ highestChangeIndexWithHistory =
+ max(tuple.item3, highestChangeIndexWithHistory);
addressesToStore.addAll(tuple.item1);
}
}
+ // remove extra addresses to help minimize risk of creating a large gap
+ addressesToStore.removeWhere((e) =>
+ e.subType == isar_models.AddressSubType.change &&
+ e.derivationIndex > highestChangeIndexWithHistory);
+ addressesToStore.removeWhere((e) =>
+ e.subType == isar_models.AddressSubType.receiving &&
+ e.derivationIndex > highestReceivingIndexWithHistory);
+
if (isRescan) {
await db.updateOrPutAddresses(addressesToStore);
} else {
@@ -659,10 +679,11 @@ class BitcoinWallet extends CoinServiceAPI
}
// get own payment code
- final myCode = await getPaymentCode(DerivePathType.bip44, root);
+ // isSegwit does not matter here at all
+ final myCode = await getPaymentCode(isSegwit: false);
// refresh transactions to pick up any received notification transactions
- await _refreshTransactions();
+ await _refreshNotificationAddressTransactions();
try {
final Set codesToCheck = {};
@@ -691,7 +712,10 @@ class BitcoinWallet extends CoinServiceAPI
);
}
- await _updateUTXOs();
+ await Future.wait([
+ _refreshTransactions(),
+ _updateUTXOs(),
+ ]);
await Future.wait([
updateCachedId(walletId),
@@ -915,7 +939,8 @@ class BitcoinWallet extends CoinServiceAPI
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId));
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.1, walletId));
- final myCode = await getPaymentCode(DerivePathType.bip44);
+ // isSegwit does not matter here at all
+ final myCode = await getPaymentCode(isSegwit: false);
final Set codesToCheck = {};
final nym = await PaynymIsApi().nym(myCode.toString());
if (nym.value != null) {
@@ -1221,6 +1246,11 @@ class BitcoinWallet extends CoinServiceAPI
}
await _prefs.init();
+
+ // this will add the notification address to the db if it isn't
+ // already there for older wallets
+ await getMyNotificationAddress();
+
// await _checkCurrentChangeAddressesForTransactions();
// await _checkCurrentReceivingAddressesForTransactions();
}
@@ -1346,10 +1376,12 @@ class BitcoinWallet extends CoinServiceAPI
.getAddresses(walletId)
.filter()
.not()
- .typeEqualTo(isar_models.AddressType.nonWallet)
- .and()
- .not()
- .subTypeEqualTo(isar_models.AddressSubType.nonWallet)
+ .group(
+ (q) => q
+ .typeEqualTo(isar_models.AddressType.nonWallet)
+ .or()
+ .subTypeEqualTo(isar_models.AddressSubType.nonWallet),
+ )
.findAll();
return allAddresses;
}
@@ -1444,6 +1476,10 @@ class BitcoinWallet extends CoinServiceAPI
_generateAddressForChain(1, 0, DerivePathType.bip49),
]);
+ // this will add the notification address to the db if it isn't
+ // already there so it can be watched
+ await getMyNotificationAddress();
+
await db.putAddresses(initialAddresses);
Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info);
@@ -1517,42 +1553,6 @@ class BitcoinWallet extends CoinServiceAPI
);
}
- /// Returns the latest receiving/change (external/internal) address for the wallet depending on [chain]
- /// and
- /// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
- Future _getCurrentAddressForChain(
- int chain,
- DerivePathType derivePathType,
- ) async {
- final subType = chain == 0 // Here, we assume that chain == 1 if it isn't 0
- ? isar_models.AddressSubType.receiving
- : isar_models.AddressSubType.change;
-
- isar_models.AddressType type;
- isar_models.Address? address;
- switch (derivePathType) {
- case DerivePathType.bip44:
- type = isar_models.AddressType.p2pkh;
- break;
- case DerivePathType.bip49:
- type = isar_models.AddressType.p2sh;
- break;
- case DerivePathType.bip84:
- type = isar_models.AddressType.p2wpkh;
- break;
- default:
- throw Exception("DerivePathType unsupported");
- }
- address = await db
- .getAddresses(walletId)
- .filter()
- .typeEqualTo(type)
- .subTypeEqualTo(subType)
- .sortByDerivationIndexDesc()
- .findFirst();
- return address!.value;
- }
-
String _buildDerivationStorageKey({
required int chain,
required DerivePathType derivePathType,
@@ -2020,6 +2020,60 @@ class BitcoinWallet extends CoinServiceAPI
return false;
}
+ Future _refreshNotificationAddressTransactions() async {
+ final address = await getMyNotificationAddress();
+ final hashes = await _fetchHistory([address.value]);
+
+ List