diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index 0553170cc..359f9b36d 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:convert/convert.dart'; import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:cw_bitcoin/bitcoin_amount_format.dart'; import 'package:cw_bitcoin/script_hash.dart'; @@ -263,8 +264,12 @@ class ElectrumClient { await call(method: 'blockchain.transaction.get_merkle', params: [hash, height]) as Map<String, dynamic>; - Future<Map<String, dynamic>> getHeader({required int height}) async => - await call(method: 'blockchain.block.get_header', params: [height]) as Map<String, dynamic>; + Future<DateTime> getBlockTime({required int height}) async { + final header = await call(method: 'blockchain.block.header', params: [height]) as String; + final bd = ByteData.sublistView(Uint8List.fromList(hex.decode(header))); + final timestamp = bd.getUint32(68, Endian.little) * 1000; + return DateTime.fromMillisecondsSinceEpoch(timestamp, isUtc: true); + } Future<double> estimatefee({required int p}) => call(method: 'blockchain.estimatefee', params: [p]).then((dynamic result) { diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index 1608a3dba..e71a68dee 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -1,9 +1,12 @@ import 'dart:async'; +import 'package:convert/convert.dart'; import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; +import 'package:cw_bitcoin/electrum_transaction_info.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/sync_status.dart'; +import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_bitcoin/litecoin_wallet_addresses.dart'; import 'package:cw_core/transaction_priority.dart'; @@ -11,6 +14,7 @@ import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/wallet_info.dart'; +import 'package:cw_core/wallet_type.dart'; import 'package:cw_bitcoin/electrum_wallet_snapshot.dart'; import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart'; @@ -36,7 +40,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { ElectrumBalance? initialBalance, Map<String, int>? initialRegularAddressIndex, Map<String, int>? initialChangeAddressIndex, - }) : super( + }) : mwebHd = bitcoin.HDWallet.fromSeed(seedBytes, + network: litecoinNetwork).derivePath("m/1000'"), + super( mnemonic: mnemonic, password: password, walletInfo: walletInfo, @@ -54,7 +60,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { initialChangeAddressIndex: initialChangeAddressIndex, mainHd: hd, sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath("m/0'/1"), - mwebHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath("m/1000'"), + mwebHd: mwebHd, network: network, ); autorun((_) { @@ -62,6 +68,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { }); } + final bitcoin.HDWallet mwebHd; + static Future<LitecoinWallet> create( {required String mnemonic, required String password, @@ -129,6 +137,25 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { syncStatus = SyncedSyncStatus(); } }); + final scanSecret = mwebHd.derive(0x80000000).privKey!; + final req = UtxosRequest(scanSecret: hex.decode(scanSecret)); + await for (var utxo in stub.utxos(req)) { + final status = await stub.status(StatusRequest()); + var date = DateTime.now(); + var confirmations = 0; + if (utxo.height > 0) { + date = await electrumClient.getBlockTime(height: utxo.height); + confirmations = status.blockHeaderHeight - utxo.height + 1; + } + final tx = ElectrumTransactionInfo(WalletType.litecoin, + id: utxo.outputId, height: utxo.height, + amount: utxo.value.toInt(), + direction: TransactionDirection.incoming, + isPending: utxo.height == 0, + date: date, confirmations: confirmations); + transactionHistory.addOne(tx); + await transactionHistory.save(); + } } @override