Skip to content

Commit cce9faa

Browse files
committed
Merge branch 'staging' into various
# Conflicts: # lib/pages/add_wallet_views/restore_wallet_view/restore_view_only_wallet_view.dart # lib/pages/wallet_view/wallet_view.dart
2 parents 56cd4b1 + 6f1a57e commit cce9faa

18 files changed

Lines changed: 1117 additions & 353 deletions

File tree

lib/models/keys/view_only_wallet_data.dart

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import 'key_data_interface.dart';
77
enum ViewOnlyWalletType {
88
cryptonote,
99
addressOnly,
10-
xPub;
10+
xPub,
11+
spark;
1112
}
1213

1314
sealed class ViewOnlyWalletData with KeyDataInterface {
@@ -46,6 +47,12 @@ sealed class ViewOnlyWalletData with KeyDataInterface {
4647
jsonEncodedString,
4748
walletId: walletId,
4849
);
50+
51+
case ViewOnlyWalletType.spark:
52+
return SparkViewOnlyWalletData.fromJsonEncodedString(
53+
jsonEncodedString,
54+
walletId: walletId,
55+
);
4956
}
5057
}
5158

@@ -162,3 +169,34 @@ class ExtendedKeysViewOnlyWalletData extends ViewOnlyWalletData {
162169
],
163170
});
164171
}
172+
173+
class SparkViewOnlyWalletData extends ViewOnlyWalletData {
174+
@override
175+
final type = ViewOnlyWalletType.spark;
176+
177+
final String viewKey;
178+
179+
SparkViewOnlyWalletData({
180+
required super.walletId,
181+
required this.viewKey,
182+
});
183+
184+
static SparkViewOnlyWalletData fromJsonEncodedString(
185+
String jsonEncodedString, {
186+
required String walletId,
187+
}) {
188+
final map = jsonDecode(jsonEncodedString) as Map;
189+
final json = Map<String, dynamic>.from(map);
190+
191+
return SparkViewOnlyWalletData(
192+
walletId: walletId,
193+
viewKey: json["viewKey"] as String,
194+
);
195+
}
196+
197+
@override
198+
String toJsonEncodedString() => jsonEncode({
199+
"type": type.index,
200+
"viewKey": viewKey,
201+
});
202+
}

lib/pages/add_wallet_views/restore_wallet_view/restore_view_only_wallet_view.dart

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import '../../../widgets/desktop/desktop_app_bar.dart';
3535
import '../../../widgets/desktop/desktop_scaffold.dart';
3636
import '../../../widgets/desktop/primary_button.dart';
3737
import '../../../widgets/stack_text_field.dart';
38-
import '../../../widgets/toggle.dart';
38+
import '../../../widgets/options.dart';
3939
import '../../home_view/home_view.dart';
4040
import 'confirm_recovery_dialog.dart';
4141
import 'sub_widgets/restore_failed_dialog.dart';
@@ -67,13 +67,13 @@ class _RestoreViewOnlyWalletViewState
6767
extends ConsumerState<RestoreViewOnlyWalletView> {
6868
late final TextEditingController addressController;
6969
late final TextEditingController viewKeyController;
70+
late final TextEditingController sparkViewKeyController;
7071

71-
late String _currentDropDownValue;
72+
late ViewOnlyWalletType _walletType;
7273

7374
bool _enableRestoreButton = false;
74-
bool _addressOnly = false;
75-
7675
bool _buttonLock = false;
76+
late String _currentDropDownValue;
7777

7878
Future<void> _requestRestore() async {
7979
if (_buttonLock) return;
@@ -106,20 +106,16 @@ class _RestoreViewOnlyWalletViewState
106106
WalletInfoKeys.isViewOnlyKey: true,
107107
};
108108

109-
final ViewOnlyWalletType viewOnlyWalletType;
109+
ViewOnlyWalletType viewOnlyWalletType = _walletType;
110110
if (widget.coin is Bip39HDCurrency) {
111-
viewOnlyWalletType = _addressOnly
112-
? ViewOnlyWalletType.addressOnly
113-
: ViewOnlyWalletType.xPub;
114111
} else if (widget.coin is CryptonoteCurrency) {
115112
viewOnlyWalletType = ViewOnlyWalletType.cryptonote;
116113
} else {
117114
throw Exception(
118115
"Unsupported view only wallet currency type found: ${widget.coin.runtimeType}",
119116
);
120117
}
121-
otherDataJson[WalletInfoKeys.viewOnlyTypeIndexKey] =
122-
viewOnlyWalletType.index;
118+
otherDataJson[WalletInfoKeys.viewOnlyTypeIndexKey] = _walletType.index;
123119

124120
if (!Platform.isLinux && !Util.isDesktop) await WakelockPlus.enable();
125121

@@ -190,6 +186,16 @@ class _RestoreViewOnlyWalletViewState
190186
],
191187
);
192188
break;
189+
190+
case ViewOnlyWalletType.spark:
191+
if (sparkViewKeyController.text.isEmpty) {
192+
throw Exception("Spark View Key is empty");
193+
}
194+
viewOnlyData = SparkViewOnlyWalletData(
195+
walletId: info.walletId,
196+
viewKey: sparkViewKeyController.text,
197+
);
198+
break;
193199
}
194200

