From d1c85651f29811192c61133e094332bc4499296b Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Tue, 3 Sep 2024 11:05:55 -0700
Subject: [PATCH] improve mweb reliability

---
 cw_bitcoin/lib/litecoin_wallet.dart                | 14 ++++++++++++++
 cw_bitcoin/lib/litecoin_wallet_addresses.dart      |  7 +++++--
 cw_bitcoin/lib/litecoin_wallet_service.dart        |  6 +++---
 .../kotlin/com/cakewallet/mweb/CwMwebPlugin.kt     |  5 ++++-
 cw_mweb/ios/Classes/CwMwebPlugin.swift             |  1 +
 cw_mweb/lib/cw_mweb.dart                           |  2 ++
 6 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart
index 3204e5cbd..b69ba59dd 100644
--- a/cw_bitcoin/lib/litecoin_wallet.dart
+++ b/cw_bitcoin/lib/litecoin_wallet.dart
@@ -443,6 +443,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   Future<void> processMwebUtxos() async {
+    if (!mwebEnabled) {
+      return;
+    }
+
     int restoreHeight = walletInfo.restoreHeight;
     print("SCANNING FROM HEIGHT: $restoreHeight");
     final req = UtxosRequest(scanSecret: scanSecret, fromHeight: restoreHeight);
@@ -502,6 +506,10 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   Future<void> checkMwebUtxosSpent() async {
+    if (!mwebEnabled) {
+      return;
+    }
+
     while ((await Future.wait(transactionHistory.transactions.values
             .where((tx) => tx.direction == TransactionDirection.outgoing && tx.isPending)
             .map(checkPendingTransaction)))
@@ -557,6 +565,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
   }
 
   Future<bool> checkPendingTransaction(ElectrumTransactionInfo tx) async {
+    if (!mwebEnabled) return false;
     if (!tx.isPending) return false;
     final outputId = <String>[], target = <String>{};
     final isHash = RegExp(r'^[a-f0-9]{64}$').hasMatch;
@@ -755,6 +764,11 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
         vinOutpoints: vinOutpoints,
       );
     }
+
+    if (!mwebEnabled) {
+      throw Exception("MWEB is not enabled! can't calculate fee without starting the mweb server!");
+    }
+
     if (outputs.length == 1 && outputs[0].toOutput.amount == BigInt.zero) {
       outputs = [
         BitcoinScriptOutput(
diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
index 12140472c..7db9d7bae 100644
--- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart
@@ -25,7 +25,10 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
     super.initialChangeAddressIndex,
   }) : super(walletInfo) {
     if (mwebEnabled) {
-      topUpMweb(0);
+      // give the server a few seconds to start up before trying to get the addresses:
+      Future.delayed(const Duration(seconds: 5), () async {
+        await topUpMweb(0);
+      });
     }
   }
 
@@ -39,9 +42,9 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
   List<String> mwebAddrs = [];
 
   Future<void> topUpMweb(int index) async {
+    final stub = await CwMweb.stub();
     while (mwebAddrs.length - index < 1000) {
       final length = mwebAddrs.length;
-      final stub = await CwMweb.stub();
       final resp = await stub.addresses(AddressRequest(
         fromIndex: length,
         toIndex: index + 1000,
diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart
index 72efa41c7..da3602024 100644
--- a/cw_bitcoin/lib/litecoin_wallet_service.dart
+++ b/cw_bitcoin/lib/litecoin_wallet_service.dart
@@ -150,9 +150,9 @@ class LitecoinWalletService extends WalletService<
   @override
   Future<LitecoinWallet> restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials,
       {bool? isTestnet}) async {
-    if (!validateMnemonic(credentials.mnemonic) && !bip39.validateMnemonic(credentials.mnemonic)) {
-      throw LitecoinMnemonicIsIncorrectException();
-    }
+    // if (!validateMnemonic(credentials.mnemonic) && !bip39.validateMnemonic(credentials.mnemonic)) {
+    //   throw LitecoinMnemonicIsIncorrectException();
+    // }
 
     final wallet = await LitecoinWalletBase.create(
       password: credentials.password!,
diff --git a/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt b/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
index 2b366ad76..b1180dd4a 100644
--- a/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
+++ b/cw_mweb/android/src/main/kotlin/com/cakewallet/mweb/CwMwebPlugin.kt
@@ -28,9 +28,12 @@ class CwMwebPlugin: FlutterPlugin, MethodCallHandler {
 
   override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
     if (call.method == "start") {
+      server?.stop()
       val dataDir = call.argument("dataDir") ?: ""
+      // server = server ?: Mwebd.newServer("", dataDir, "")
+      // port = port ?: server?.start(0)
       server = server ?: Mwebd.newServer("", dataDir, "")
-      port = port ?: server?.start(0)
+      port = server?.start(0)
       result.success(port)
     } else if (call.method == "stop") {
       server?.stop()
diff --git a/cw_mweb/ios/Classes/CwMwebPlugin.swift b/cw_mweb/ios/Classes/CwMwebPlugin.swift
index fff1283d8..ed08d6748 100644
--- a/cw_mweb/ios/Classes/CwMwebPlugin.swift
+++ b/cw_mweb/ios/Classes/CwMwebPlugin.swift
@@ -18,6 +18,7 @@ public class CwMwebPlugin: NSObject, FlutterPlugin {
         case "getPlatformVersion":
             result("iOS " + UIDevice.current.systemVersion)
         case "start":
+            stopServer()
             let args = call.arguments as? [String: String]
             let dataDir = args?["dataDir"]
             CwMwebPlugin.dataDir = dataDir
diff --git a/cw_mweb/lib/cw_mweb.dart b/cw_mweb/lib/cw_mweb.dart
index 98afc73dd..df3300379 100644
--- a/cw_mweb/lib/cw_mweb.dart
+++ b/cw_mweb/lib/cw_mweb.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
 import 'package:grpc/grpc.dart';
 import 'package:path_provider/path_provider.dart';
 import 'cw_mweb_platform_interface.dart';