From fc2627df38178fcb7d4ac769e859b6227cb63868 Mon Sep 17 00:00:00 2001 From: Serhii Date: Wed, 15 Mar 2023 17:30:06 +0200 Subject: [PATCH] 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 --- cw_core/lib/get_height_by_date.dart | 87 +++- lib/haven/cw_haven.dart | 453 +++++++++--------- .../screens/wallet_keys/wallet_keys_page.dart | 28 ++ lib/view_model/wallet_keys_view_model.dart | 60 ++- tool/configure.dart | 3 +- 5 files changed, 393 insertions(+), 238 deletions(-) diff --git a/cw_core/lib/get_height_by_date.dart b/cw_core/lib/get_height_by_date.dart index e350a19cb..768a5534f 100644 --- a/cw_core/lib/get_height_by_date.dart +++ b/cw_core/lib/get_height_by_date.dart @@ -1,4 +1,6 @@ import 'package:intl/intl.dart'; +import 'dart:convert'; +import 'package:http/http.dart' as http; // FIXME: Hardcoded values; Works only for monero @@ -93,7 +95,7 @@ int getMoneroHeigthByDate({required DateTime date}) { int height = 0; try { - if ((dates[raw] == null)||(dates[raw] == lastHeight)) { + if ((dates[raw] == null) || (dates[raw] == lastHeight)) { startHeight = dates.values.toList()[dates.length - 2]; endHeight = dates.values.toList()[dates.length - 1]; final heightPerDay = (endHeight - startHeight) / 31; @@ -118,3 +120,86 @@ int getMoneroHeigthByDate({required DateTime date}) { 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 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'); + } +} diff --git a/lib/haven/cw_haven.dart b/lib/haven/cw_haven.dart index 6e805b0e3..57c4e49c3 100644 --- a/lib/haven/cw_haven.dart +++ b/lib/haven/cw_haven.dart @@ -1,346 +1,331 @@ part of 'haven.dart'; class CWHavenAccountList extends HavenAccountList { - CWHavenAccountList(this._wallet); - final Object _wallet; + CWHavenAccountList(this._wallet); - @override - @computed + final Object _wallet; + + @override + @computed ObservableList get accounts { - final havenWallet = _wallet as HavenWallet; - final accounts = havenWallet.walletAddresses.accountList - .accounts - .map((acc) => Account(id: acc.id, label: acc.label)) - .toList(); - return ObservableList.of(accounts); + final havenWallet = _wallet as HavenWallet; + final accounts = havenWallet.walletAddresses.accountList.accounts + .map((acc) => Account(id: acc.id, label: acc.label)) + .toList(); + return ObservableList.of(accounts); } @override void update(Object wallet) { - final havenWallet = wallet as HavenWallet; - havenWallet.walletAddresses.accountList.update(); + final havenWallet = wallet as HavenWallet; + havenWallet.walletAddresses.accountList.update(); } @override - void refresh(Object wallet) { - final havenWallet = wallet as HavenWallet; - havenWallet.walletAddresses.accountList.refresh(); - } + void refresh(Object wallet) { + final havenWallet = wallet as HavenWallet; + havenWallet.walletAddresses.accountList.refresh(); + } - @override + @override List getAll(Object wallet) { - final havenWallet = wallet as HavenWallet; - return havenWallet.walletAddresses.accountList - .getAll() - .map((acc) => Account(id: acc.id, label: acc.label)) - .toList(); + final havenWallet = wallet as HavenWallet; + return havenWallet.walletAddresses.accountList + .getAll() + .map((acc) => Account(id: acc.id, label: acc.label)) + .toList(); } @override Future addAccount(Object wallet, {required String label}) async { - final havenWallet = wallet as HavenWallet; - await havenWallet.walletAddresses.accountList.addAccount(label: label); + final havenWallet = wallet as HavenWallet; + await havenWallet.walletAddresses.accountList.addAccount(label: label); } @override - Future setLabelAccount(Object wallet, {required int accountIndex, required String label}) async { - final havenWallet = wallet as HavenWallet; - await havenWallet.walletAddresses.accountList - .setLabelAccount( - accountIndex: accountIndex, - label: label); + Future setLabelAccount(Object wallet, + {required int accountIndex, required String label}) async { + final havenWallet = wallet as HavenWallet; + await havenWallet.walletAddresses.accountList + .setLabelAccount(accountIndex: accountIndex, label: label); } } class CWHavenSubaddressList extends MoneroSubaddressList { - CWHavenSubaddressList(this._wallet); - final Object _wallet; + CWHavenSubaddressList(this._wallet); - @override - @computed + final Object _wallet; + + @override + @computed ObservableList get subaddresses { - final havenWallet = _wallet as HavenWallet; - final subAddresses = havenWallet.walletAddresses.subaddressList - .subaddresses - .map((sub) => Subaddress( - id: sub.id, - address: sub.address, - label: sub.label)) - .toList(); - return ObservableList.of(subAddresses); + final havenWallet = _wallet as HavenWallet; + final subAddresses = havenWallet.walletAddresses.subaddressList.subaddresses + .map((sub) => Subaddress(id: sub.id, address: sub.address, label: sub.label)) + .toList(); + return ObservableList.of(subAddresses); } @override void update(Object wallet, {required int accountIndex}) { - final havenWallet = wallet as HavenWallet; - havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex); + final havenWallet = wallet as HavenWallet; + havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex); } @override void refresh(Object wallet, {required int accountIndex}) { - final havenWallet = wallet as HavenWallet; - havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex); + final havenWallet = wallet as HavenWallet; + havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex); } @override List getAll(Object wallet) { - final havenWallet = wallet as HavenWallet; - return havenWallet.walletAddresses - .subaddressList - .getAll() - .map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address)) - .toList(); + final havenWallet = wallet as HavenWallet; + return havenWallet.walletAddresses.subaddressList + .getAll() + .map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address)) + .toList(); } @override - Future addSubaddress(Object wallet, {required int accountIndex, required String label}) async { - final havenWallet = wallet as HavenWallet; - await havenWallet.walletAddresses.subaddressList - .addSubaddress( - accountIndex: accountIndex, - label: label); + Future addSubaddress(Object wallet, + {required int accountIndex, required String label}) async { + final havenWallet = wallet as HavenWallet; + await havenWallet.walletAddresses.subaddressList + .addSubaddress(accountIndex: accountIndex, label: label); } @override Future setLabelSubaddress(Object wallet, {required int accountIndex, required int addressIndex, required String label}) async { - final havenWallet = wallet as HavenWallet; - await havenWallet.walletAddresses.subaddressList - .setLabelSubaddress( - accountIndex: accountIndex, - addressIndex: addressIndex, - label: label); + final havenWallet = wallet as HavenWallet; + await havenWallet.walletAddresses.subaddressList + .setLabelSubaddress(accountIndex: accountIndex, addressIndex: addressIndex, label: label); } } class CWHavenWalletDetails extends HavenWalletDetails { - CWHavenWalletDetails(this._wallet); - final Object _wallet; + CWHavenWalletDetails(this._wallet); - @computed + final Object _wallet; + + @computed @override Account get account { - final havenWallet = _wallet as HavenWallet; - final acc = havenWallet.walletAddresses.account as monero_account.Account; - return Account(id: acc.id, label: acc.label); + final havenWallet = _wallet as HavenWallet; + final acc = havenWallet.walletAddresses.account as monero_account.Account; + return Account(id: acc.id, label: acc.label); } @computed @override - HavenBalance get balance { - final havenWallet = _wallet as HavenWallet; - final balance = havenWallet.balance; - throw Exception('Unimplemented'); - //return HavenBalance( - // fullBalance: balance.fullBalance, - // unlockedBalance: balance.unlockedBalance); - } + HavenBalance get balance { + final havenWallet = _wallet as HavenWallet; + final balance = havenWallet.balance; + throw Exception('Unimplemented'); + //return HavenBalance( + // fullBalance: balance.fullBalance, + // unlockedBalance: balance.unlockedBalance); + } } class CWHaven extends Haven { @override HavenAccountList getAccountList(Object wallet) { - return CWHavenAccountList(wallet); - } - - @override - MoneroSubaddressList getSubaddressList(Object wallet) { - return CWHavenSubaddressList(wallet); - } + return CWHavenAccountList(wallet); + } @override - TransactionHistoryBase getTransactionHistory(Object wallet) { - final havenWallet = wallet as HavenWallet; - return havenWallet.transactionHistory; - } + MoneroSubaddressList getSubaddressList(Object wallet) { + return CWHavenSubaddressList(wallet); + } @override - HavenWalletDetails getMoneroWalletDetails(Object wallet) { - return CWHavenWalletDetails(wallet); - } + TransactionHistoryBase getTransactionHistory(Object wallet) { + final havenWallet = wallet as HavenWallet; + return havenWallet.transactionHistory; + } @override - int getHeigthByDate({required DateTime date}) { - return getMoneroHeigthByDate(date: date); - } - - @override - TransactionPriority getDefaultTransactionPriority() { - return MoneroTransactionPriority.automatic; - } + HavenWalletDetails getMoneroWalletDetails(Object wallet) { + return CWHavenWalletDetails(wallet); + } @override - TransactionPriority deserializeMoneroTransactionPriority({required int raw}) { - return MoneroTransactionPriority.deserialize(raw: raw); - } + int getHeightByDate({required DateTime date}) => getHavenHeightByDate(date: date); @override - List getTransactionPriorities() { - return MoneroTransactionPriority.all; - } + Future getCurrentHeight() => getHavenCurrentHeight(); @override - List 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; - } - } + TransactionPriority getDefaultTransactionPriority() { + return MoneroTransactionPriority.automatic; + } @override - WalletCredentials createHavenRestoreWalletFromKeysCredentials({ - required String name, + TransactionPriority deserializeMoneroTransactionPriority({required int raw}) { + return MoneroTransactionPriority.deserialize(raw: raw); + } + + @override + List getTransactionPriorities() { + return MoneroTransactionPriority.all; + } + + @override + List 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 viewKey, required String address, required String password, required String language, required int height}) { - return HavenRestoreWalletFromKeysCredentials( - name: name, - spendKey: spendKey, - viewKey: viewKey, - address: address, - password: password, - language: language, - 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); - } + return HavenRestoreWalletFromKeysCredentials( + name: name, + spendKey: spendKey, + viewKey: viewKey, + address: address, + password: password, + language: language, + height: height); + } @override - WalletCredentials createHavenNewWalletCredentials({ - required String name, - required String language, - String? password}) { - return HavenNewWalletCredentials( - name: name, - password: password, - language: language); - } + 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 - Map getKeys(Object wallet) { - final havenWallet = wallet as HavenWallet; - final keys = havenWallet.keys; - return { - 'privateSpendKey': keys.privateSpendKey, + WalletCredentials createHavenNewWalletCredentials( + {required String name, required String language, String? password}) { + return HavenNewWalletCredentials(name: name, password: password, language: language); + } + + @override + Map getKeys(Object wallet) { + final havenWallet = wallet as HavenWallet; + final keys = havenWallet.keys; + return { + 'privateSpendKey': keys.privateSpendKey, 'privateViewKey': keys.privateViewKey, 'publicSpendKey': keys.publicSpendKey, - 'publicViewKey': keys.publicViewKey}; - } + 'publicViewKey': keys.publicViewKey + }; + } @override - Object createHavenTransactionCreationCredentials({ - required List outputs, - required TransactionPriority priority, - required String assetType}) { - return HavenTransactionCreationCredentials( - outputs: outputs.map((out) => OutputInfo( - fiatAmount: out.fiatAmount, - cryptoAmount: out.cryptoAmount, - address: out.address, - note: out.note, - sendAll: out.sendAll, - extractedAddress: out.extractedAddress, - isParsedAddress: out.isParsedAddress, - formattedCryptoAmount: out.formattedCryptoAmount)) - .toList(), - priority: priority as MoneroTransactionPriority, - assetType: assetType); - } + Object createHavenTransactionCreationCredentials( + {required List outputs, + required TransactionPriority priority, + required String assetType}) { + return HavenTransactionCreationCredentials( + outputs: outputs + .map((out) => OutputInfo( + fiatAmount: out.fiatAmount, + cryptoAmount: out.cryptoAmount, + address: out.address, + note: out.note, + sendAll: out.sendAll, + extractedAddress: out.extractedAddress, + isParsedAddress: out.isParsedAddress, + formattedCryptoAmount: out.formattedCryptoAmount)) + .toList(), + priority: priority as MoneroTransactionPriority, + assetType: assetType); + } @override - String formatterMoneroAmountToString({required int amount}) { - return moneroAmountToString(amount: amount); - } - - @override - double formatterMoneroAmountToDouble({required int amount}) { - return moneroAmountToDouble(amount: amount); - } + String formatterMoneroAmountToString({required int amount}) { + return moneroAmountToString(amount: amount); + } @override - int formatterMoneroParseAmount({required String amount}) { - return moneroParseAmount(amount: amount); - } + double formatterMoneroAmountToDouble({required int amount}) { + return moneroAmountToDouble(amount: amount); + } @override - Account getCurrentAccount(Object wallet) { - final havenWallet = wallet as HavenWallet; - final acc = havenWallet.walletAddresses.account as monero_account.Account; - return Account(id: acc.id, label: acc.label); - } + int formatterMoneroParseAmount({required String amount}) { + return moneroParseAmount(amount: amount); + } @override - void setCurrentAccount(Object wallet, int id, String label) { - final havenWallet = wallet as HavenWallet; - havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label); - } + Account getCurrentAccount(Object wallet) { + final havenWallet = wallet as HavenWallet; + final acc = havenWallet.walletAddresses.account as monero_account.Account; + return Account(id: acc.id, label: acc.label); + } @override - void onStartup() { - monero_wallet_api.onStartup(); - } + void setCurrentAccount(Object wallet, int id, String label) { + final havenWallet = wallet as HavenWallet; + havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label); + } @override - int getTransactionInfoAccountId(TransactionInfo tx) { - final havenTransactionInfo = tx as HavenTransactionInfo; - return havenTransactionInfo.accountIndex; - } + void onStartup() { + monero_wallet_api.onStartup(); + } @override - WalletService createHavenWalletService(Box walletInfoSource) { - return HavenWalletService(walletInfoSource); - } + int getTransactionInfoAccountId(TransactionInfo tx) { + final havenTransactionInfo = tx as HavenTransactionInfo; + return havenTransactionInfo.accountIndex; + } @override - String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) { - final havenWallet = wallet as HavenWallet; - return havenWallet.getTransactionAddress(accountIndex, addressIndex); - } + WalletService createHavenWalletService(Box walletInfoSource) { + return HavenWalletService(walletInfoSource); + } @override - CryptoCurrency assetOfTransaction(TransactionInfo tx) { - final transaction = tx as HavenTransactionInfo; - final asset = CryptoCurrency.fromString(transaction.assetType); - return asset; - } + String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) { + final havenWallet = wallet as HavenWallet; + return havenWallet.getTransactionAddress(accountIndex, addressIndex); + } @override - List getAssetRate() - => getRate() - .map((rate) => AssetRate(rate.getAssetType(), rate.getRate())) - .toList(); + CryptoCurrency assetOfTransaction(TransactionInfo tx) { + final transaction = tx as HavenTransactionInfo; + final asset = CryptoCurrency.fromString(transaction.assetType); + return asset; + } + + @override + List getAssetRate() => + getRate().map((rate) => AssetRate(rate.getAssetType(), rate.getRate())).toList(); } diff --git a/lib/src/screens/wallet_keys/wallet_keys_page.dart b/lib/src/screens/wallet_keys/wallet_keys_page.dart index e81ec7d2a..e9f9ea285 100644 --- a/lib/src/screens/wallet_keys/wallet_keys_page.dart +++ b/lib/src/screens/wallet_keys/wallet_keys_page.dart @@ -1,6 +1,7 @@ import 'package:auto_size_text/auto_size_text.dart'; import 'package:cake_wallet/src/widgets/section_divider.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/cupertino.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/widgets/list_row.dart'; import 'package:cake_wallet/view_model/wallet_keys_view_model.dart'; +import 'package:cake_wallet/routes.dart'; class WalletKeysPage extends BasePage { WalletKeysPage(this.walletKeysViewModel); @@ -18,6 +20,32 @@ class WalletKeysPage extends BasePage { 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 Widget body(BuildContext context) { return Column( diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart index dcfa97701..023713bd8 100644 --- a/lib/view_model/wallet_keys_view_model.dart +++ b/lib/view_model/wallet_keys_view_model.dart @@ -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/monero/monero.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'; @@ -15,10 +16,11 @@ abstract class WalletKeysViewModelBase with Store { : title = wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin ? S.current.wallet_seed : S.current.wallet_keys, + _wallet = wallet, + _restoreHeight = wallet.walletInfo.restoreHeight, items = ObservableList() { if (wallet.type == WalletType.monero) { final keys = monero!.getKeys(wallet); - items.addAll([ if (keys['publicSpendKey'] != null) StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!), @@ -34,7 +36,6 @@ abstract class WalletKeysViewModelBase with Store { if (wallet.type == WalletType.haven) { final keys = haven!.getKeys(wallet); - items.addAll([ if (keys['publicSpendKey'] != null) StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!), @@ -58,4 +59,59 @@ abstract class WalletKeysViewModelBase with Store { final ObservableList items; final String title; + + final WalletBase _wallet; + + final int _restoreHeight; + + Future 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 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> get _queryParams async { + final restoreHeightResult = await restoreHeight; + return { + 'seed': _wallet.seed, + if (restoreHeightResult != null) ...{'height': restoreHeightResult} + }; + } + + Future get url async { + return Uri( + path: _path, + queryParameters: await _queryParams, + ); + } } diff --git a/tool/configure.dart b/tool/configure.dart index 5ae5a2111..c556f2f86 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -402,7 +402,8 @@ abstract class Haven { String getTransactionAddress(Object wallet, int accountIndex, int addressIndex); - int getHeigthByDate({required DateTime date}); + int getHeightByDate({required DateTime date}); + Future getCurrentHeight(); TransactionPriority getDefaultTransactionPriority(); TransactionPriority deserializeMoneroTransactionPriority({required int raw}); List getTransactionPriorities();