195201
var node = ref
@@ -308,18 +314,23 @@ class _RestoreViewOnlyWalletViewState
308314
super.initState();
309315
addressController = TextEditingController();
310316
viewKeyController = TextEditingController();
317+
sparkViewKeyController = TextEditingController();
311318

312319
if (widget.coin is Bip39HDCurrency) {
313320
_currentDropDownValue = (widget.coin as Bip39HDCurrency)
314321
.supportedHardenedDerivationPaths
315322
.last;
323+
_walletType = ViewOnlyWalletType.xPub;
324+
} else if (widget.coin is CryptonoteCurrency) {
325+
_walletType = ViewOnlyWalletType.cryptonote;
316326
}
317327
}
318328

319329
@override
320330
void dispose() {
321331
addressController.dispose();
322332
viewKeyController.dispose();
333+
sparkViewKeyController.dispose();
323334
super.dispose();
324335
}
325336

@@ -384,21 +395,25 @@ class _RestoreViewOnlyWalletViewState
384395
if (isElectrumX)
385396
SizedBox(
386397
height: isDesktop ? 56 : 48,
387-
width: isDesktop ? 490 : null,
388-
child: Toggle(
398+
width: isDesktop ? 490 : double.infinity,
399+
child: Options(
389400
key: UniqueKey(),
390-
onText: "Extended pub key",
391-
offText: "Single address",
392-
onColor: Theme.of(
393-
context,
394-
).extension<StackColors>()!.popupBG,
395-
offColor: Theme.of(
396-
context,
397-
).extension<StackColors>()!.textFieldDefaultBG,
398-
isOn: _addressOnly,
401+
texts: [
402+
"Single address",
403+
"Extended pub key",
404+
if (widget.coin is Firo)
405+
isDesktop ? "Spark View Key" : "View Key"
406+
],
407+
onColor: Theme.of(context)
408+
.extension<StackColors>()!
409+
.popupBG,
410+
offColor: Theme.of(context)
411+
.extension<StackColors>()!
412+
.textFieldDefaultBG,
413+
selectedIndex: _walletType.index-1,
399414
onValueChanged: (value) {
400415
setState(() {
401-
_addressOnly = value;
416+
_walletType = ViewOnlyWalletType.values[value+1];
402417
});
403418
},
404419
decoration: BoxDecoration(
@@ -409,8 +424,10 @@ class _RestoreViewOnlyWalletViewState
409424
),
410425
),
411426
),
412-
SizedBox(height: isDesktop ? 24 : 16),
413-
if (!isElectrumX || _addressOnly)
427+
SizedBox(
428+
height: isDesktop ? 24 : 16,
429+
),
430+
if (!isElectrumX || _walletType == ViewOnlyWalletType.addressOnly)
414431
FullTextField(
415432
key: const Key("viewOnlyAddressRestoreFieldKey"),
416433
label: "Address",
@@ -430,8 +447,11 @@ class _RestoreViewOnlyWalletViewState
430447
}
431448
},
432449
),
433-
if (!isElectrumX) SizedBox(height: isDesktop ? 16 : 12),
434-
if (isElectrumX && !_addressOnly)
450+
if (!isElectrumX)
451+
SizedBox(
452+
height: isDesktop ? 16 : 12,
453+
),
454+
if (isElectrumX && _walletType == ViewOnlyWalletType.xPub)
435455
DropdownButtonHideUnderline(
436456
child: DropdownButton2<String>(
437457
value: _currentDropDownValue,
@@ -499,9 +519,11 @@ class _RestoreViewOnlyWalletViewState
499519
),
500520
),
501521
),
502-
if (isElectrumX && !_addressOnly)
503-
SizedBox(height: isDesktop ? 16 : 12),
504-
if (!isElectrumX || !_addressOnly)
522+
if (isElectrumX && _walletType == ViewOnlyWalletType.xPub)
523+
SizedBox(
524+
height: isDesktop ? 16 : 12,
525+
),
526+
if (!isElectrumX || _walletType == ViewOnlyWalletType.xPub)
505527
FullTextField(
506528
key: const Key("viewOnlyKeyRestoreFieldKey"),
507529
label:
@@ -522,6 +544,21 @@ class _RestoreViewOnlyWalletViewState
522544
}
523545
},
524546
),
547+
if (_walletType == ViewOnlyWalletType.spark)
548+
SizedBox(
549+
height: isDesktop ? 16 : 12,
550+
),
551+
if (_walletType == ViewOnlyWalletType.spark)
552+
FullTextField(
553+
key: const Key("viewOnlySparkViewKeyRestoreFieldKey"),
554+
label: "Spark View Key",
555+
controller: sparkViewKeyController,
556+
onChanged: (value) {
557+
setState(() {
558+
_enableRestoreButton = value.isNotEmpty;
559+
});
560+
},
561+
),
525562
if (!isDesktop) const Spacer(),
526563
SizedBox(height: isDesktop ? 24 : 16),
527564
PrimaryButton(

lib/pages/receive_view/receive_view.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,16 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
179179
if (wallet is Bip39HDWallet && wallet is! BCashInterface) {
180180
DerivePathType? type;
181181
if (wallet.isViewOnly && wallet is ExtendedKeysInterface) {
182-
final voData =
183-
await wallet.getViewOnlyWalletData()
184-
as ExtendedKeysViewOnlyWalletData;
182+
final voData = await wallet.getViewOnlyWalletData();
185183
for (final t in wallet.cryptoCurrency.supportedDerivationPathTypes) {
186184
final testPath = wallet.cryptoCurrency.constructDerivePath(
187185
derivePathType: t,
188186
chain: 0,
189187
index: 0,
190188
);
191-
if (testPath.startsWith(voData.xPubs.first.path)) {
189+
if (voData is SparkViewOnlyWalletData) {
190+
type = t;
191+
} else if (testPath.startsWith((voData as ExtendedKeysViewOnlyWalletData).xPubs.first.path)) {
192192
type = t;
193193
break;
194194
}

lib/pages/settings_views/sub_widgets/view_only_wallet_data_widget.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,22 @@ class ViewOnlyWalletDataWidget extends StatelessWidget {
8181
),
8282
],
8383
),
84+
final SparkViewOnlyWalletData e => Column(
85+
crossAxisAlignment: CrossAxisAlignment.stretch,
86+
children: [
87+
DetailItem(
88+
title: "View Key",
89+
detail: e.viewKey,
90+
button: Util.isDesktop
91+
? IconCopyButton(
92+
data: e.viewKey,
93+
)
94+
: SimpleCopyButton(
95+
data: e.viewKey,
96+
),
97+
),
98+
],
99+
),
84100
};
85101
}
86102
}

0 commit comments

Comments
 (0)