CW-319-Wallet-Seed-keys-URI-QR-code (#831)

* wallet QR code on Wallet/Seed screen

* fix restore height for new wallet

* fix height parameter

* fix currenHeight and HeightByDate for haven

* update configure.dart

* fix coments

* minor fix
This commit is contained in:
Serhii 2023-03-15 17:30:06 +02:00 committed by GitHub
parent f458e5b349
commit fc2627df38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 393 additions and 238 deletions

View file

@ -1,4 +1,6 @@
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
// FIXME: Hardcoded values; Works only for monero // FIXME: Hardcoded values; Works only for monero
@ -93,7 +95,7 @@ int getMoneroHeigthByDate({required DateTime date}) {
int height = 0; int height = 0;
try { try {
if ((dates[raw] == null)||(dates[raw] == lastHeight)) { if ((dates[raw] == null) || (dates[raw] == lastHeight)) {
startHeight = dates.values.toList()[dates.length - 2]; startHeight = dates.values.toList()[dates.length - 2];
endHeight = dates.values.toList()[dates.length - 1]; endHeight = dates.values.toList()[dates.length - 1];
final heightPerDay = (endHeight - startHeight) / 31; final heightPerDay = (endHeight - startHeight) / 31;
@ -118,3 +120,86 @@ int getMoneroHeigthByDate({required DateTime date}) {
return height; return height;
} }
const havenDates = {
"2023-03": 1309180,
"2023-01": 1266810,
"2022-12": 1244510,
"2022-11": 1222970,
"2022-10": 1200700,
"2022-09": 1179140,
"2022-08": 1156870,
"2022-07": 1134600,
"2022-06": 1113030,
"2022-05": 1090800,
"2022-04": 1069250,
"2022-03": 1047000,
"2022-02": 1026960,
"2022-01": 1004700,
"2021-12": 982400,
"2021-11": 961000,
"2021-10": 938600,
"2021-09": 917000,
"2021-08": 894800,
"2021-07": 886000,
"2021-06": 867300,
"2021-05": 845000,
"2021-04": 823500,
"2021-03": 801500,
"2021-02": 781000,
"2021-01": 759000,
"2020-12": 736500,
"2020-11": 715000,
"2020-10": 693000,
"2020-09": 671000,
"2020-08": 649000,
"2020-07": 626600,
"2020-06": 605000,
"2020-05": 582700,
"2020-04": 561100,
"2020-03": 539000,
"2020-02": 518000,
"2020-01": 496000,
"2019-12": 473400,
"2019-11": 451900,
"2019-10": 429600,
"2019-09": 408000,
"2019-08": 385700,
"2019-07": 363800,
"2019-06": 342200,
"2019-05": 320000,
"2019-04": 298400,
"2019-03": 276000,
"2019-02": 256000,
"2019-01": 233700,
"2018-12": 211400,
"2018-11": 189800,
"2018-10": 167500,
"2018-09": 145900,
"2018-08": 123700,
"2018-07": 101400,
"2018-06": 80000,
"2018-05": 57550,
"2018-04": 32000,
"2018-03": 8500
};
DateTime formatMapKey(String key) => dateFormat.parse(key);
int getHavenHeightByDate({required DateTime date}) {
String closestKey =
havenDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
return havenDates[closestKey] ?? 0;
}
Future<int> getHavenCurrentHeight() async {
final response = await http.get(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'));
if (response.statusCode == 200) {
final info = jsonDecode(response.body);
return info['data']['height'] as int;
} else {
throw Exception('Failed to load current blockchain height');
}
}

View file

@ -1,346 +1,331 @@
part of 'haven.dart'; part of 'haven.dart';
class CWHavenAccountList extends HavenAccountList { class CWHavenAccountList extends HavenAccountList {
CWHavenAccountList(this._wallet); CWHavenAccountList(this._wallet);
final Object _wallet;
@override final Object _wallet;
@computed
@override
@computed
ObservableList<Account> get accounts { ObservableList<Account> get accounts {
final havenWallet = _wallet as HavenWallet; final havenWallet = _wallet as HavenWallet;
final accounts = havenWallet.walletAddresses.accountList final accounts = havenWallet.walletAddresses.accountList.accounts
.accounts .map((acc) => Account(id: acc.id, label: acc.label))
.map((acc) => Account(id: acc.id, label: acc.label)) .toList();
.toList(); return ObservableList<Account>.of(accounts);
return ObservableList<Account>.of(accounts);
} }
@override @override
void update(Object wallet) { void update(Object wallet) {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.accountList.update(); havenWallet.walletAddresses.accountList.update();
} }
@override @override
void refresh(Object wallet) { void refresh(Object wallet) {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.accountList.refresh(); havenWallet.walletAddresses.accountList.refresh();
} }
@override @override
List<Account> getAll(Object wallet) { List<Account> getAll(Object wallet) {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
return havenWallet.walletAddresses.accountList return havenWallet.walletAddresses.accountList
.getAll() .getAll()
.map((acc) => Account(id: acc.id, label: acc.label)) .map((acc) => Account(id: acc.id, label: acc.label))
.toList(); .toList();
} }
@override @override
Future<void> addAccount(Object wallet, {required String label}) async { Future<void> addAccount(Object wallet, {required String label}) async {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
await havenWallet.walletAddresses.accountList.addAccount(label: label); await havenWallet.walletAddresses.accountList.addAccount(label: label);
} }
@override @override
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async { Future<void> setLabelAccount(Object wallet,
final havenWallet = wallet as HavenWallet; {required int accountIndex, required String label}) async {
await havenWallet.walletAddresses.accountList final havenWallet = wallet as HavenWallet;
.setLabelAccount( await havenWallet.walletAddresses.accountList
accountIndex: accountIndex, .setLabelAccount(accountIndex: accountIndex, label: label);
label: label);
} }
} }
class CWHavenSubaddressList extends MoneroSubaddressList { class CWHavenSubaddressList extends MoneroSubaddressList {
CWHavenSubaddressList(this._wallet); CWHavenSubaddressList(this._wallet);
final Object _wallet;
@override final Object _wallet;
@computed
@override
@computed
ObservableList<Subaddress> get subaddresses { ObservableList<Subaddress> get subaddresses {
final havenWallet = _wallet as HavenWallet; final havenWallet = _wallet as HavenWallet;
final subAddresses = havenWallet.walletAddresses.subaddressList final subAddresses = havenWallet.walletAddresses.subaddressList.subaddresses
.subaddresses .map((sub) => Subaddress(id: sub.id, address: sub.address, label: sub.label))
.map((sub) => Subaddress( .toList();
id: sub.id, return ObservableList<Subaddress>.of(subAddresses);
address: sub.address,
label: sub.label))
.toList();
return ObservableList<Subaddress>.of(subAddresses);
} }
@override @override
void update(Object wallet, {required int accountIndex}) { void update(Object wallet, {required int accountIndex}) {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex); havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
} }
@override @override
void refresh(Object wallet, {required int accountIndex}) { void refresh(Object wallet, {required int accountIndex}) {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex); havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
} }
@override @override
List<Subaddress> getAll(Object wallet) { List<Subaddress> getAll(Object wallet) {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
return havenWallet.walletAddresses return havenWallet.walletAddresses.subaddressList
.subaddressList .getAll()
.getAll() .map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
.map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address)) .toList();
.toList();
} }
@override @override
Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async { Future<void> addSubaddress(Object wallet,
final havenWallet = wallet as HavenWallet; {required int accountIndex, required String label}) async {
await havenWallet.walletAddresses.subaddressList final havenWallet = wallet as HavenWallet;
.addSubaddress( await havenWallet.walletAddresses.subaddressList
accountIndex: accountIndex, .addSubaddress(accountIndex: accountIndex, label: label);
label: label);
} }
@override @override
Future<void> setLabelSubaddress(Object wallet, Future<void> setLabelSubaddress(Object wallet,
{required int accountIndex, required int addressIndex, required String label}) async { {required int accountIndex, required int addressIndex, required String label}) async {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
await havenWallet.walletAddresses.subaddressList await havenWallet.walletAddresses.subaddressList
.setLabelSubaddress( .setLabelSubaddress(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
accountIndex: accountIndex,
addressIndex: addressIndex,
label: label);
} }
} }
class CWHavenWalletDetails extends HavenWalletDetails { class CWHavenWalletDetails extends HavenWalletDetails {
CWHavenWalletDetails(this._wallet); CWHavenWalletDetails(this._wallet);
final Object _wallet;
@computed final Object _wallet;
@computed
@override @override
Account get account { Account get account {
final havenWallet = _wallet as HavenWallet; final havenWallet = _wallet as HavenWallet;
final acc = havenWallet.walletAddresses.account as monero_account.Account; final acc = havenWallet.walletAddresses.account as monero_account.Account;
return Account(id: acc.id, label: acc.label); return Account(id: acc.id, label: acc.label);
} }
@computed @computed
@override @override
HavenBalance get balance { HavenBalance get balance {
final havenWallet = _wallet as HavenWallet; final havenWallet = _wallet as HavenWallet;
final balance = havenWallet.balance; final balance = havenWallet.balance;
throw Exception('Unimplemented'); throw Exception('Unimplemented');
//return HavenBalance( //return HavenBalance(
// fullBalance: balance.fullBalance, // fullBalance: balance.fullBalance,
// unlockedBalance: balance.unlockedBalance); // unlockedBalance: balance.unlockedBalance);
} }
} }
class CWHaven extends Haven { class CWHaven extends Haven {
@override @override
HavenAccountList getAccountList(Object wallet) { HavenAccountList getAccountList(Object wallet) {
return CWHavenAccountList(wallet); return CWHavenAccountList(wallet);
} }
@override
MoneroSubaddressList getSubaddressList(Object wallet) {
return CWHavenSubaddressList(wallet);
}
@override @override
TransactionHistoryBase getTransactionHistory(Object wallet) { MoneroSubaddressList getSubaddressList(Object wallet) {
final havenWallet = wallet as HavenWallet; return CWHavenSubaddressList(wallet);
return havenWallet.transactionHistory; }
}
@override @override
HavenWalletDetails getMoneroWalletDetails(Object wallet) { TransactionHistoryBase getTransactionHistory(Object wallet) {
return CWHavenWalletDetails(wallet); final havenWallet = wallet as HavenWallet;
} return havenWallet.transactionHistory;
}
@override @override
int getHeigthByDate({required DateTime date}) { HavenWalletDetails getMoneroWalletDetails(Object wallet) {
return getMoneroHeigthByDate(date: date); return CWHavenWalletDetails(wallet);
} }
@override
TransactionPriority getDefaultTransactionPriority() {
return MoneroTransactionPriority.automatic;
}
@override @override
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) { int getHeightByDate({required DateTime date}) => getHavenHeightByDate(date: date);
return MoneroTransactionPriority.deserialize(raw: raw);
}
@override @override
List<TransactionPriority> getTransactionPriorities() { Future<int> getCurrentHeight() => getHavenCurrentHeight();
return MoneroTransactionPriority.all;
}
@override @override
List<String> getMoneroWordList(String language) { TransactionPriority getDefaultTransactionPriority() {
switch (language.toLowerCase()) { return MoneroTransactionPriority.automatic;
case 'english': }
return EnglishMnemonics.words;
case 'chinese (simplified)':
return ChineseSimplifiedMnemonics.words;
case 'dutch':
return DutchMnemonics.words;
case 'german':
return GermanMnemonics.words;
case 'japanese':
return JapaneseMnemonics.words;
case 'portuguese':
return PortugueseMnemonics.words;
case 'russian':
return RussianMnemonics.words;
case 'spanish':
return SpanishMnemonics.words;
case 'french':
return FrenchMnemonics.words;
case 'italian':
return ItalianMnemonics.words;
default:
return EnglishMnemonics.words;
}
}
@override @override
WalletCredentials createHavenRestoreWalletFromKeysCredentials({ TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
required String name, return MoneroTransactionPriority.deserialize(raw: raw);
}
@override
List<TransactionPriority> getTransactionPriorities() {
return MoneroTransactionPriority.all;
}
@override
List<String> getMoneroWordList(String language) {
switch (language.toLowerCase()) {
case 'english':
return EnglishMnemonics.words;
case 'chinese (simplified)':
return ChineseSimplifiedMnemonics.words;
case 'dutch':
return DutchMnemonics.words;
case 'german':
return GermanMnemonics.words;
case 'japanese':
return JapaneseMnemonics.words;
case 'portuguese':
return PortugueseMnemonics.words;
case 'russian':
return RussianMnemonics.words;
case 'spanish':
return SpanishMnemonics.words;
case 'french':
return FrenchMnemonics.words;
case 'italian':
return ItalianMnemonics.words;
default:
return EnglishMnemonics.words;
}
}
@override
WalletCredentials createHavenRestoreWalletFromKeysCredentials(
{required String name,
required String spendKey, required String spendKey,
required String viewKey, required String viewKey,
required String address, required String address,
required String password, required String password,
required String language, required String language,
required int height}) { required int height}) {
return HavenRestoreWalletFromKeysCredentials( return HavenRestoreWalletFromKeysCredentials(
name: name, name: name,
spendKey: spendKey, spendKey: spendKey,
viewKey: viewKey, viewKey: viewKey,
address: address, address: address,
password: password, password: password,
language: language, language: language,
height: height); height: height);
} }
@override
WalletCredentials createHavenRestoreWalletFromSeedCredentials({
required String name,
required String password,
required int height,
required String mnemonic}) {
return HavenRestoreWalletFromSeedCredentials(
name: name,
password: password,
height: height,
mnemonic: mnemonic);
}
@override @override
WalletCredentials createHavenNewWalletCredentials({ WalletCredentials createHavenRestoreWalletFromSeedCredentials(
required String name, {required String name,
required String language, required String password,
String? password}) { required int height,
return HavenNewWalletCredentials( required String mnemonic}) {
name: name, return HavenRestoreWalletFromSeedCredentials(
password: password, name: name, password: password, height: height, mnemonic: mnemonic);
language: language); }
}
@override @override
Map<String, String> getKeys(Object wallet) { WalletCredentials createHavenNewWalletCredentials(
final havenWallet = wallet as HavenWallet; {required String name, required String language, String? password}) {
final keys = havenWallet.keys; return HavenNewWalletCredentials(name: name, password: password, language: language);
return <String, String>{ }
'privateSpendKey': keys.privateSpendKey,
@override
Map<String, String> getKeys(Object wallet) {
final havenWallet = wallet as HavenWallet;
final keys = havenWallet.keys;
return <String, String>{
'privateSpendKey': keys.privateSpendKey,
'privateViewKey': keys.privateViewKey, 'privateViewKey': keys.privateViewKey,
'publicSpendKey': keys.publicSpendKey, 'publicSpendKey': keys.publicSpendKey,
'publicViewKey': keys.publicViewKey}; 'publicViewKey': keys.publicViewKey
} };
}
@override @override
Object createHavenTransactionCreationCredentials({ Object createHavenTransactionCreationCredentials(
required List<Output> outputs, {required List<Output> outputs,
required TransactionPriority priority, required TransactionPriority priority,
required String assetType}) { required String assetType}) {
return HavenTransactionCreationCredentials( return HavenTransactionCreationCredentials(
outputs: outputs.map((out) => OutputInfo( outputs: outputs
fiatAmount: out.fiatAmount, .map((out) => OutputInfo(
cryptoAmount: out.cryptoAmount, fiatAmount: out.fiatAmount,
address: out.address, cryptoAmount: out.cryptoAmount,
note: out.note, address: out.address,
sendAll: out.sendAll, note: out.note,
extractedAddress: out.extractedAddress, sendAll: out.sendAll,
isParsedAddress: out.isParsedAddress, extractedAddress: out.extractedAddress,
formattedCryptoAmount: out.formattedCryptoAmount)) isParsedAddress: out.isParsedAddress,
.toList(), formattedCryptoAmount: out.formattedCryptoAmount))
priority: priority as MoneroTransactionPriority, .toList(),
assetType: assetType); priority: priority as MoneroTransactionPriority,
} assetType: assetType);
}
@override @override
String formatterMoneroAmountToString({required int amount}) { String formatterMoneroAmountToString({required int amount}) {
return moneroAmountToString(amount: amount); return moneroAmountToString(amount: amount);
} }
@override
double formatterMoneroAmountToDouble({required int amount}) {
return moneroAmountToDouble(amount: amount);
}
@override @override
int formatterMoneroParseAmount({required String amount}) { double formatterMoneroAmountToDouble({required int amount}) {
return moneroParseAmount(amount: amount); return moneroAmountToDouble(amount: amount);
} }
@override @override
Account getCurrentAccount(Object wallet) { int formatterMoneroParseAmount({required String amount}) {
final havenWallet = wallet as HavenWallet; return moneroParseAmount(amount: amount);
final acc = havenWallet.walletAddresses.account as monero_account.Account; }
return Account(id: acc.id, label: acc.label);
}
@override @override
void setCurrentAccount(Object wallet, int id, String label) { Account getCurrentAccount(Object wallet) {
final havenWallet = wallet as HavenWallet; final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label); final acc = havenWallet.walletAddresses.account as monero_account.Account;
} return Account(id: acc.id, label: acc.label);
}
@override @override
void onStartup() { void setCurrentAccount(Object wallet, int id, String label) {
monero_wallet_api.onStartup(); final havenWallet = wallet as HavenWallet;
} havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
}
@override @override
int getTransactionInfoAccountId(TransactionInfo tx) { void onStartup() {
final havenTransactionInfo = tx as HavenTransactionInfo; monero_wallet_api.onStartup();
return havenTransactionInfo.accountIndex; }
}
@override @override
WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) { int getTransactionInfoAccountId(TransactionInfo tx) {
return HavenWalletService(walletInfoSource); final havenTransactionInfo = tx as HavenTransactionInfo;
} return havenTransactionInfo.accountIndex;
}
@override @override
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) { WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) {
final havenWallet = wallet as HavenWallet; return HavenWalletService(walletInfoSource);
return havenWallet.getTransactionAddress(accountIndex, addressIndex); }
}
@override @override
CryptoCurrency assetOfTransaction(TransactionInfo tx) { String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
final transaction = tx as HavenTransactionInfo; final havenWallet = wallet as HavenWallet;
final asset = CryptoCurrency.fromString(transaction.assetType); return havenWallet.getTransactionAddress(accountIndex, addressIndex);
return asset; }
}
@override @override
List<AssetRate> getAssetRate() CryptoCurrency assetOfTransaction(TransactionInfo tx) {
=> getRate() final transaction = tx as HavenTransactionInfo;
.map((rate) => AssetRate(rate.getAssetType(), rate.getRate())) final asset = CryptoCurrency.fromString(transaction.assetType);
.toList(); return asset;
}
@override
List<AssetRate> getAssetRate() =>
getRate().map((rate) => AssetRate(rate.getAssetType(), rate.getRate())).toList();
} }

