mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-22 10:45:08 +00:00
feat: single block scan, rescan by date working for btc mainnet
This commit is contained in:
parent
058ff6aeec
commit
8ea2e6ee40
33 changed files with 147 additions and 24 deletions
|
@ -201,7 +201,7 @@ abstract class ElectrumWalletBase
|
|||
}
|
||||
|
||||
@action
|
||||
Future<void> _setListeners(int height, {int? chainTip}) async {
|
||||
Future<void> _setListeners(int height, {int? chainTip, bool? doSingleScan}) async {
|
||||
final currentChainTip = chainTip ?? await electrumClient.getCurrentBlockChainTip() ?? 0;
|
||||
syncStatus = AttemptingSyncStatus();
|
||||
|
||||
|
@ -223,6 +223,7 @@ abstract class ElectrumWalletBase
|
|||
transactionHistoryIds: transactionHistory.transactions.keys.toList(),
|
||||
node: ScanNode(node!.uri, node!.useSSL),
|
||||
labels: walletAddresses.labels,
|
||||
isSingleScan: doSingleScan ?? false,
|
||||
));
|
||||
|
||||
await for (var message in receivePort) {
|
||||
|
@ -981,9 +982,10 @@ abstract class ElectrumWalletBase
|
|||
|
||||
@action
|
||||
@override
|
||||
Future<void> rescan({required int height, int? chainTip, ScanData? scanData}) async {
|
||||
Future<void> rescan(
|
||||
{required int height, int? chainTip, ScanData? scanData, bool? doSingleScan}) async {
|
||||
silentPaymentsScanningActive = true;
|
||||
_setListeners(height);
|
||||
_setListeners(height, doSingleScan: doSingleScan);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1606,6 +1608,7 @@ class ScanData {
|
|||
final ElectrumClient electrumClient;
|
||||
final List<String> transactionHistoryIds;
|
||||
final Map<String, String> labels;
|
||||
final bool isSingleScan;
|
||||
|
||||
ScanData({
|
||||
required this.sendPort,
|
||||
|
@ -1617,6 +1620,7 @@ class ScanData {
|
|||
required this.electrumClient,
|
||||
required this.transactionHistoryIds,
|
||||
required this.labels,
|
||||
required this.isSingleScan,
|
||||
});
|
||||
|
||||
factory ScanData.fromHeight(ScanData scanData, int newHeight) {
|
||||
|
@ -1630,6 +1634,7 @@ class ScanData {
|
|||
transactionHistoryIds: scanData.transactionHistoryIds,
|
||||
electrumClient: scanData.electrumClient,
|
||||
labels: scanData.labels,
|
||||
isSingleScan: scanData.isSingleScan,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1689,11 +1694,17 @@ Future<void> startRefresh(ScanData scanData) async {
|
|||
while (true) {
|
||||
lastKnownBlockHeight = syncHeight;
|
||||
|
||||
final syncingStatus =
|
||||
SyncingSyncStatus.fromHeightValues(currentChainTip, initialSyncHeight, syncHeight);
|
||||
SyncingSyncStatus syncingStatus;
|
||||
if (scanData.isSingleScan) {
|
||||
syncingStatus = SyncingSyncStatus(1, 0);
|
||||
} else {
|
||||
syncingStatus =
|
||||
SyncingSyncStatus.fromHeightValues(currentChainTip, initialSyncHeight, syncHeight);
|
||||
}
|
||||
|
||||
scanData.sendPort.send(SyncResponse(syncHeight, syncingStatus));
|
||||
|
||||
if (syncingStatus.blocksLeft <= 0) {
|
||||
if (syncingStatus.blocksLeft <= 0 || (scanData.isSingleScan && scanData.height != syncHeight)) {
|
||||
scanData.sendPort.send(SyncResponse(currentChainTip, SyncedSyncStatus()));
|
||||
return;
|
||||
}
|
||||
|
@ -1701,7 +1712,8 @@ Future<void> startRefresh(ScanData scanData) async {
|
|||
try {
|
||||
final electrumClient = await getElectrumConnection();
|
||||
|
||||
final scanningBlockCount = scanData.network == BitcoinNetwork.testnet ? 50 : 10;
|
||||
final scanningBlockCount =
|
||||
scanData.isSingleScan ? 1 : (scanData.network == BitcoinNetwork.testnet ? 1 : 10);
|
||||
|
||||
Map<String, dynamic>? tweaks;
|
||||
try {
|
||||
|
@ -1743,8 +1755,7 @@ Future<void> startRefresh(ScanData scanData) async {
|
|||
scanData.silentAddress.b_scan,
|
||||
scanData.silentAddress.B_spend,
|
||||
outputPubkeys.values
|
||||
.map((o) => getScriptFromOutput(
|
||||
o["pubkey"].toString(), int.parse(o["amount"].toString())))
|
||||
.map((o) => getScriptFromOutput(o[0].toString(), int.parse(o[1].toString())))
|
||||
.toList(),
|
||||
precomputedLabels: scanData.labels,
|
||||
);
|
||||
|
@ -1770,9 +1781,9 @@ Future<void> startRefresh(ScanData scanData) async {
|
|||
int? amount;
|
||||
int? pos;
|
||||
outputPubkeys.entries.firstWhere((k) {
|
||||
final matches = k.value["pubkey"] == key;
|
||||
final matches = k.value[0] == key;
|
||||
if (matches) {
|
||||
amount = int.parse(k.value["amount"].toString());
|
||||
amount = int.parse(k.value[1].toString());
|
||||
pos = int.parse(k.key.toString());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -242,3 +242,32 @@ Future<int> getHavenCurrentHeight() async {
|
|||
throw Exception('Failed to load current blockchain height');
|
||||
}
|
||||
}
|
||||
|
||||
// Data taken from https://timechaincalendar.com/
|
||||
const bitcoinDates = {
|
||||
"2024-04": 837182,
|
||||
"2024-03": 832623,
|
||||
"2024-02": 828319,
|
||||
"2024-01": 823807,
|
||||
"2023-12": 819206,
|
||||
"2023-11": 814765,
|
||||
"2023-10": 810098,
|
||||
"2023-09": 805675,
|
||||
"2023-08": 801140,
|
||||
"2023-07": 796640,
|
||||
"2023-06": 792330,
|
||||
"2023-05": 787733,
|
||||
"2023-04": 783403,
|
||||
"2023-03": 778740,
|
||||
"2023-02": 774525,
|
||||
"2023-01": 769810,
|
||||
};
|
||||
|
||||
int getBitcoinHeightByDate({required DateTime date}) {
|
||||
String closestKey =
|
||||
bitcoinDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
|
||||
|
||||
final oldestHeight = bitcoinDates.values.last;
|
||||
|
||||
return bitcoinDates[closestKey] ?? oldestHeight;
|
||||
}
|
||||
|
|
|
@ -335,4 +335,12 @@ class CWBitcoin extends Bitcoin {
|
|||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
return bitcoinWallet.isTestnet ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
int getHeightByDate({required DateTime date}) => getBitcoinHeightByDate(date: date);
|
||||
|
||||
void rescan(Object wallet, {required int height, bool? doSingleScan}) {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
bitcoinWallet.rescan(height: height, doSingleScan: doSingleScan);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,15 @@ class RescanPage extends BasePage {
|
|||
return Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
BlockchainHeightWidget(
|
||||
key: _blockchainHeightWidgetKey,
|
||||
onHeightOrDateEntered: (value) => _rescanViewModel.isButtonEnabled = value,
|
||||
isSilentPaymentsScan: _rescanViewModel.isSilentPaymentsScan,
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => BlockchainHeightWidget(
|
||||
key: _blockchainHeightWidgetKey,
|
||||
onHeightOrDateEntered: (value) => _rescanViewModel.isButtonEnabled = value,
|
||||
isSilentPaymentsScan: _rescanViewModel.isSilentPaymentsScan,
|
||||
doSingleScan: _rescanViewModel.doSingleScan,
|
||||
toggleSingleScan: () =>
|
||||
_rescanViewModel.doSingleScan = !_rescanViewModel.doSingleScan,
|
||||
)),
|
||||
Observer(
|
||||
builder: (_) => LoadingPrimaryButton(
|
||||
isLoading: _rescanViewModel.state == RescanWalletState.rescaning,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_switch.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/utils/date_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -14,6 +16,8 @@ class BlockchainHeightWidget extends StatefulWidget {
|
|||
this.onHeightOrDateEntered,
|
||||
this.hasDatePicker = true,
|
||||
this.isSilentPaymentsScan = false,
|
||||
this.toggleSingleScan,
|
||||
this.doSingleScan = false,
|
||||
}) : super(key: key);
|
||||
|
||||
final Function(int)? onHeightChange;
|
||||
|
@ -21,6 +25,8 @@ class BlockchainHeightWidget extends StatefulWidget {
|
|||
final FocusNode? focusNode;
|
||||
final bool hasDatePicker;
|
||||
final bool isSilentPaymentsScan;
|
||||
final bool doSingleScan;
|
||||
final Function()? toggleSingleScan;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => BlockchainHeightState();
|
||||
|
@ -101,6 +107,30 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
|
|||
))
|
||||
],
|
||||
),
|
||||
if (widget.isSilentPaymentsScan)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).scan_one_block,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: StandardSwitch(
|
||||
value: widget.doSingleScan,
|
||||
onTaped: () => widget.toggleSingleScan?.call(),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 40, right: 40, top: 24),
|
||||
child: Text(
|
||||
|
@ -126,7 +156,12 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
|
|||
lastDate: now);
|
||||
|
||||
if (date != null) {
|
||||
final height = monero!.getHeightByDate(date: date);
|
||||
int height;
|
||||
if (widget.isSilentPaymentsScan) {
|
||||
height = bitcoin!.getHeightByDate(date: date);
|
||||
} else {
|
||||
height = monero!.getHeightByDate(date: date);
|
||||
}
|
||||
setState(() {
|
||||
dateController.text = DateFormat('yyyy-MM-dd').format(date);
|
||||
restoreHeightController.text = '$height';
|
||||
|
|
|
@ -12,7 +12,8 @@ enum RescanWalletState { rescaning, none }
|
|||
abstract class RescanViewModelBase with Store {
|
||||
RescanViewModelBase(this._wallet)
|
||||
: state = RescanWalletState.none,
|
||||
isButtonEnabled = false;
|
||||
isButtonEnabled = false,
|
||||
doSingleScan = false;
|
||||
|
||||
final WalletBase _wallet;
|
||||
|
||||
|
@ -22,14 +23,21 @@ abstract class RescanViewModelBase with Store {
|
|||
@observable
|
||||
bool isButtonEnabled;
|
||||
|
||||
@observable
|
||||
bool doSingleScan;
|
||||
|
||||
@computed
|
||||
bool get isSilentPaymentsScan => bitcoin!.hasSelectedSilentPayments(_wallet);
|
||||
bool get isSilentPaymentsScan => _wallet.type == WalletType.bitcoin;
|
||||
|
||||
@action
|
||||
Future<void> rescanCurrentWallet({required int restoreHeight}) async {
|
||||
state = RescanWalletState.rescaning;
|
||||
_wallet.rescan(height: restoreHeight);
|
||||
if (_wallet.type != WalletType.bitcoin) _wallet.transactionHistory.clear();
|
||||
if (_wallet.type != WalletType.bitcoin) {
|
||||
_wallet.rescan(height: restoreHeight);
|
||||
_wallet.transactionHistory.clear();
|
||||
} else {
|
||||
bitcoin!.rescan(_wallet, height: restoreHeight, doSingleScan: doSingleScan);
|
||||
}
|
||||
state = RescanWalletState.none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "حفظ كلمة المرور الاحتياطية",
|
||||
"save_to_downloads": "ﺕﻼﻳﺰﻨﺘﻟﺍ ﻲﻓ ﻆﻔﺣ",
|
||||
"saved_the_trade_id": "لقد تم حفظ معرف العملية",
|
||||
"scan_one_block": "مسح كتلة واحدة",
|
||||
"scan_qr_code": "امسح رمز QR ضوئيًا",
|
||||
"scan_qr_code_to_get_address": "امسح ال QR للحصول على العنوان",
|
||||
"scan_qr_on_device": " ﺮﺧﺁ ﺯﺎﻬﺟ ﻰﻠﻋ ﺎﻴًﺋﻮﺿ ﺍﺬﻫ ﺔﻌﻳﺮﺴﻟﺍ ﺔﺑﺎﺠﺘﺳﻻﺍ ﺰﻣﺭ ﺢﺴﻤﺑ ﻢﻗ",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Запазване на паролата за възстановяване",
|
||||
"save_to_downloads": "Запазване в Изтегляния",
|
||||
"saved_the_trade_id": "Запазих trade ID-то",
|
||||
"scan_one_block": "Сканирайте един блок",
|
||||
"scan_qr_code": "Сканирайте QR кода, за да получите адреса",
|
||||
"scan_qr_code_to_get_address": "Сканирайте QR кода, за да получите адреса",
|
||||
"scan_qr_on_device": "Сканирайте този QR код на друго устройство",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Uložit heslo pro zálohy",
|
||||
"save_to_downloads": "Uložit do Stažených souborů",
|
||||
"saved_the_trade_id": "Uložil jsem si ID transakce (trade ID)",
|
||||
"scan_one_block": "Prohledejte jeden blok",
|
||||
"scan_qr_code": "Naskenujte QR kód pro získání adresy",
|
||||
"scan_qr_code_to_get_address": "Prohledejte QR kód a získejte adresu",
|
||||
"scan_qr_on_device": "Naskenujte tento QR kód na jiném zařízení",
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
"save_backup_password_alert": "Sicherungskennwort speichern",
|
||||
"save_to_downloads": "Unter „Downloads“ speichern",
|
||||
"saved_the_trade_id": "Ich habe die Handels-ID gespeichert",
|
||||
"scan_one_block": "Einen Block scannen",
|
||||
"scan_qr_code": "QR-Code scannen",
|
||||
"scan_qr_code_to_get_address": "Scannen Sie den QR-Code, um die Adresse zu erhalten",
|
||||
"scan_qr_on_device": "Scannen Sie diesen QR-Code auf einem anderen Gerät",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Save backup password",
|
||||
"save_to_downloads": "Save to Downloads",
|
||||
"saved_the_trade_id": "I've saved the trade ID",
|
||||
"scan_one_block": "Scan one block",
|
||||
"scan_qr_code": "Scan QR code",
|
||||
"scan_qr_code_to_get_address": "Scan the QR code to get the address",
|
||||
"scan_qr_on_device": "Scan this QR code on another device",
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
"save_backup_password_alert": "Guardar contraseña de respaldo",
|
||||
"save_to_downloads": "Guardar en Descargas",
|
||||
"saved_the_trade_id": "He salvado comercial ID",
|
||||
"scan_one_block": "Escanear un bloque",
|
||||
"scan_qr_code": "Escanear código QR",
|
||||
"scan_qr_code_to_get_address": "Escanee el código QR para obtener la dirección",
|
||||
"scan_qr_on_device": "Escanea este código QR en otro dispositivo",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Enregistrer le mot de passe de sauvegarde",
|
||||
"save_to_downloads": "Enregistrer dans les téléchargements",
|
||||
"saved_the_trade_id": "J'ai sauvegardé l'ID d'échange",
|
||||
"scan_one_block": "Scanner un bloc",
|
||||
"scan_qr_code": "Scannez le QR code",
|
||||
"scan_qr_code_to_get_address": "Scannez le QR code pour obtenir l'adresse",
|
||||
"scan_qr_on_device": "Scannez ce code QR sur un autre appareil",
|
||||
|
|
|
@ -513,6 +513,7 @@
|
|||
"save_backup_password_alert": "Ajiye kalmar sirri ta ajiya",
|
||||
"save_to_downloads": "Ajiye zuwa Zazzagewa",
|
||||
"saved_the_trade_id": "Na ajiye ID na ciniki",
|
||||
"scan_one_block": "Duba toshe daya",
|
||||
"scan_qr_code": "Gani QR kodin",
|
||||
"scan_qr_code_to_get_address": "Duba lambar QR don samun adireshin",
|
||||
"scan_qr_on_device": "Duba wannan lambar QR akan wata na'ura",
|
||||
|
|
|
@ -513,6 +513,7 @@
|
|||
"save_backup_password_alert": "बैकअप पासवर्ड सेव करें",
|
||||
"save_to_downloads": "डाउनलोड में सहेजें",
|
||||
"saved_the_trade_id": "मैंने व्यापार बचा लिया है ID",
|
||||
"scan_one_block": "एक ब्लॉक को स्कैन करना",
|
||||
"scan_qr_code": "स्कैन क्यू आर कोड",
|
||||
"scan_qr_code_to_get_address": "पता प्राप्त करने के लिए QR कोड स्कैन करें",
|
||||
"scan_qr_on_device": "इस QR कोड को किसी अन्य डिवाइस पर स्कैन करें",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Spremi lozinku za sigurnosnu kopiju",
|
||||
"save_to_downloads": "Spremi u Preuzimanja",
|
||||
"saved_the_trade_id": "Spremio/la sam transakcijski ID",
|
||||
"scan_one_block": "Skenirajte jedan blok",
|
||||
"scan_qr_code": "Skenirajte QR kod",
|
||||
"scan_qr_code_to_get_address": "Skeniraj QR kod za dobivanje adrese",
|
||||
"scan_qr_on_device": "Skenirajte ovaj QR kod na drugom uređaju",
|
||||
|
|
|
@ -514,6 +514,7 @@
|
|||
"save_backup_password_alert": "Simpan kata sandi cadangan",
|
||||
"save_to_downloads": "Simpan ke Unduhan",
|
||||
"saved_the_trade_id": "Saya telah menyimpan ID perdagangan",
|
||||
"scan_one_block": "Pindai satu blok",
|
||||
"scan_qr_code": "Scan kode QR untuk mendapatkan alamat",
|
||||
"scan_qr_code_to_get_address": "Pindai kode QR untuk mendapatkan alamat",
|
||||
"scan_qr_on_device": "Pindai kode QR ini di perangkat lain",
|
||||
|
|
|
@ -513,6 +513,7 @@
|
|||
"save_backup_password_alert": "Salva password Backup",
|
||||
"save_to_downloads": "Salva in Download",
|
||||
"saved_the_trade_id": "Ho salvato l'ID dello scambio",
|
||||
"scan_one_block": "Scansionare un blocco",
|
||||
"scan_qr_code": "Scansiona il codice QR",
|
||||
"scan_qr_code_to_get_address": "Scansiona il codice QR per ottenere l'indirizzo",
|
||||
"scan_qr_on_device": "Scansiona questo codice QR su un altro dispositivo",
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
"save_backup_password_alert": "バックアップパスワードを保存する",
|
||||
"save_to_downloads": "ダウンロードに保存",
|
||||
"saved_the_trade_id": "取引IDを保存しました",
|
||||
"scan_one_block": "1つのブロックをスキャンします",
|
||||
"scan_qr_code": "QRコードをスキャン",
|
||||
"scan_qr_code_to_get_address": "QRコードをスキャンして住所を取得します",
|
||||
"scan_qr_on_device": "別のデバイスでこの QR コードをスキャンします",
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
"save_backup_password_alert": "백업 비밀번호 저장",
|
||||
"save_to_downloads": "다운로드에 저장",
|
||||
"saved_the_trade_id": "거래 ID를 저장했습니다",
|
||||
"scan_one_block": "하나의 블록을 스캔하십시오",
|
||||
"scan_qr_code": "QR 코드 스캔",
|
||||
"scan_qr_code_to_get_address": "QR 코드를 스캔하여 주소를 얻습니다.",
|
||||
"scan_qr_on_device": "다른 기기에서 이 QR 코드를 스캔하세요.",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "အရန်စကားဝှက်ကို သိမ်းဆည်းပါ။",
|
||||
"save_to_downloads": "ဒေါင်းလုဒ်များထံ သိမ်းဆည်းပါ။",
|
||||
"saved_the_trade_id": "ကုန်သွယ်မှု ID ကို သိမ်းဆည်းပြီးပါပြီ။",
|
||||
"scan_one_block": "တစ်ကွက်ကိုစကင်ဖတ်စစ်ဆေးပါ",
|
||||
"scan_qr_code": "QR ကုဒ်ကို စကင်န်ဖတ်ပါ။",
|
||||
"scan_qr_code_to_get_address": "လိပ်စာရယူရန် QR ကုဒ်ကို စကင်န်ဖတ်ပါ။",
|
||||
"scan_qr_on_device": "အခြားစက်တွင် ဤ QR ကုဒ်ကို စကင်ဖတ်ပါ။",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Bewaar back-upwachtwoord",
|
||||
"save_to_downloads": "Opslaan in downloads",
|
||||
"saved_the_trade_id": "Ik heb de ruil-ID opgeslagen",
|
||||
"scan_one_block": "Scan een blok",
|
||||
"scan_qr_code": "Scan QR-code",
|
||||
"scan_qr_code_to_get_address": "Scan de QR-code om het adres te krijgen",
|
||||
"scan_qr_on_device": "Scan deze QR-code op een ander apparaat",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Zapisz hasło kopii zapasowej",
|
||||
"save_to_downloads": "Zapisz w Pobranych",
|
||||
"saved_the_trade_id": "Zapisałem ID",
|
||||
"scan_one_block": "Zeskanuj jeden blok",
|
||||
"scan_qr_code": "Skanowania QR code",
|
||||
"scan_qr_code_to_get_address": "Zeskanuj kod QR, aby uzyskać adres",
|
||||
"scan_qr_on_device": "Zeskanuj ten kod QR na innym urządzeniu",
|
||||
|
|
|
@ -513,6 +513,7 @@
|
|||
"save_backup_password_alert": "Salvar senha de backup",
|
||||
"save_to_downloads": "Salvar em Downloads",
|
||||
"saved_the_trade_id": "ID da troca salvo",
|
||||
"scan_one_block": "Escanear um bloco",
|
||||
"scan_qr_code": "Escanear código QR",
|
||||
"scan_qr_code_to_get_address": "Digitalize o código QR para obter o endereço",
|
||||
"scan_qr_on_device": "Digitalize este código QR em outro dispositivo",
|
||||
|
@ -624,7 +625,7 @@
|
|||
"silent_payments": "Pagamentos silenciosos",
|
||||
"silent_payments_disclaimer": "Novos endereços não são novas identidades. É uma reutilização de uma identidade existente com um rótulo diferente.",
|
||||
"silent_payments_scan_from_date": "Escanear a partir da data",
|
||||
"silent_payments_scan_from_date_or_blockheight": "Por favor, insira a altura do bloco que deseja iniciar o escaneamento para obter pagamentos silenciosos ou use a data. Você pode escolher se a carteira continua digitalizando cada bloco ou verifica apenas a altura especificada.",
|
||||
"silent_payments_scan_from_date_or_blockheight": "Por favor, insira a altura do bloco que deseja iniciar o escaneamento para obter pagamentos silenciosos ou use a data. Você pode escolher se a carteira continua escaneando cada bloco ou verifica apenas a altura especificada.",
|
||||
"silent_payments_scan_from_height": "Escanear a partir da altura do bloco",
|
||||
"silent_payments_scanning": "Escanear Pagamentos Silenciosos",
|
||||
"slidable": "Deslizável",
|
||||
|
@ -823,4 +824,4 @@
|
|||
"you_will_get": "Converter para",
|
||||
"you_will_send": "Converter de",
|
||||
"yy": "aa"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
"save_backup_password_alert": "Сохранить пароль резервной копии",
|
||||
"save_to_downloads": "Сохранить в загрузках",
|
||||
"saved_the_trade_id": "Я сохранил ID сделки",
|
||||
"scan_one_block": "Сканируйте один блок",
|
||||
"scan_qr_code": "Сканировать QR-код",
|
||||
"scan_qr_code_to_get_address": "Отсканируйте QR-код для получения адреса",
|
||||
"scan_qr_on_device": "Отсканируйте этот QR-код на другом устройстве",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "บันทึกรหัสผ่านสำรอง",
|
||||
"save_to_downloads": "บันทึกลงดาวน์โหลด",
|
||||
"saved_the_trade_id": "ฉันได้บันทึก ID ของการซื้อขายแล้ว",
|
||||
"scan_one_block": "สแกนหนึ่งบล็อก",
|
||||
"scan_qr_code": "สแกนรหัส QR",
|
||||
"scan_qr_code_to_get_address": "สแกน QR code เพื่อรับที่อยู่",
|
||||
"scan_qr_on_device": "สแกนโค้ด QR นี้บนอุปกรณ์อื่น",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "I -save ang backup password",
|
||||
"save_to_downloads": "I -save sa mga pag -download",
|
||||
"saved_the_trade_id": "Nai -save ko ang trade ID",
|
||||
"scan_one_block": "I -scan ang isang bloke",
|
||||
"scan_qr_code": "I -scan ang QR Code",
|
||||
"scan_qr_code_to_get_address": "I -scan ang QR code upang makuha ang address",
|
||||
"scan_qr_on_device": "I-scan ang QR code na ito sa ibang device",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "Yedek parolasını kaydet",
|
||||
"save_to_downloads": "İndirilenlere Kaydet",
|
||||
"saved_the_trade_id": "Takas ID'imi kaydettim",
|
||||
"scan_one_block": "Bir bloğu tara",
|
||||
"scan_qr_code": "QR kodunu tarayın",
|
||||
"scan_qr_code_to_get_address": "Adresi getirmek için QR kodunu tara",
|
||||
"scan_qr_on_device": "Bu QR kodunu başka bir cihazda tarayın",
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
"save_backup_password_alert": "Зберегти пароль резервної копії",
|
||||
"save_to_downloads": "Зберегти до завантажень",
|
||||
"saved_the_trade_id": "Я зберіг ID операції",
|
||||
"scan_one_block": "Сканувати один блок",
|
||||
"scan_qr_code": "Відскануйте QR-код",
|
||||
"scan_qr_code_to_get_address": "Скануйте QR-код для одержання адреси",
|
||||
"scan_qr_on_device": "Відскануйте цей QR-код на іншому пристрої",
|
||||
|
|
|
@ -513,6 +513,7 @@
|
|||
"save_backup_password_alert": "بیک اپ پاس ورڈ محفوظ کریں۔",
|
||||
"save_to_downloads": "۔ﮟﯾﺮﮐ ﻅﻮﻔﺤﻣ ﮟﯿﻣ ﺯﮈﻮﻟ ﻥﺅﺍﮈ",
|
||||
"saved_the_trade_id": "میں نے تجارتی ID محفوظ کر لی ہے۔",
|
||||
"scan_one_block": "ایک بلاک اسکین کریں",
|
||||
"scan_qr_code": "پتہ حاصل کرنے کے لیے QR کوڈ اسکین کریں۔",
|
||||
"scan_qr_code_to_get_address": "پتہ حاصل کرنے کے لئے QR کوڈ کو اسکین کریں",
|
||||
"scan_qr_on_device": " ۔ﮟﯾﺮﮐ ﻦﯿﮑﺳﺍ ﺮﭘ ﺲﺋﺍﻮﯾﮈ ﺭﻭﺍ ﯽﺴﮐ ﻮﮐ ﮈﻮﮐ QR ﺱﺍ",
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
"save_backup_password_alert": "Pamọ́ ọ̀rọ̀ aṣínà ti ẹ̀dà",
|
||||
"save_to_downloads": "Fipamọ si Awọn igbasilẹ",
|
||||
"saved_the_trade_id": "Mo ti pamọ́ àmì ìdánimọ̀ pàṣípààrọ̀",
|
||||
"scan_one_block": "Ọlọjẹ ọkan bulọki",
|
||||
"scan_qr_code": "Yan QR koodu",
|
||||
"scan_qr_code_to_get_address": "Ṣayẹwo koodu QR naa lati gba adirẹsi naa",
|
||||
"scan_qr_on_device": "Ṣe ayẹwo koodu QR yii lori ẹrọ miiran",
|
||||
|
|
|
@ -511,6 +511,7 @@
|
|||
"save_backup_password_alert": "保存备份密码",
|
||||
"save_to_downloads": "保存到下载",
|
||||
"saved_the_trade_id": "我已经保存了交易编号",
|
||||
"scan_one_block": "扫描一个街区",
|
||||
"scan_qr_code": "扫描二维码",
|
||||
"scan_qr_code_to_get_address": "扫描二维码获取地址",
|
||||
"scan_qr_on_device": "在另一台设备上扫描此二维码",
|
||||
|
|
|
@ -87,7 +87,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
|||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
|
||||
import 'package:cw_bitcoin/litecoin_wallet_service.dart';
|
||||
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
|
||||
import 'package:cw_core/get_height_by_date.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
""";
|
||||
const bitcoinCwPart = "part 'cw_bitcoin.dart';";
|
||||
|
@ -167,6 +167,8 @@ abstract class Bitcoin {
|
|||
Future<bool> isChangeSufficientForFee(Object wallet, String txId, String newFee);
|
||||
int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size});
|
||||
int getFeeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size});
|
||||
int getHeightByDate({required DateTime date});
|
||||
void rescan(Object wallet, {required int height, bool? doSingleScan});
|
||||
}
|
||||
""";
|
||||
|
||||
|
|
Loading…
Reference in a new issue