mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-19 01:04:43 +00:00
Merge branch 'mweb' of https://github.com/cake-tech/cake_wallet into mweb-bg-sync-2
This commit is contained in:
commit
5be1284d58
11 changed files with 78 additions and 64 deletions
|
@ -223,8 +223,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
if (walletInfo.type == WalletType.bitcoinCash) {
|
||||
await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
|
||||
} else if (walletInfo.type == WalletType.litecoin) {
|
||||
await _generateInitialAddresses();
|
||||
await _generateInitialAddresses(type: SegwitAddresType.mweb);
|
||||
// await _generateInitialAddresses();
|
||||
// await _generateInitialAddresses(type: SegwitAddresType.mweb);
|
||||
} else if (walletInfo.type == WalletType.bitcoin) {
|
||||
await _generateInitialAddresses();
|
||||
await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
|
||||
|
@ -232,6 +232,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
await _generateInitialAddresses(type: SegwitAddresType.p2tr);
|
||||
await _generateInitialAddresses(type: SegwitAddresType.p2wsh);
|
||||
}
|
||||
|
||||
updateAddressesByMatch();
|
||||
updateReceiveAddresses();
|
||||
updateChangeAddresses();
|
||||
|
@ -335,6 +336,13 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
}) =>
|
||||
'';
|
||||
|
||||
Future<String> getAddressAsync({
|
||||
required int index,
|
||||
required Bip32Slip10Secp256k1 hd,
|
||||
BitcoinAddressType? addressType,
|
||||
}) async =>
|
||||
getAddress(index: index, hd: hd, addressType: addressType);
|
||||
|
||||
void addBitcoinAddressTypes() {
|
||||
final lastP2wpkh = _addresses
|
||||
.where((addressRecord) =>
|
||||
|
@ -569,7 +577,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
|
||||
for (var i = startIndex; i < count + startIndex; i++) {
|
||||
final address = BitcoinAddressRecord(
|
||||
getAddress(index: i, hd: _getHd(isHidden), addressType: type ?? addressPageType),
|
||||
await getAddressAsync(index: i, hd: _getHd(isHidden), addressType: type ?? addressPageType),
|
||||
index: i,
|
||||
isHidden: isHidden,
|
||||
type: type ?? addressPageType,
|
||||
|
@ -600,14 +608,14 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
}
|
||||
|
||||
void _validateAddresses() {
|
||||
_addresses.forEach((element) {
|
||||
_addresses.forEach((element) async {
|
||||
if (!element.isHidden &&
|
||||
element.address !=
|
||||
getAddress(index: element.index, hd: mainHd, addressType: element.type)) {
|
||||
await getAddressAsync(index: element.index, hd: mainHd, addressType: element.type)) {
|
||||
element.isHidden = true;
|
||||
} else if (element.isHidden &&
|
||||
element.address !=
|
||||
getAddress(index: element.index, hd: sideHd, addressType: element.type)) {
|
||||
await getAddressAsync(index: element.index, hd: sideHd, addressType: element.type)) {
|
||||
element.isHidden = false;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:bech32/bech32.dart';
|
||||
|
@ -8,6 +9,7 @@ import 'package:cw_bitcoin/utils.dart';
|
|||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_mweb/cw_mweb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'litecoin_wallet_addresses.g.dart';
|
||||
|
@ -30,31 +32,46 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
|||
super.initialRegularAddressIndex,
|
||||
super.initialChangeAddressIndex,
|
||||
}) : super(walletInfo) {
|
||||
topUpMweb(0);
|
||||
// start generating mweb addresses in the background:
|
||||
initMwebAddresses();
|
||||
}
|
||||
|
||||
final Bip32Slip10Secp256k1 mwebHd;
|
||||
bool mwebEnabled;
|
||||
int mwebTopUpIndex = 1000;
|
||||
List<String> mwebAddrs = [];
|
||||
static Timer? mwebTopUpTimer;
|
||||
|
||||
List<int> get scanSecret => mwebHd.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw;
|
||||
List<int> get spendPubkey =>
|
||||
mwebHd.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed;
|
||||
|
||||
List<String> mwebAddrs = [];
|
||||
|
||||
Future<void> topUpMweb(int index) async {
|
||||
// generate up to index + 1000 addresses:
|
||||
while (mwebAddrs.length - index < 1000) {
|
||||
final length = mwebAddrs.length;
|
||||
final address = await CwMweb.address(
|
||||
Uint8List.fromList(scanSecret),
|
||||
Uint8List.fromList(spendPubkey),
|
||||
length,
|
||||
);
|
||||
Future<void> ensureMwebAddressUpToIndexExists(int index) async {
|
||||
Uint8List scan = Uint8List.fromList(scanSecret);
|
||||
Uint8List spend = Uint8List.fromList(spendPubkey);
|
||||
while (mwebAddrs.length <= (index + 1)) {
|
||||
final address = await CwMweb.address(scan, spend, mwebAddrs.length);
|
||||
mwebAddrs.add(address!);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> generateNumAddresses(int num) async {
|
||||
Uint8List scan = Uint8List.fromList(scanSecret);
|
||||
Uint8List spend = Uint8List.fromList(spendPubkey);
|
||||
for (int i = 0; i < num; i++) {
|
||||
final address = await CwMweb.address(scan, spend, mwebAddrs.length);
|
||||
mwebAddrs.add(address!);
|
||||
await Future.delayed(Duration.zero);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> initMwebAddresses() async {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
await generateNumAddresses(250);
|
||||
await Future.delayed(const Duration(milliseconds: 1500));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String getAddress({
|
||||
required int index,
|
||||
|
@ -62,13 +79,23 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
|||
BitcoinAddressType? addressType,
|
||||
}) {
|
||||
if (addressType == SegwitAddresType.mweb) {
|
||||
topUpMweb(index).then((value) {
|
||||
return hd == sideHd ? mwebAddrs[0] : mwebAddrs[index + 1];
|
||||
});
|
||||
return hd == sideHd ? mwebAddrs[0] : mwebAddrs[index + 1];
|
||||
}
|
||||
return generateP2WPKHAddress(hd: hd, index: index, network: network);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getAddressAsync({
|
||||
required int index,
|
||||
required Bip32Slip10Secp256k1 hd,
|
||||
BitcoinAddressType? addressType,
|
||||
}) async {
|
||||
if (addressType == SegwitAddresType.mweb) {
|
||||
await ensureMwebAddressUpToIndexExists(index);
|
||||
}
|
||||
return getAddress(index: index, hd: hd, addressType: addressType);
|
||||
}
|
||||
|
||||
@action
|
||||
@override
|
||||
Future<String> getChangeAddress({List<BitcoinOutput>? outputs, UtxoDetails? utxoDetails}) async {
|
||||
|
@ -99,7 +126,6 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
|||
}
|
||||
|
||||
if (mwebEnabled) {
|
||||
await topUpMweb(0);
|
||||
return mwebAddrs[0];
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ class LitecoinWalletService extends WalletService<
|
|||
BitcoinRestoreWalletFromSeedCredentials,
|
||||
BitcoinRestoreWalletFromWIFCredentials,
|
||||
BitcoinNewWalletCredentials> {
|
||||
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect, this.alwaysScan);
|
||||
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan, this.isDirect);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
||||
final bool isDirect;
|
||||
final bool alwaysScan;
|
||||
final bool isDirect;
|
||||
|
||||
@override
|
||||
WalletType getType() => WalletType.litecoin;
|
||||
|
|
|
@ -267,11 +267,6 @@ const bitcoinDates = {
|
|||
"2023-01": 769810,
|
||||
};
|
||||
|
||||
|
||||
const Map<String, int> litecoinDates = {
|
||||
// TODO: add litecoin dates
|
||||
};
|
||||
|
||||
int getBitcoinHeightByDate({required DateTime date}) {
|
||||
String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}';
|
||||
final closestKey = bitcoinDates.keys
|
||||
|
@ -305,19 +300,9 @@ DateTime getDateByBitcoinHeight(int height) {
|
|||
return estimatedDate;
|
||||
}
|
||||
|
||||
int getLitecoinHeightByDate({required DateTime date}) {
|
||||
String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}';
|
||||
final closestKey = litecoinDates.keys
|
||||
.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => litecoinDates.keys.last);
|
||||
final beginningBlock = litecoinDates[dateKey] ?? litecoinDates[closestKey]!;
|
||||
|
||||
final startOfMonth = DateTime(date.year, date.month);
|
||||
final daysDifference = date.difference(startOfMonth).inDays;
|
||||
|
||||
// approximately 6 blocks per hour, 24 hours per day
|
||||
int estimatedBlocksSinceStartOfMonth = (daysDifference * 24 * 6);
|
||||
|
||||
return beginningBlock + estimatedBlocksSinceStartOfMonth;
|
||||
int getLtcHeightByDate({required DateTime date}) {
|
||||
// TODO: use the proxy layer to get the height with a binary search of blocked header heights
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: enhance all of this global const lists
|
||||
|
@ -397,4 +382,3 @@ int getWowneroHeightByDate({required DateTime date}) {
|
|||
|
||||
return wowDates[closestKey] ?? 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,11 +55,6 @@ class CwMweb {
|
|||
}
|
||||
|
||||
static Future<String?> address(Uint8List scanSecret, Uint8List spendPub, int index) async {
|
||||
// try {
|
||||
// return (await CwMwebPlatform.instance.address(scan, spendPub, index))!;
|
||||
// } catch (e) {
|
||||
// print("error generating address!: $e");
|
||||
// }
|
||||
return CwMwebPlatform.instance.address(scanSecret, spendPub, index);
|
||||
}
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ class CWBitcoin extends Bitcoin {
|
|||
|
||||
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource,
|
||||
Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect) {
|
||||
return LitecoinWalletService(walletInfoSource, unspentCoinSource, isDirect, alwaysScan);
|
||||
return LitecoinWalletService(walletInfoSource, unspentCoinSource, alwaysScan, isDirect);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -530,7 +530,7 @@ class CWBitcoin extends Bitcoin {
|
|||
int getHeightByDate({required DateTime date}) => getBitcoinHeightByDate(date: date);
|
||||
|
||||
@override
|
||||
int getLitecoinHeightByDate({required DateTime date}) => getLitecoinHeightByDate(date: date);
|
||||
int getLitecoinHeightByDate({required DateTime date}) => getLtcHeightByDate(date: date);
|
||||
|
||||
@override
|
||||
Future<void> rescan(Object wallet, {required int height, bool? doSingleScan}) async {
|
||||
|
|
|
@ -85,7 +85,8 @@ class WalletLoadingService {
|
|||
authenticatedErrorStreamController.add(corruptedWalletsSeeds);
|
||||
|
||||
return wallet;
|
||||
} catch (_) {
|
||||
} catch (e) {
|
||||
print(e);
|
||||
// save seeds and show corrupted wallets' seeds to the user
|
||||
try {
|
||||
final seeds = await _getCorruptedWalletSeeds(walletInfo.name, walletInfo.type);
|
||||
|
|
|
@ -1000,8 +1000,8 @@ Future<void> setup({
|
|||
return bitcoin!.createLitecoinWalletService(
|
||||
_walletInfoSource,
|
||||
_unspentCoinsInfoSource,
|
||||
SettingsStoreBase.walletPasswordDirectInput,
|
||||
getIt.get<SettingsStore>().mwebAlwaysScan,
|
||||
SettingsStoreBase.walletPasswordDirectInput,
|
||||
);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumWalletService(
|
||||
|
|
|
@ -35,7 +35,7 @@ class RescanPage extends BasePage {
|
|||
isSilentPaymentsScan: _rescanViewModel.isSilentPaymentsScan,
|
||||
isMwebScan: _rescanViewModel.isMwebScan,
|
||||
doSingleScan: _rescanViewModel.doSingleScan,
|
||||
hasDatePicker: !_rescanViewModel.isMwebScan,
|
||||
hasDatePicker: !_rescanViewModel.isMwebScan,// disable date picker for mweb for now
|
||||
toggleSingleScan: () =>
|
||||
_rescanViewModel.doSingleScan = !_rescanViewModel.doSingleScan,
|
||||
walletType: _rescanViewModel.wallet.type,
|
||||
|
|
|
@ -103,10 +103,10 @@ class UnspentCoinsListItem extends StatelessWidget {
|
|||
),
|
||||
maxLines: 1,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
if (isChange)
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
// children: [
|
||||
if (isChange || true)
|
||||
Container(
|
||||
height: 17,
|
||||
padding: EdgeInsets.only(left: 6, right: 6),
|
||||
|
@ -123,7 +123,7 @@ class UnspentCoinsListItem extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (address.toLowerCase().contains("mweb"))
|
||||
if (address.toLowerCase().contains("mweb") || true)
|
||||
Container(
|
||||
height: 17,
|
||||
padding: EdgeInsets.only(left: 6, right: 6),
|
||||
|
@ -141,7 +141,7 @@ class UnspentCoinsListItem extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (isSilentPayment)
|
||||
if (isSilentPayment || true)
|
||||
Container(
|
||||
height: 17,
|
||||
padding: EdgeInsets.only(left: 6, right: 6),
|
||||
|
@ -158,8 +158,8 @@ class UnspentCoinsListItem extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -414,8 +414,8 @@ abstract class DashboardViewModelBase with Store {
|
|||
@computed
|
||||
bool get showMwebCard => hasMweb && settingsStore.mwebCardDisplay;
|
||||
|
||||
@observable
|
||||
bool mwebScanningActive = false;
|
||||
@computed
|
||||
bool get mwebScanningActive => settingsStore.mwebEnabled;
|
||||
|
||||
@computed
|
||||
bool get hasEnabledMwebBefore => settingsStore.hasEnabledMwebBefore;
|
||||
|
@ -430,7 +430,7 @@ abstract class DashboardViewModelBase with Store {
|
|||
settingsStore.hasEnabledMwebBefore = true;
|
||||
}
|
||||
|
||||
mwebScanningActive = active;
|
||||
settingsStore.mwebEnabled = active;
|
||||
bitcoin!.setMwebEnabled(wallet, active);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue