Merge branch 'main' of https://github.com/cake-tech/cake_wallet into mweb
|
@ -91,5 +91,4 @@ dependencies {
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
implementation 'com.unstoppabledomains:resolution:5.0.0'
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,10 @@ import android.net.Uri;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import com.unstoppabledomains.resolution.DomainResolution;
|
|
||||||
import com.unstoppabledomains.resolution.Resolution;
|
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public class MainActivity extends FlutterFragmentActivity {
|
public class MainActivity extends FlutterFragmentActivity {
|
||||||
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
|
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
|
||||||
final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
|
|
||||||
boolean isAppSecure = false;
|
boolean isAppSecure = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,14 +49,6 @@ public class MainActivity extends FlutterFragmentActivity {
|
||||||
random.nextBytes(bytes);
|
random.nextBytes(bytes);
|
||||||
handler.post(() -> result.success(bytes));
|
handler.post(() -> result.success(bytes));
|
||||||
break;
|
break;
|
||||||
case "getUnstoppableDomainAddress":
|
|
||||||
int version = Build.VERSION.SDK_INT;
|
|
||||||
if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
|
|
||||||
getUnstoppableDomainAddress(call, result);
|
|
||||||
} else {
|
|
||||||
handler.post(() -> result.success(""));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "setIsAppSecure":
|
case "setIsAppSecure":
|
||||||
isAppSecure = call.argument("isAppSecure");
|
isAppSecure = call.argument("isAppSecure");
|
||||||
if (isAppSecure) {
|
if (isAppSecure) {
|
||||||
|
@ -85,23 +73,6 @@ public class MainActivity extends FlutterFragmentActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
|
||||||
DomainResolution resolution = new Resolution();
|
|
||||||
Handler handler = new Handler(Looper.getMainLooper());
|
|
||||||
String domain = call.argument("domain");
|
|
||||||
String ticker = call.argument("ticker");
|
|
||||||
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
try {
|
|
||||||
String address = resolution.getAddress(domain, ticker);
|
|
||||||
handler.post(() -> result.success(address));
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("Expected Address, but got " + e.getMessage());
|
|
||||||
handler.post(() -> result.success(""));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableBatteryOptimization() {
|
private void disableBatteryOptimization() {
|
||||||
String packageName = getPackageName();
|
String packageName = getPackageName();
|
||||||
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
|
|
|
@ -19,14 +19,10 @@ import android.net.Uri;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import com.unstoppabledomains.resolution.DomainResolution;
|
|
||||||
import com.unstoppabledomains.resolution.Resolution;
|
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public class MainActivity extends FlutterFragmentActivity {
|
public class MainActivity extends FlutterFragmentActivity {
|
||||||
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
|
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
|
||||||
final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
|
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
|
||||||
|
@ -51,14 +47,6 @@ public class MainActivity extends FlutterFragmentActivity {
|
||||||
random.nextBytes(bytes);
|
random.nextBytes(bytes);
|
||||||
handler.post(() -> result.success(bytes));
|
handler.post(() -> result.success(bytes));
|
||||||
break;
|
break;
|
||||||
case "getUnstoppableDomainAddress":
|
|
||||||
int version = Build.VERSION.SDK_INT;
|
|
||||||
if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
|
|
||||||
getUnstoppableDomainAddress(call, result);
|
|
||||||
} else {
|
|
||||||
handler.post(() -> result.success(""));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "disableBatteryOptimization":
|
case "disableBatteryOptimization":
|
||||||
disableBatteryOptimization();
|
disableBatteryOptimization();
|
||||||
handler.post(() -> result.success(null));
|
handler.post(() -> result.success(null));
|
||||||
|
@ -75,23 +63,6 @@ public class MainActivity extends FlutterFragmentActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
|
||||||
DomainResolution resolution = new Resolution();
|
|
||||||
Handler handler = new Handler(Looper.getMainLooper());
|
|
||||||
String domain = call.argument("domain");
|
|
||||||
String ticker = call.argument("ticker");
|
|
||||||
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
try {
|
|
||||||
String address = resolution.getAddress(domain, ticker);
|
|
||||||
handler.post(() -> result.success(address));
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("Expected Address, but got " + e.getMessage());
|
|
||||||
handler.post(() -> result.success(""));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableBatteryOptimization() {
|
private void disableBatteryOptimization() {
|
||||||
String packageName = getPackageName();
|
String packageName = getPackageName();
|
||||||
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
|
|
|
@ -19,14 +19,10 @@ import android.net.Uri;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import com.unstoppabledomains.resolution.DomainResolution;
|
|
||||||
import com.unstoppabledomains.resolution.Resolution;
|
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public class MainActivity extends FlutterFragmentActivity {
|
public class MainActivity extends FlutterFragmentActivity {
|
||||||
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
|
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
|
||||||
final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
|
|
||||||
boolean isAppSecure = false;
|
boolean isAppSecure = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,14 +48,6 @@ public class MainActivity extends FlutterFragmentActivity {
|
||||||
random.nextBytes(bytes);
|
random.nextBytes(bytes);
|
||||||
handler.post(() -> result.success(bytes));
|
handler.post(() -> result.success(bytes));
|
||||||
break;
|
break;
|
||||||
case "getUnstoppableDomainAddress":
|
|
||||||
int version = Build.VERSION.SDK_INT;
|
|
||||||
if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
|
|
||||||
getUnstoppableDomainAddress(call, result);
|
|
||||||
} else {
|
|
||||||
handler.post(() -> result.success(""));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "setIsAppSecure":
|
case "setIsAppSecure":
|
||||||
isAppSecure = call.argument("isAppSecure");
|
isAppSecure = call.argument("isAppSecure");
|
||||||
if (isAppSecure) {
|
if (isAppSecure) {
|
||||||
|
@ -84,23 +72,6 @@ public class MainActivity extends FlutterFragmentActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
|
||||||
DomainResolution resolution = new Resolution();
|
|
||||||
Handler handler = new Handler(Looper.getMainLooper());
|
|
||||||
String domain = call.argument("domain");
|
|
||||||
String ticker = call.argument("ticker");
|
|
||||||
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
try {
|
|
||||||
String address = resolution.getAddress(domain, ticker);
|
|
||||||
handler.post(() -> result.success(address));
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("Expected Address, but got " + e.getMessage());
|
|
||||||
handler.post(() -> result.success(""));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableBatteryOptimization() {
|
private void disableBatteryOptimization() {
|
||||||
String packageName = getPackageName();
|
String packageName = getPackageName();
|
||||||
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
|
|
|
@ -2,7 +2,7 @@ buildscript {
|
||||||
ext.kotlin_version = '1.8.21'
|
ext.kotlin_version = '1.8.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -15,7 +15,7 @@ buildscript {
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 28 KiB |
|
@ -5,7 +5,7 @@ buildscript {
|
||||||
ext.kotlin_version = '1.7.10'
|
ext.kotlin_version = '1.7.10'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -17,7 +17,7 @@ buildscript {
|
||||||
rootProject.allprojects {
|
rootProject.allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ buildscript {
|
||||||
ext.kotlin_version = '1.7.10'
|
ext.kotlin_version = '1.7.10'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -17,7 +17,7 @@ buildscript {
|
||||||
rootProject.allprojects {
|
rootProject.allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ target 'Runner' do
|
||||||
|
|
||||||
# Cake Wallet (Legacy)
|
# Cake Wallet (Legacy)
|
||||||
pod 'CryptoSwift'
|
pod 'CryptoSwift'
|
||||||
pod 'UnstoppableDomainsResolution', '~> 4.0.0'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import Flutter
|
import Flutter
|
||||||
import UnstoppableDomainsResolution
|
|
||||||
import workmanager
|
import workmanager
|
||||||
|
|
||||||
@UIApplicationMain
|
@UIApplicationMain
|
||||||
|
@ -87,27 +86,7 @@ import workmanager
|
||||||
}
|
}
|
||||||
|
|
||||||
result(secRandom(count: count))
|
result(secRandom(count: count))
|
||||||
case "getUnstoppableDomainAddress":
|
|
||||||
guard let args = call.arguments as? Dictionary<String, String>,
|
|
||||||
let domain = args["domain"],
|
|
||||||
let ticker = args["ticker"],
|
|
||||||
let resolution = self?.resolution else {
|
|
||||||
result(nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resolution.addr(domain: domain, ticker: ticker) { addrResult in
|
|
||||||
var address : String = ""
|
|
||||||
|
|
||||||
switch addrResult {
|
|
||||||
case .success(let returnValue):
|
|
||||||
address = returnValue
|
|
||||||
case .failure(let error):
|
|
||||||
print("Expected Address, but got \(error)")
|
|
||||||
}
|
|
||||||
|
|
||||||
result(address)
|
|
||||||
}
|
|
||||||
case "setIsAppSecure":
|
case "setIsAppSecure":
|
||||||
guard let args = call.arguments as? Dictionary<String, Bool>,
|
guard let args = call.arguments as? Dictionary<String, Bool>,
|
||||||
let isAppSecure = args["isAppSecure"] else {
|
let isAppSecure = args["isAppSecure"] else {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import 'package:cake_wallet/utils/device_info.dart';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
const channel = MethodChannel('com.cake_wallet/native_utils');
|
const channel = MethodChannel('com.cake_wallet/native_utils');
|
||||||
|
|
||||||
|
@ -7,18 +9,19 @@ Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async
|
||||||
var address = '';
|
var address = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (DeviceInfo.instance.isMobile) {
|
final uri = Uri.parse("https://api.unstoppabledomains.com/profile/public/${Uri.encodeQueryComponent(domain)}?fields=records");
|
||||||
address = await channel.invokeMethod<String>(
|
final jsonString = await http.read(uri);
|
||||||
'getUnstoppableDomainAddress',
|
final jsonParsed = json.decode(jsonString) as Map<String, dynamic>;
|
||||||
<String, String> {
|
if (jsonParsed["records"] == null) {
|
||||||
'domain' : domain,
|
throw Exception(".records response from $uri is empty");
|
||||||
'ticker' : ticker
|
};
|
||||||
}
|
final records = jsonParsed["records"] as Map<String, dynamic>;
|
||||||
) ?? '';
|
final key = "crypto.${ticker.toUpperCase()}.address";
|
||||||
} else {
|
if (records[key] == null) {
|
||||||
// TODO: Integrate with Unstoppable domains resolution API
|
throw Exception(".records.${key} response from $uri is empty");
|
||||||
return address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return records[key] as String? ?? '';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Unstoppable domain error: ${e.toString()}');
|
print('Unstoppable domain error: ${e.toString()}');
|
||||||
address = '';
|
address = '';
|
||||||
|
|
|
@ -25,6 +25,7 @@ import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
import 'package:cake_wallet/entities/seed_type.dart';
|
import 'package:cake_wallet/entities/seed_type.dart';
|
||||||
|
|
||||||
|
|
||||||
class NewWalletPage extends BasePage {
|
class NewWalletPage extends BasePage {
|
||||||
NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
|
NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||||
_walletNewVM.hasWalletPassword ? TextEditingController() : null;
|
_walletNewVM.hasWalletPassword ? TextEditingController() : null;
|
||||||
|
|
||||||
static const aspectRatioImage = 1.22;
|
static const aspectRatioImage = 1.22;
|
||||||
|
static bool formProcessing = false;
|
||||||
|
|
||||||
final GlobalKey<FormState> _formKey;
|
final GlobalKey<FormState> _formKey;
|
||||||
final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
|
final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
|
||||||
|
@ -347,26 +349,35 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _confirmForm() {
|
void _confirmForm() async {
|
||||||
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
|
if (formProcessing) return;
|
||||||
return;
|
formProcessing = true;
|
||||||
}
|
try {
|
||||||
if (_walletNewVM.nameExists(_walletNewVM.name)) {
|
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
|
||||||
showPopUp<void>(
|
formProcessing = false;
|
||||||
context: context,
|
return;
|
||||||
builder: (_) {
|
}
|
||||||
return AlertWithOneAction(
|
if (_walletNewVM.nameExists(_walletNewVM.name)) {
|
||||||
alertTitle: '',
|
await showPopUp<void>(
|
||||||
alertContent: S.of(context).wallet_name_exists,
|
context: context,
|
||||||
buttonText: S.of(context).ok,
|
builder: (_) {
|
||||||
buttonAction: () => Navigator.of(context).pop());
|
return AlertWithOneAction(
|
||||||
});
|
alertTitle: '',
|
||||||
} else {
|
alertContent: S.of(context).wallet_name_exists,
|
||||||
_walletNewVM.create(
|
buttonText: S.of(context).ok,
|
||||||
options: _walletNewVM.hasLanguageSelector
|
buttonAction: () => Navigator.of(context).pop());
|
||||||
? [_languageSelectorKey.currentState!.selected, isPolyseed]
|
});
|
||||||
: null);
|
} else {
|
||||||
|
await _walletNewVM.create(
|
||||||
|
options: _walletNewVM.hasLanguageSelector
|
||||||
|
? [_languageSelectorKey.currentState!.selected, isPolyseed]
|
||||||
|
: null);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
formProcessing = false;
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
|
formProcessing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
|
bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:cake_wallet/core/execution_state.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
|
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
|
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
|
@ -80,6 +81,8 @@ class WalletRestorePage extends BasePage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool formProcessing = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget middle(BuildContext context) => Observer(
|
Widget middle(BuildContext context) => Observer(
|
||||||
builder: (_) => Text(
|
builder: (_) => Text(
|
||||||
|
@ -350,75 +353,85 @@ class WalletRestorePage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _confirmForm(BuildContext context) async {
|
Future<void> _confirmForm(BuildContext context) async {
|
||||||
// Dismissing all visible keyboard to provide context for navigation
|
if (formProcessing) return;
|
||||||
FocusManager.instance.primaryFocus?.unfocus();
|
formProcessing = true;
|
||||||
|
try {
|
||||||
|
// Dismissing all visible keyboard to provide context for navigation
|
||||||
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
|
|
||||||
late BuildContext? formContext;
|
late BuildContext? formContext;
|
||||||
late GlobalKey<FormState>? formKey;
|
late GlobalKey<FormState>? formKey;
|
||||||
late String name;
|
late String name;
|
||||||
if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
|
if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
|
||||||
formContext = walletRestoreFromSeedFormKey.currentContext;
|
formContext = walletRestoreFromSeedFormKey.currentContext;
|
||||||
formKey = walletRestoreFromSeedFormKey.currentState!.formKey;
|
formKey = walletRestoreFromSeedFormKey.currentState!.formKey;
|
||||||
name = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.value.text;
|
name = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.value.text;
|
||||||
} else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) {
|
} else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) {
|
||||||
formContext = walletRestoreFromKeysFormKey.currentContext;
|
formContext = walletRestoreFromKeysFormKey.currentContext;
|
||||||
formKey = walletRestoreFromKeysFormKey.currentState!.formKey;
|
formKey = walletRestoreFromKeysFormKey.currentState!.formKey;
|
||||||
name = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.value.text;
|
name = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.value.text;
|
||||||
}
|
|
||||||
|
|
||||||
if (!formKey!.currentState!.validate()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walletRestoreViewModel.nameExists(name)) {
|
|
||||||
showNameExistsAlert(formContext!);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
walletRestoreViewModel.state = IsExecutingState();
|
|
||||||
|
|
||||||
DerivationInfo? dInfo;
|
|
||||||
|
|
||||||
// get info about the different derivations:
|
|
||||||
List<DerivationInfo> derivations =
|
|
||||||
await walletRestoreViewModel.getDerivationInfo(_credentials());
|
|
||||||
|
|
||||||
int derivationsWithHistory = 0;
|
|
||||||
int derivationWithHistoryIndex = 0;
|
|
||||||
for (int i = 0; i < derivations.length; i++) {
|
|
||||||
if (derivations[i].transactionsCount > 0) {
|
|
||||||
derivationsWithHistory++;
|
|
||||||
derivationWithHistoryIndex = i;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (derivationsWithHistory > 1) {
|
if (!formKey!.currentState!.validate()) {
|
||||||
dInfo = await Navigator.of(context).pushNamed(
|
formProcessing = false;
|
||||||
Routes.restoreWalletChooseDerivation,
|
return;
|
||||||
arguments: derivations,
|
|
||||||
) as DerivationInfo?;
|
|
||||||
} else if (derivationsWithHistory == 1) {
|
|
||||||
dInfo = derivations[derivationWithHistoryIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the default derivation for this wallet type:
|
|
||||||
if (dInfo == null) {
|
|
||||||
// we only return 1 derivation if we're pretty sure we know which one to use:
|
|
||||||
if (derivations.length == 1) {
|
|
||||||
dInfo = derivations.first;
|
|
||||||
} else {
|
|
||||||
// if we have multiple possible derivations, and none have histories
|
|
||||||
// we just default to the most common one:
|
|
||||||
dInfo = walletRestoreViewModel.getCommonRestoreDerivation();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.derivationInfo = dInfo;
|
if (walletRestoreViewModel.nameExists(name)) {
|
||||||
if (this.derivationInfo == null) {
|
showNameExistsAlert(formContext!);
|
||||||
this.derivationInfo = walletRestoreViewModel.getDefaultDerivation();
|
formProcessing = false;
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
walletRestoreViewModel.create(options: _credentials());
|
walletRestoreViewModel.state = IsExecutingState();
|
||||||
|
|
||||||
|
DerivationInfo? dInfo;
|
||||||
|
|
||||||
|
// get info about the different derivations:
|
||||||
|
List<DerivationInfo> derivations =
|
||||||
|
await walletRestoreViewModel.getDerivationInfo(_credentials());
|
||||||
|
|
||||||
|
int derivationsWithHistory = 0;
|
||||||
|
int derivationWithHistoryIndex = 0;
|
||||||
|
for (int i = 0; i < derivations.length; i++) {
|
||||||
|
if (derivations[i].transactionsCount > 0) {
|
||||||
|
derivationsWithHistory++;
|
||||||
|
derivationWithHistoryIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (derivationsWithHistory > 1) {
|
||||||
|
dInfo = await Navigator.of(context).pushNamed(
|
||||||
|
Routes.restoreWalletChooseDerivation,
|
||||||
|
arguments: derivations,
|
||||||
|
) as DerivationInfo?;
|
||||||
|
} else if (derivationsWithHistory == 1) {
|
||||||
|
dInfo = derivations[derivationWithHistoryIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the default derivation for this wallet type:
|
||||||
|
if (dInfo == null) {
|
||||||
|
// we only return 1 derivation if we're pretty sure we know which one to use:
|
||||||
|
if (derivations.length == 1) {
|
||||||
|
dInfo = derivations.first;
|
||||||
|
} else {
|
||||||
|
// if we have multiple possible derivations, and none have histories
|
||||||
|
// we just default to the most common one:
|
||||||
|
dInfo = walletRestoreViewModel.getCommonRestoreDerivation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.derivationInfo = dInfo;
|
||||||
|
if (this.derivationInfo == null) {
|
||||||
|
this.derivationInfo = walletRestoreViewModel.getDefaultDerivation();
|
||||||
|
}
|
||||||
|
|
||||||
|
await walletRestoreViewModel.create(options: _credentials());
|
||||||
|
} catch (e) {
|
||||||
|
formProcessing = false;
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
formProcessing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> showNameExistsAlert(BuildContext context) {
|
Future<void> showNameExistsAlert(BuildContext context) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/view_model/settings/regular_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/support_view_model.dart';
|
import 'package:cake_wallet/view_model/support_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
|
||||||
class SupportOtherLinksPage extends BasePage {
|
class SupportOtherLinksPage extends BasePage {
|
||||||
|
@ -22,8 +23,11 @@ class SupportOtherLinksPage extends BasePage {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget body(BuildContext context) {
|
Widget body(BuildContext context) {
|
||||||
|
|
||||||
final iconColor = Theme.of(context).extension<SupportPageTheme>()!.iconColor;
|
final iconColor = Theme.of(context).extension<SupportPageTheme>()!.iconColor;
|
||||||
|
|
||||||
|
final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
|
@ -37,16 +41,16 @@ class SupportOtherLinksPage extends BasePage {
|
||||||
if (item is RegularListItem) {
|
if (item is RegularListItem) {
|
||||||
return SettingsCellWithArrow(title: item.title, handler: item.handler);
|
return SettingsCellWithArrow(title: item.title, handler: item.handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item is LinkListItem) {
|
if (item is LinkListItem) {
|
||||||
|
bool hasLightIcon = false;
|
||||||
|
if (item.lightIcon != null) hasLightIcon = true;
|
||||||
return SettingsLinkProviderCell(
|
return SettingsLinkProviderCell(
|
||||||
title: item.title,
|
title: item.title,
|
||||||
icon: item.icon,
|
icon: isLightMode && hasLightIcon ? item.lightIcon : item.icon,
|
||||||
iconColor: item.hasIconColor ? iconColor : null,
|
iconColor: item.hasIconColor ? iconColor : null,
|
||||||
link: item.link,
|
link: item.link,
|
||||||
linkTitle: item.linkTitle);
|
linkTitle: item.linkTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container();
|
return Container();
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|
|
@ -8,10 +8,12 @@ class LinkListItem extends SettingsListItem {
|
||||||
required this.link,
|
required this.link,
|
||||||
required this.linkTitle,
|
required this.linkTitle,
|
||||||
this.icon,
|
this.icon,
|
||||||
|
this.lightIcon,
|
||||||
this.hasIconColor = false})
|
this.hasIconColor = false})
|
||||||
: super(title);
|
: super(title);
|
||||||
|
|
||||||
final String? icon;
|
final String? icon;
|
||||||
|
final String? lightIcon;
|
||||||
final String link;
|
final String link;
|
||||||
final String linkTitle;
|
final String linkTitle;
|
||||||
final bool hasIconColor;
|
final bool hasIconColor;
|
||||||
|
|
|
@ -33,11 +33,6 @@ abstract class SupportViewModelBase with Store {
|
||||||
icon: 'assets/images/Telegram.png',
|
icon: 'assets/images/Telegram.png',
|
||||||
linkTitle: '@cakewallet_bot',
|
linkTitle: '@cakewallet_bot',
|
||||||
link: 'https://t.me/cakewallet_bot'),
|
link: 'https://t.me/cakewallet_bot'),
|
||||||
LinkListItem(
|
|
||||||
title: 'Twitter',
|
|
||||||
icon: 'assets/images/Twitter.png',
|
|
||||||
linkTitle: '@cakewallet',
|
|
||||||
link: 'https://twitter.com/cakewallet'),
|
|
||||||
LinkListItem(
|
LinkListItem(
|
||||||
title: 'ChangeNow',
|
title: 'ChangeNow',
|
||||||
icon: 'assets/images/change_now.png',
|
icon: 'assets/images/change_now.png',
|
||||||
|
@ -46,7 +41,7 @@ abstract class SupportViewModelBase with Store {
|
||||||
LinkListItem(
|
LinkListItem(
|
||||||
title: 'SideShift',
|
title: 'SideShift',
|
||||||
icon: 'assets/images/sideshift.png',
|
icon: 'assets/images/sideshift.png',
|
||||||
linkTitle: S.current.help,
|
linkTitle: 'help.sideshift.ai',
|
||||||
link: 'https://help.sideshift.ai/en/'),
|
link: 'https://help.sideshift.ai/en/'),
|
||||||
LinkListItem(
|
LinkListItem(
|
||||||
title: 'SimpleSwap',
|
title: 'SimpleSwap',
|
||||||
|
@ -58,19 +53,41 @@ abstract class SupportViewModelBase with Store {
|
||||||
icon: 'assets/images/exolix.png',
|
icon: 'assets/images/exolix.png',
|
||||||
linkTitle: 'support@exolix.com',
|
linkTitle: 'support@exolix.com',
|
||||||
link: 'mailto:support@exolix.com'),
|
link: 'mailto:support@exolix.com'),
|
||||||
|
LinkListItem(
|
||||||
|
title: 'Quantex',
|
||||||
|
icon: 'assets/images/quantex.png',
|
||||||
|
linkTitle: 'help.myquantex.com',
|
||||||
|
link: 'mailto:support@exolix.com'),
|
||||||
|
LinkListItem(
|
||||||
|
title: 'Trocador',
|
||||||
|
icon: 'assets/images/trocador.png',
|
||||||
|
linkTitle: 'mail@trocador.app',
|
||||||
|
link: 'mailto:mail@trocador.app'),
|
||||||
|
LinkListItem(
|
||||||
|
title: 'Onramper',
|
||||||
|
icon: 'assets/images/onramper_dark.png',
|
||||||
|
lightIcon: 'assets/images/onramper_light.png',
|
||||||
|
linkTitle: 'View exchanges',
|
||||||
|
link: 'https://guides.cakewallet.com/docs/service-support/buy/#onramper'),
|
||||||
|
LinkListItem(
|
||||||
|
title: 'DFX',
|
||||||
|
icon: 'assets/images/dfx_dark.png',
|
||||||
|
lightIcon: 'assets/images/dfx_light.png',
|
||||||
|
linkTitle: 'support@dfx.swiss',
|
||||||
|
link: 'mailto:support@dfx.swiss'),
|
||||||
if (!isMoneroOnly) ... [
|
if (!isMoneroOnly) ... [
|
||||||
LinkListItem(
|
|
||||||
title: 'Wyre',
|
|
||||||
icon: 'assets/images/wyre.png',
|
|
||||||
linkTitle: S.current.submit_request,
|
|
||||||
link: 'https://wyre-support.zendesk.com/hc/en-us/requests/new'),
|
|
||||||
LinkListItem(
|
LinkListItem(
|
||||||
title: 'MoonPay',
|
title: 'MoonPay',
|
||||||
icon: 'assets/images/moonpay.png',
|
icon: 'assets/images/moonpay.png',
|
||||||
hasIconColor: true,
|
|
||||||
linkTitle: S.current.submit_request,
|
linkTitle: S.current.submit_request,
|
||||||
link: 'https://support.moonpay.com/hc/en-gb/requests/new')
|
link: 'https://support.moonpay.com/hc/en-gb/requests/new'),
|
||||||
]
|
LinkListItem(
|
||||||
|
title: 'Robinhood Connect',
|
||||||
|
icon: 'assets/images/robinhood_dark.png',
|
||||||
|
lightIcon: 'assets/images/robinhood_light.png',
|
||||||
|
linkTitle: S.current.submit_request,
|
||||||
|
link: 'https://robinhood.com/contact')
|
||||||
|
]
|
||||||
//LinkListItem(
|
//LinkListItem(
|
||||||
// title: 'Yat',
|
// title: 'Yat',
|
||||||
// icon: 'assets/images/yat_mini_logo.png',
|
// icon: 'assets/images/yat_mini_logo.png',
|
||||||
|
|