View file

@ -1,6 +1,7 @@
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/src/widgets/section_divider.dart'; import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_bar.dart';
import 'package:device_display_brightness/device_display_brightness.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -9,6 +10,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/list_row.dart'; import 'package:cake_wallet/src/widgets/list_row.dart';
import 'package:cake_wallet/view_model/wallet_keys_view_model.dart'; import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
import 'package:cake_wallet/routes.dart';
class WalletKeysPage extends BasePage { class WalletKeysPage extends BasePage {
WalletKeysPage(this.walletKeysViewModel); WalletKeysPage(this.walletKeysViewModel);
@ -18,6 +20,32 @@ class WalletKeysPage extends BasePage {
final WalletKeysViewModel walletKeysViewModel; final WalletKeysViewModel walletKeysViewModel;
@override
Widget trailing(BuildContext context) => IconButton(
onPressed: () async {
// Get the current brightness:
final double brightness = await DeviceDisplayBrightness.getBrightness();
// ignore: unawaited_futures
DeviceDisplayBrightness.setBrightness(1.0);
await Navigator.pushNamed(
context,
Routes.fullscreenQR,
arguments: {
'qrData': (await walletKeysViewModel.url).toString(),
'isLight': true,
},
);
// ignore: unawaited_futures
DeviceDisplayBrightness.setBrightness(brightness);
},
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
icon: Image.asset(
'assets/images/qr_code_icon.png',
));
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
return Column( return Column(

View file

@ -5,6 +5,7 @@ import 'package:cw_core/wallet_base.dart';
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart'; import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/haven/haven.dart'; import 'package:cake_wallet/haven/haven.dart';
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
part 'wallet_keys_view_model.g.dart'; part 'wallet_keys_view_model.g.dart';
@ -15,10 +16,11 @@ abstract class WalletKeysViewModelBase with Store {
: title = wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin : title = wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin
? S.current.wallet_seed ? S.current.wallet_seed
: S.current.wallet_keys, : S.current.wallet_keys,
_wallet = wallet,
_restoreHeight = wallet.walletInfo.restoreHeight,
items = ObservableList<StandartListItem>() { items = ObservableList<StandartListItem>() {
if (wallet.type == WalletType.monero) { if (wallet.type == WalletType.monero) {
final keys = monero!.getKeys(wallet); final keys = monero!.getKeys(wallet);
items.addAll([ items.addAll([
if (keys['publicSpendKey'] != null) if (keys['publicSpendKey'] != null)
StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!), StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!),
@ -34,7 +36,6 @@ abstract class WalletKeysViewModelBase with Store {
if (wallet.type == WalletType.haven) { if (wallet.type == WalletType.haven) {
final keys = haven!.getKeys(wallet); final keys = haven!.getKeys(wallet);
items.addAll([ items.addAll([
if (keys['publicSpendKey'] != null) if (keys['publicSpendKey'] != null)
StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!), StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!),
@ -58,4 +59,59 @@ abstract class WalletKeysViewModelBase with Store {
final ObservableList<StandartListItem> items; final ObservableList<StandartListItem> items;
final String title; final String title;
final WalletBase _wallet;
final int _restoreHeight;
Future<int?> currentHeight() async {
if (_wallet.type == WalletType.haven) {
return await haven!.getCurrentHeight();
}
if (_wallet.type == WalletType.monero) {
return monero_wallet.getCurrentHeight();
}
return null;
}
String get _path {
switch (_wallet.type) {
case WalletType.monero:
return 'monero_wallet:';
case WalletType.bitcoin:
return 'bitcoin_wallet:';
case WalletType.litecoin:
return 'litecoin_wallet:';
case WalletType.haven:
return 'haven_wallet:';
default:
throw Exception('Unexpected wallet type: ${_wallet.toString()}');
}
}
Future<String?> get restoreHeight async {
if (_restoreHeight != 0) {
return _restoreHeight.toString();
}
final _currentHeight = await currentHeight();
if (_currentHeight == null) {
return null;
}
return ((_currentHeight / 1000).floor() * 1000).toString();
}
Future<Map<String, String>> get _queryParams async {
final restoreHeightResult = await restoreHeight;
return {
'seed': _wallet.seed,
if (restoreHeightResult != null) ...{'height': restoreHeightResult}
};
}
Future<Uri> get url async {
return Uri(
path: _path,
queryParameters: await _queryParams,
);
}
} }

View file

@ -402,7 +402,8 @@ abstract class Haven {
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex); String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
int getHeigthByDate({required DateTime date}); int getHeightByDate({required DateTime date});
Future<int> getCurrentHeight();
TransactionPriority getDefaultTransactionPriority(); TransactionPriority getDefaultTransactionPriority();
TransactionPriority deserializeMoneroTransactionPriority({required int raw}); TransactionPriority deserializeMoneroTransactionPriority({required int raw});
List<TransactionPriority> getTransactionPriorities(); List<TransactionPriority> getTransactionPriorities();