mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
Merge remote-tracking branch 'origin/main' into electrum-sp-refactors
This commit is contained in:
commit
3ee697b4c1
29 changed files with 353 additions and 177 deletions
|
@ -1,6 +1,3 @@
|
||||||
-
|
|
||||||
uri: electrum.cakewallet.com:50002
|
|
||||||
useSSL: true
|
|
||||||
-
|
-
|
||||||
uri: btc-electrum.cakewallet.com:50002
|
uri: btc-electrum.cakewallet.com:50002
|
||||||
useSSL: true
|
useSSL: true
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
uri: xmr-node.cakewallet.com:18081
|
uri: xmr-node.cakewallet.com:18081
|
||||||
is_default: true
|
is_default: true
|
||||||
trusted: true
|
trusted: true
|
||||||
|
useSSL: true
|
||||||
-
|
-
|
||||||
uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081
|
uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081
|
||||||
is_default: false
|
is_default: false
|
||||||
|
|
|
@ -203,9 +203,30 @@ class Node extends HiveObject with Keyable {
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: json.encode(body),
|
body: json.encode(body),
|
||||||
);
|
);
|
||||||
|
|
||||||
client.close();
|
client.close();
|
||||||
|
|
||||||
|
if ((
|
||||||
|
response.body.contains("400 Bad Request") // Some other generic error
|
||||||
|
|| response.body.contains("plain HTTP request was sent to HTTPS port") // Cloudflare
|
||||||
|
|| response.headers["location"] != null // Generic reverse proxy
|
||||||
|
|| response.body.contains("301 Moved Permanently") // Poorly configured generic reverse proxy
|
||||||
|
) && !(useSSL??false)
|
||||||
|
) {
|
||||||
|
|
||||||
|
final oldUseSSL = useSSL;
|
||||||
|
useSSL = true;
|
||||||
|
try {
|
||||||
|
final ret = await requestMoneroNode();
|
||||||
|
if (ret == true) {
|
||||||
|
await save();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
useSSL = oldUseSSL;
|
||||||
|
} catch (e) {
|
||||||
|
useSSL = oldUseSSL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
||||||
return !(resBody['result']['offline'] as bool);
|
return !(resBody['result']['offline'] as bool);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|
|
@ -2,14 +2,14 @@ group 'com.cakewallet.cw_haven'
|
||||||
version '1.0-SNAPSHOT'
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.7.10'
|
ext.kotlin_version = '2.0.21'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
classpath 'com.android.tools.build:gradle:8.7.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,20 @@ apply plugin: 'com.android.library'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 33
|
||||||
|
|
||||||
|
if (project.android.hasProperty("namespace")) {
|
||||||
|
namespace 'com.cakewallet.cw_haven'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '17'
|
||||||
|
}
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ String getTxKey(String txId) {
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = monero.Wallet_status(wptr!);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final error = monero.Wallet_errorString(wptr!);
|
final error = monero.Wallet_errorString(wptr!);
|
||||||
return txId+"_"+error;
|
return "";
|
||||||
}
|
}
|
||||||
return txKey;
|
return txKey;
|
||||||
}
|
}
|
||||||
|
@ -92,11 +92,18 @@ Future<PendingTransactionDescription> createTransactionSync(
|
||||||
|
|
||||||
final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount);
|
final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount);
|
||||||
|
|
||||||
|
final waddr = wptr!.address;
|
||||||
|
|
||||||
|
// force reconnection in case the os killed the connection?
|
||||||
|
// fixes failed to get block height error.
|
||||||
|
Isolate.run(() async {
|
||||||
|
monero.Wallet_synchronized(Pointer.fromAddress(waddr));
|
||||||
|
});
|
||||||
|
|
||||||
final address_ = address.toNativeUtf8();
|
final address_ = address.toNativeUtf8();
|
||||||
final paymentId_ = paymentId.toNativeUtf8();
|
final paymentId_ = paymentId.toNativeUtf8();
|
||||||
final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8();
|
final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8();
|
||||||
|
|
||||||
final waddr = wptr!.address;
|
|
||||||
final addraddr = address_.address;
|
final addraddr = address_.address;
|
||||||
final paymentIdAddr = paymentId_.address;
|
final paymentIdAddr = paymentId_.address;
|
||||||
final preferredInputsAddr = preferredInputs_.address;
|
final preferredInputsAddr = preferredInputs_.address;
|
||||||
|
@ -357,16 +364,7 @@ class Transaction {
|
||||||
confirmations = monero.TransactionInfo_confirmations(txInfo),
|
confirmations = monero.TransactionInfo_confirmations(txInfo),
|
||||||
fee = monero.TransactionInfo_fee(txInfo),
|
fee = monero.TransactionInfo_fee(txInfo),
|
||||||
description = monero.TransactionInfo_description(txInfo),
|
description = monero.TransactionInfo_description(txInfo),
|
||||||
key = getTxKey(txInfo);
|
key = getTxKey(monero.TransactionInfo_hash(txInfo));
|
||||||
|
|
||||||
static String getTxKey(monero.TransactionInfo txInfo) {
|
|
||||||
final txKey = monero.Wallet_getTxKey(wptr!, txid: monero.TransactionInfo_hash(txInfo));
|
|
||||||
final status = monero.Wallet_status(wptr!);
|
|
||||||
if (status != 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return txKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transaction.dummy({
|
Transaction.dummy({
|
||||||
required this.displayLabel,
|
required this.displayLabel,
|
||||||
|
|
|
@ -150,14 +150,15 @@ final storeMutex = Mutex();
|
||||||
|
|
||||||
int lastStorePointer = 0;
|
int lastStorePointer = 0;
|
||||||
int lastStoreHeight = 0;
|
int lastStoreHeight = 0;
|
||||||
void storeSync() async {
|
void storeSync({bool force = false}) async {
|
||||||
final addr = wptr!.address;
|
final addr = wptr!.address;
|
||||||
final synchronized = await Isolate.run(() {
|
final synchronized = await Isolate.run(() {
|
||||||
return monero.Wallet_synchronized(Pointer.fromAddress(addr));
|
return monero.Wallet_synchronized(Pointer.fromAddress(addr));
|
||||||
});
|
});
|
||||||
if (lastStorePointer == wptr!.address &&
|
if (lastStorePointer == wptr!.address &&
|
||||||
lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) &&
|
lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) &&
|
||||||
!synchronized) {
|
!synchronized &&
|
||||||
|
!force) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastStorePointer = wptr!.address;
|
lastStorePointer = wptr!.address;
|
||||||
|
|
|
@ -286,8 +286,18 @@ Future<void> loadWallet(
|
||||||
/// 0: Software Wallet
|
/// 0: Software Wallet
|
||||||
/// 1: Ledger
|
/// 1: Ledger
|
||||||
/// 2: Trezor
|
/// 2: Trezor
|
||||||
final deviceType = monero.WalletManager_queryWalletDevice(wmPtr,
|
late final deviceType;
|
||||||
keysFileName: "$path.keys", password: password, kdfRounds: 1);
|
|
||||||
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
|
deviceType = monero.WalletManager_queryWalletDevice(
|
||||||
|
wmPtr,
|
||||||
|
keysFileName: "$path.keys",
|
||||||
|
password: password,
|
||||||
|
kdfRounds: 1,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
deviceType = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (deviceType == 1) {
|
if (deviceType == 1) {
|
||||||
final dummyWPtr = wptr ??
|
final dummyWPtr = wptr ??
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/amount_converter.dart';
|
import 'package:cw_core/amount_converter.dart';
|
||||||
|
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
|
|
||||||
class DoubleSpendException implements Exception {
|
class DoubleSpendException implements Exception {
|
||||||
DoubleSpendException();
|
DoubleSpendException();
|
||||||
|
@ -53,6 +54,7 @@ class PendingMoneroTransaction with PendingTransaction {
|
||||||
|
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
storeSync(force: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -25,7 +25,20 @@ apply plugin: 'com.android.library'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 30
|
compileSdkVersion 33
|
||||||
|
|
||||||
|
if (project.android.hasProperty("namespace")) {
|
||||||
|
namespace 'com.cakewallet.cw_shared_external'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '17'
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
|
|
@ -251,8 +251,12 @@ class OnRamperBuyProvider extends BuyProvider {
|
||||||
return tag;
|
return tag;
|
||||||
case 'POL':
|
case 'POL':
|
||||||
return 'POLYGON';
|
return 'POLYGON';
|
||||||
default:
|
default:
|
||||||
return CryptoCurrency.fromString(tag).fullName ?? tag;
|
try {
|
||||||
|
return CryptoCurrency.fromString(tag).fullName!;
|
||||||
|
} catch (_) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,10 +260,34 @@ Future<void> defaultSettingsMigration(
|
||||||
updateBtcElectrumNodeToUseSSL(nodes, sharedPreferences);
|
updateBtcElectrumNodeToUseSSL(nodes, sharedPreferences);
|
||||||
break;
|
break;
|
||||||
case 43:
|
case 43:
|
||||||
_updateCakeXmrNode(nodes);
|
await _updateCakeXmrNode(nodes);
|
||||||
_deselectExchangeProvider(sharedPreferences, "THORChain");
|
_deselectExchangeProvider(sharedPreferences, "THORChain");
|
||||||
_deselectExchangeProvider(sharedPreferences, "SimpleSwap");
|
_deselectExchangeProvider(sharedPreferences, "SimpleSwap");
|
||||||
break;
|
break;
|
||||||
|
case 44:
|
||||||
|
await _updateCakeXmrNode(nodes);
|
||||||
|
await _changeDefaultNode(
|
||||||
|
nodes: nodes,
|
||||||
|
sharedPreferences: sharedPreferences,
|
||||||
|
type: WalletType.bitcoin,
|
||||||
|
newDefaultUri: newCakeWalletBitcoinUri,
|
||||||
|
currentNodePreferenceKey: PreferencesKey.currentBitcoinElectrumSererIdKey,
|
||||||
|
useSSL: true,
|
||||||
|
oldUri: ['cakewallet.com'],
|
||||||
|
);
|
||||||
|
_changeDefaultNode(
|
||||||
|
nodes: nodes,
|
||||||
|
sharedPreferences: sharedPreferences,
|
||||||
|
type: WalletType.tron,
|
||||||
|
newDefaultUri: tronDefaultNodeUri,
|
||||||
|
currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey,
|
||||||
|
useSSL: true,
|
||||||
|
oldUri: [
|
||||||
|
'tron-rpc.publicnode.com:443',
|
||||||
|
'api.trongrid.io',
|
||||||
|
],
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -279,17 +303,54 @@ Future<void> defaultSettingsMigration(
|
||||||
await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version);
|
await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateCakeXmrNode(Box<Node> nodes) {
|
/// generic function for changing any wallet default node
|
||||||
|
/// instead of making a new function for each change
|
||||||
|
Future<void> _changeDefaultNode({
|
||||||
|
required Box<Node> nodes,
|
||||||
|
required SharedPreferences sharedPreferences,
|
||||||
|
required WalletType type,
|
||||||
|
required String newDefaultUri,
|
||||||
|
required String currentNodePreferenceKey,
|
||||||
|
required bool useSSL,
|
||||||
|
required List<String> oldUri, // leave empty if you want to force replace the node regardless of the user's current node
|
||||||
|
}) async {
|
||||||
|
final currentNodeId = sharedPreferences.getInt(currentNodePreferenceKey);
|
||||||
|
final currentNode = nodes.values.firstWhere((node) => node.key == currentNodeId);
|
||||||
|
final shouldReplace = oldUri.any((e) => currentNode.uriRaw.contains(e));
|
||||||
|
|
||||||
|
if (shouldReplace) {
|
||||||
|
var newNodeId =
|
||||||
|
nodes.values.firstWhereOrNull((element) => element.uriRaw == newDefaultUri)?.key;
|
||||||
|
|
||||||
|
// new node doesn't exist, then add it
|
||||||
|
if (newNodeId == null) {
|
||||||
|
final newNode = Node(
|
||||||
|
uri: newDefaultUri,
|
||||||
|
type: type,
|
||||||
|
useSSL: useSSL,
|
||||||
|
);
|
||||||
|
|
||||||
|
await nodes.add(newNode);
|
||||||
|
newNodeId = newNode.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
await sharedPreferences.setInt(currentNodePreferenceKey, newNodeId as int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _updateCakeXmrNode(Box<Node> nodes) async {
|
||||||
final node = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletMoneroUri);
|
final node = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletMoneroUri);
|
||||||
|
|
||||||
if (node != null && !node.trusted) {
|
if (node != null) {
|
||||||
node.trusted = true;
|
node.trusted = true;
|
||||||
node.save();
|
node.useSSL = true;
|
||||||
|
await node.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateBtcElectrumNodeToUseSSL(Box<Node> nodes, SharedPreferences sharedPreferences) {
|
void updateBtcElectrumNodeToUseSSL(Box<Node> nodes, SharedPreferences sharedPreferences) {
|
||||||
final btcElectrumNode = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletBitcoinUri);
|
final btcElectrumNode =
|
||||||
|
nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletBitcoinUri);
|
||||||
|
|
||||||
if (btcElectrumNode != null) {
|
if (btcElectrumNode != null) {
|
||||||
btcElectrumNode.useSSL = true;
|
btcElectrumNode.useSSL = true;
|
||||||
|
@ -538,7 +599,6 @@ Node? getBitcoinCashDefaultElectrumServer({required Box<Node> nodes}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Node getMoneroDefaultNode({required Box<Node> nodes}) {
|
Node getMoneroDefaultNode({required Box<Node> nodes}) {
|
||||||
final timeZone = DateTime.now().timeZoneOffset.inHours;
|
|
||||||
var nodeUri = newCakeWalletMoneroUri;
|
var nodeUri = newCakeWalletMoneroUri;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -858,7 +918,8 @@ Future<void> changeDefaultMoneroNode(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero, trusted: true);
|
final newCakeWalletNode =
|
||||||
|
Node(uri: newCakeWalletMoneroUri, type: WalletType.monero, trusted: true);
|
||||||
|
|
||||||
await nodeSource.add(newCakeWalletNode);
|
await nodeSource.add(newCakeWalletNode);
|
||||||
|
|
||||||
|
@ -897,7 +958,7 @@ Future<void> updateBtcNanoWalletInfos(Box<WalletInfo> walletsInfoSource) async {
|
||||||
Future<void> changeDefaultNanoNode(
|
Future<void> changeDefaultNanoNode(
|
||||||
Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
|
Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
|
||||||
const oldNanoNodeUriPattern = 'rpc.nano.to';
|
const oldNanoNodeUriPattern = 'rpc.nano.to';
|
||||||
final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
|
final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
|
||||||
final currentNanoNode = nodeSource.values.firstWhere((node) => node.key == currentNanoNodeId);
|
final currentNanoNode = nodeSource.values.firstWhere((node) => node.key == currentNanoNodeId);
|
||||||
|
|
||||||
final newCakeWalletNode = Node(
|
final newCakeWalletNode = Node(
|
||||||
|
@ -909,7 +970,8 @@ Future<void> changeDefaultNanoNode(
|
||||||
await nodeSource.add(newCakeWalletNode);
|
await nodeSource.add(newCakeWalletNode);
|
||||||
|
|
||||||
if (currentNanoNode.uri.toString().contains(oldNanoNodeUriPattern)) {
|
if (currentNanoNode.uri.toString().contains(oldNanoNodeUriPattern)) {
|
||||||
await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, newCakeWalletNode.key as int);
|
await sharedPreferences.setInt(
|
||||||
|
PreferencesKey.currentNanoNodeIdKey, newCakeWalletNode.key as int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,7 +986,7 @@ Future<void> changeDefaultBitcoinNode(
|
||||||
currentBitcoinNode.uri.toString().contains(cakeWalletBitcoinNodeUriPattern);
|
currentBitcoinNode.uri.toString().contains(cakeWalletBitcoinNodeUriPattern);
|
||||||
|
|
||||||
final newCakeWalletBitcoinNode =
|
final newCakeWalletBitcoinNode =
|
||||||
Node(uri: newCakeWalletBitcoinUri, type: WalletType.bitcoin, useSSL: false);
|
Node(uri: newCakeWalletBitcoinUri, type: WalletType.bitcoin, useSSL: true);
|
||||||
|
|
||||||
if (!nodeSource.values.any((element) => element.uriRaw == newCakeWalletBitcoinUri)) {
|
if (!nodeSource.values.any((element) => element.uriRaw == newCakeWalletBitcoinUri)) {
|
||||||
await nodeSource.add(newCakeWalletBitcoinNode);
|
await nodeSource.add(newCakeWalletBitcoinNode);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
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/widgets/alert_with_one_action.dart';
|
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
|
||||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
@ -68,7 +66,7 @@ class MainActions {
|
||||||
|
|
||||||
|
|
||||||
static MainActions tradeAction = MainActions._(
|
static MainActions tradeAction = MainActions._(
|
||||||
name: (context) => '${S.of(context).buy} / ${S.of(context).sell}',
|
name: (context) => '${S.of(context).buy}/${S.of(context).sell}',
|
||||||
image: 'assets/images/buy_sell.png',
|
image: 'assets/images/buy_sell.png',
|
||||||
isEnabled: (viewModel) => viewModel.isEnabledTradeAction,
|
isEnabled: (viewModel) => viewModel.isEnabledTradeAction,
|
||||||
canShow: (viewModel) => viewModel.hasTradeAction,
|
canShow: (viewModel) => viewModel.hasTradeAction,
|
||||||
|
|
|
@ -26,23 +26,80 @@ class AddressResolver {
|
||||||
final SettingsStore settingsStore;
|
final SettingsStore settingsStore;
|
||||||
|
|
||||||
static const unstoppableDomains = [
|
static const unstoppableDomains = [
|
||||||
'crypto',
|
"888",
|
||||||
'zil',
|
"altimist",
|
||||||
'x',
|
"anime",
|
||||||
'wallet',
|
"austin",
|
||||||
'bitcoin',
|
"bald",
|
||||||
'888',
|
"benji",
|
||||||
'nft',
|
"bet",
|
||||||
'dao',
|
"binanceus",
|
||||||
'blockchain',
|
"bitcoin",
|
||||||
'polygon',
|
"bitget",
|
||||||
'klever',
|
"blockchain",
|
||||||
'hi',
|
"ca",
|
||||||
'kresus',
|
"chomp",
|
||||||
'anime',
|
"clay",
|
||||||
'manga',
|
"co",
|
||||||
'binanceus',
|
"com",
|
||||||
'xmr',
|
"crypto",
|
||||||
|
"dao",
|
||||||
|
"dfz",
|
||||||
|
"digital",
|
||||||
|
"dream",
|
||||||
|
"eth",
|
||||||
|
"ethermail",
|
||||||
|
"farms",
|
||||||
|
"fun",
|
||||||
|
"go",
|
||||||
|
"group",
|
||||||
|
"hi",
|
||||||
|
"host",
|
||||||
|
"info",
|
||||||
|
"io",
|
||||||
|
"klever",
|
||||||
|
"kresus",
|
||||||
|
"kryptic",
|
||||||
|
"lfg",
|
||||||
|
"life",
|
||||||
|
"live",
|
||||||
|
"ltd",
|
||||||
|
"manga",
|
||||||
|
"metropolis",
|
||||||
|
"moon",
|
||||||
|
"mumu",
|
||||||
|
"net",
|
||||||
|
"nft",
|
||||||
|
"online",
|
||||||
|
"org",
|
||||||
|
"pog",
|
||||||
|
"polygon",
|
||||||
|
"press",
|
||||||
|
"pro",
|
||||||
|
"propykeys",
|
||||||
|
"pudgy",
|
||||||
|
"pw",
|
||||||
|
"raiin",
|
||||||
|
"secret",
|
||||||
|
"site",
|
||||||
|
"smobler",
|
||||||
|
"space",
|
||||||
|
"stepn",
|
||||||
|
"store",
|
||||||
|
"tball",
|
||||||
|
"tech",
|
||||||
|
"ubu",
|
||||||
|
"uno",
|
||||||
|
"unstoppable",
|
||||||
|
"wallet",
|
||||||
|
"website",
|
||||||
|
"wifi",
|
||||||
|
"witg",
|
||||||
|
"wrkx",
|
||||||
|
"x",
|
||||||
|
"xmr",
|
||||||
|
"xyz",
|
||||||
|
"zil",
|
||||||
];
|
];
|
||||||
|
|
||||||
static String? extractAddressByType({required String raw, required CryptoCurrency type}) {
|
static String? extractAddressByType({required String raw, required CryptoCurrency type}) {
|
||||||
|
|
|
@ -203,7 +203,7 @@ Future<void> initializeAppConfigs() async {
|
||||||
transactionDescriptions: transactionDescriptions,
|
transactionDescriptions: transactionDescriptions,
|
||||||
secureStorage: secureStorage,
|
secureStorage: secureStorage,
|
||||||
anonpayInvoiceInfo: anonpayInvoiceInfo,
|
anonpayInvoiceInfo: anonpayInvoiceInfo,
|
||||||
initialMigrationVersion: 43,
|
initialMigrationVersion: 44,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,8 @@ void startCurrentWalletChangeReaction(
|
||||||
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
|
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
|
||||||
startCheckConnectionReaction(wallet, settingsStore);
|
startCheckConnectionReaction(wallet, settingsStore);
|
||||||
|
|
||||||
|
await Future.delayed(Duration.zero);
|
||||||
|
|
||||||
if (wallet.type == WalletType.monero ||
|
if (wallet.type == WalletType.monero ||
|
||||||
wallet.type == WalletType.wownero ||
|
wallet.type == WalletType.wownero ||
|
||||||
wallet.type == WalletType.bitcoin ||
|
wallet.type == WalletType.bitcoin ||
|
||||||
|
|
|
@ -291,32 +291,34 @@ class _DashboardPageView extends BasePage {
|
||||||
children: MainActions.all
|
children: MainActions.all
|
||||||
.where((element) => element.canShow?.call(dashboardViewModel) ?? true)
|
.where((element) => element.canShow?.call(dashboardViewModel) ?? true)
|
||||||
.map(
|
.map(
|
||||||
(action) => Semantics(
|
(action) => Expanded(
|
||||||
button: true,
|
child: Semantics(
|
||||||
enabled: (action.isEnabled?.call(dashboardViewModel) ?? true),
|
button: true,
|
||||||
child: ActionButton(
|
enabled: (action.isEnabled?.call(dashboardViewModel) ?? true),
|
||||||
key: ValueKey(
|
child: ActionButton(
|
||||||
'dashboard_page_${action.name(context)}_action_button_key'),
|
key: ValueKey(
|
||||||
image: Image.asset(
|
'dashboard_page_${action.name(context)}_action_button_key'),
|
||||||
action.image,
|
image: Image.asset(
|
||||||
height: 24,
|
action.image,
|
||||||
width: 24,
|
height: 24,
|
||||||
color: action.isEnabled?.call(dashboardViewModel) ?? true
|
width: 24,
|
||||||
? Theme.of(context)
|
color: action.isEnabled?.call(dashboardViewModel) ?? true
|
||||||
.extension<DashboardPageTheme>()!
|
? Theme.of(context)
|
||||||
.mainActionsIconColor
|
.extension<DashboardPageTheme>()!
|
||||||
|
.mainActionsIconColor
|
||||||
|
: Theme.of(context)
|
||||||
|
.extension<BalancePageTheme>()!
|
||||||
|
.labelTextColor,
|
||||||
|
),
|
||||||
|
title: action.name(context),
|
||||||
|
onClick: () async =>
|
||||||
|
await action.onTap(context, dashboardViewModel),
|
||||||
|
textColor: action.isEnabled?.call(dashboardViewModel) ?? true
|
||||||
|
? null
|
||||||
: Theme.of(context)
|
: Theme.of(context)
|
||||||
.extension<BalancePageTheme>()!
|
.extension<BalancePageTheme>()!
|
||||||
.labelTextColor,
|
.labelTextColor,
|
||||||
),
|
),
|
||||||
title: action.name(context),
|
|
||||||
onClick: () async =>
|
|
||||||
await action.onTap(context, dashboardViewModel),
|
|
||||||
textColor: action.isEnabled?.call(dashboardViewModel) ?? true
|
|
||||||
? null
|
|
||||||
: Theme.of(context)
|
|
||||||
.extension<BalancePageTheme>()!
|
|
||||||
.labelTextColor,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,91 +10,81 @@ import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
|
|
||||||
class CakeFeaturesPage extends StatelessWidget {
|
class CakeFeaturesPage extends StatelessWidget {
|
||||||
CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel});
|
CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel});
|
||||||
|
|
||||||
final DashboardViewModel dashboardViewModel;
|
final DashboardViewModel dashboardViewModel;
|
||||||
final CakeFeaturesViewModel cakeFeaturesViewModel;
|
final CakeFeaturesViewModel cakeFeaturesViewModel;
|
||||||
final _scrollController = ScrollController();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
child: RawScrollbar(
|
child: Padding(
|
||||||
thumbColor: Colors.white.withOpacity(0.15),
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
radius: Radius.circular(20),
|
child: Column(
|
||||||
thumbVisibility: true,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
thickness: 2,
|
children: [
|
||||||
controller: _scrollController,
|
SizedBox(height: 50),
|
||||||
child: Padding(
|
Text(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
'Cake ${S.of(context).features}',
|
||||||
child: Column(
|
style: TextStyle(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
fontSize: 24,
|
||||||
children: [
|
fontWeight: FontWeight.w500,
|
||||||
SizedBox(height: 50),
|
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
|
||||||
Text(
|
|
||||||
'Cake ${S.of(context).features}',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: ListView(
|
Expanded(
|
||||||
controller: _scrollController,
|
child: ListView(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
DashBoardRoundedCardWidget(
|
DashBoardRoundedCardWidget(
|
||||||
onTap: () => _navigatorToGiftCardsPage(context),
|
onTap: () => _navigatorToGiftCardsPage(context),
|
||||||
title: 'Cake Pay',
|
title: 'Cake Pay',
|
||||||
subTitle: S.of(context).cake_pay_subtitle,
|
subTitle: S.of(context).cake_pay_subtitle,
|
||||||
image: Image.asset(
|
image: Image.asset(
|
||||||
'assets/images/cards.png',
|
'assets/images/cards.png',
|
||||||
height: 100,
|
height: 100,
|
||||||
width: 115,
|
width: 115,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
),
|
||||||
DashBoardRoundedCardWidget(
|
SizedBox(height: 10),
|
||||||
onTap: () => _launchUrl("cake.nano-gpt.com"),
|
DashBoardRoundedCardWidget(
|
||||||
title: "NanoGPT",
|
onTap: () => _launchUrl("cake.nano-gpt.com"),
|
||||||
subTitle: S.of(context).nanogpt_subtitle,
|
title: "NanoGPT",
|
||||||
image: Image.asset(
|
subTitle: S.of(context).nanogpt_subtitle,
|
||||||
'assets/images/nanogpt.png',
|
image: Image.asset(
|
||||||
height: 80,
|
'assets/images/nanogpt.png',
|
||||||
width: 80,
|
height: 80,
|
||||||
fit: BoxFit.cover,
|
width: 80,
|
||||||
),
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
),
|
||||||
Observer(
|
SizedBox(height: 10),
|
||||||
builder: (context) {
|
Observer(
|
||||||
if (!dashboardViewModel.hasSignMessages) {
|
builder: (context) {
|
||||||
return const SizedBox();
|
if (!dashboardViewModel.hasSignMessages) {
|
||||||
}
|
return const SizedBox();
|
||||||
return DashBoardRoundedCardWidget(
|
}
|
||||||
onTap: () => Navigator.of(context).pushNamed(Routes.signPage),
|
return DashBoardRoundedCardWidget(
|
||||||
title: S.current.sign_verify_message,
|
onTap: () => Navigator.of(context).pushNamed(Routes.signPage),
|
||||||
subTitle: S.current.sign_verify_message_sub,
|
title: S.current.sign_verify_message,
|
||||||
icon: Icon(
|
subTitle: S.current.sign_verify_message_sub,
|
||||||
Icons.speaker_notes_rounded,
|
icon: Icon(
|
||||||
color:
|
Icons.speaker_notes_rounded,
|
||||||
Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
|
color:
|
||||||
size: 75,
|
Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
|
||||||
),
|
size: 75,
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
),
|
},
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,7 @@ class SyncIndicatorIcon extends StatelessWidget {
|
||||||
{this.boolMode = true,
|
{this.boolMode = true,
|
||||||
this.isSynced = false,
|
this.isSynced = false,
|
||||||
this.value = waiting,
|
this.value = waiting,
|
||||||
this.size = 4.0});
|
this.size = 6.0});
|
||||||
|
|
||||||
final bool boolMode;
|
final bool boolMode;
|
||||||
final bool isSynced;
|
final bool isSynced;
|
||||||
|
|
|
@ -191,11 +191,13 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
|
||||||
height = wownero!.getHeightByDate(date: date);
|
height = wownero!.getHeightByDate(date: date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setState(() {
|
if (mounted) {
|
||||||
dateController.text = DateFormat('yyyy-MM-dd').format(date);
|
setState(() {
|
||||||
restoreHeightController.text = '$height';
|
dateController.text = DateFormat('yyyy-MM-dd').format(date);
|
||||||
_changeHeight(height);
|
restoreHeightController.text = '$height';
|
||||||
});
|
_changeHeight(height);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,15 +92,17 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: Stack(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
body,
|
Expanded(child: body),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: MediaQuery.of(context).size.width / 8),
|
horizontal: MediaQuery.of(context).size.width / 8,
|
||||||
|
vertical: 20,
|
||||||
|
),
|
||||||
child: PrimaryImageButton(
|
child: PrimaryImageButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -50,8 +50,8 @@ abstract class AppStoreBase with Store {
|
||||||
getIt.get<Web3WalletService>().create();
|
getIt.get<Web3WalletService>().create();
|
||||||
await getIt.get<Web3WalletService>().init();
|
await getIt.get<Web3WalletService>().init();
|
||||||
}
|
}
|
||||||
await getIt.get<SharedPreferences>().setString(PreferencesKey.currentWalletName, wallet.name);
|
getIt.get<SharedPreferences>().setString(PreferencesKey.currentWalletName, wallet.name);
|
||||||
await getIt
|
getIt
|
||||||
.get<SharedPreferences>()
|
.get<SharedPreferences>()
|
||||||
.setInt(PreferencesKey.currentWalletType, serializeToInt(wallet.type));
|
.setInt(PreferencesKey.currentWalletType, serializeToInt(wallet.type));
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,11 @@ abstract class CakePayCardsListViewModelBase with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void setSelectedCountry(Country country) => settingsStore.selectedCakePayCountry = country;
|
void setSelectedCountry(Country country) {
|
||||||
|
// just so it triggers the reaction even when selecting the default country
|
||||||
|
settingsStore.selectedCakePayCountry = null;
|
||||||
|
settingsStore.selectedCakePayCountry = country;
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void togglePrepaidCards() => displayPrepaidCards = !displayPrepaidCards;
|
void togglePrepaidCards() => displayPrepaidCards = !displayPrepaidCards;
|
||||||
|
|
|
@ -159,7 +159,7 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||||
case WalletType.monero:
|
case WalletType.monero:
|
||||||
return 'https://monero.com/tx/${txId}';
|
return 'https://monero.com/tx/${txId}';
|
||||||
case WalletType.bitcoin:
|
case WalletType.bitcoin:
|
||||||
return 'https://mempool.space/${wallet.isTestnet ? "testnet/" : ""}tx/${txId}';
|
return 'https://mempool.cakewallet.com/${wallet.isTestnet ? "testnet/" : ""}tx/${txId}';
|
||||||
case WalletType.litecoin:
|
case WalletType.litecoin:
|
||||||
return 'https://blockchair.com/litecoin/transaction/${txId}';
|
return 'https://blockchair.com/litecoin/transaction/${txId}';
|
||||||
case WalletType.bitcoinCash:
|
case WalletType.bitcoinCash:
|
||||||
|
|
|
@ -26,7 +26,7 @@ dependencies:
|
||||||
share_plus: ^10.0.0
|
share_plus: ^10.0.0
|
||||||
# date_range_picker: ^1.0.6
|
# date_range_picker: ^1.0.6
|
||||||
#https://api.flutter.dev/flutter/material/showDateRangePicker.html
|
#https://api.flutter.dev/flutter/material/showDateRangePicker.html
|
||||||
dio: ^4.0.6
|
dio: ^5.7.0
|
||||||
hive: ^2.2.3
|
hive: ^2.2.3
|
||||||
hive_flutter: ^1.1.0
|
hive_flutter: ^1.1.0
|
||||||
local_auth_android: ^1.0.46
|
local_auth_android: ^1.0.46
|
||||||
|
|
|
@ -921,7 +921,7 @@
|
||||||
"wallet_seed_legacy": "Graine de portefeuille hérité",
|
"wallet_seed_legacy": "Graine de portefeuille hérité",
|
||||||
"wallet_store_monero_wallet": "Portefeuille (Wallet) Monero",
|
"wallet_store_monero_wallet": "Portefeuille (Wallet) Monero",
|
||||||
"walletConnect": "WalletConnect",
|
"walletConnect": "WalletConnect",
|
||||||
"wallets": "Portefeuilles (Wallets)",
|
"wallets": "Portefeuilles",
|
||||||
"warning": "Avertissement",
|
"warning": "Avertissement",
|
||||||
"welcome": "Bienvenue sur",
|
"welcome": "Bienvenue sur",
|
||||||
"welcome_to_cakepay": "Bienvenue sur Cake Pay !",
|
"welcome_to_cakepay": "Bienvenue sur Cake Pay !",
|
||||||
|
|
|
@ -7,9 +7,9 @@ fi
|
||||||
|
|
||||||
cd ../..
|
cd ../..
|
||||||
set -x
|
set -x
|
||||||
universal_sed "0,/version:/{s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/}" ./pubspec.yaml
|
universal_sed "1,/version:/ {s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/;}" ./pubspec.yaml
|
||||||
universal_sed "0,/version:/{s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/}" ./android/app/src/main/AndroidManifest.xml
|
universal_sed "1,/version:/ {s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/;}" ./android/app/src/main/AndroidManifest.xml
|
||||||
universal_sed "0,/__APP_SCHEME__/s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/" ./android/app/src/main/AndroidManifest.xml
|
universal_sed "1,/__APP_SCHEME__/ {s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/;}" ./android/app/src/main/AndroidManifest.xml
|
||||||
universal_sed "0,/version:/{s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/}" ./android/app/src/main/AndroidManifest.xml
|
universal_sed "1,/version:/ {s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/;}" ./android/app/src/main/AndroidManifest.xml
|
||||||
universal_sed "0,/version:/{s/__versionName__/${APP_ANDROID_VERSION}/}" ./android/app/src/main/AndroidManifest.xml
|
universal_sed "1,/version:/ {s/__versionName__/${APP_ANDROID_VERSION}/;}" ./android/app/src/main/AndroidManifest.xml
|
||||||
cd scripts/android
|
cd scripts/android
|
||||||
|
|
|
@ -43,7 +43,6 @@ case $APP_IOS_TYPE in
|
||||||
CONFIG_ARGS="--haven"
|
CONFIG_ARGS="--haven"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
CONFIG_ARGS="--monero --ethereum --polygon --nano --solana --tron --wownero"
|
|
||||||
|
|
||||||
cp -rf pubspec_description.yaml pubspec.yaml
|
cp -rf pubspec_description.yaml pubspec.yaml
|
||||||
flutter pub get
|
flutter pub get
|
||||||
|
|
|
@ -16,13 +16,13 @@ if [ -n "$1" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MONERO_COM_NAME="Monero.com"
|
MONERO_COM_NAME="Monero.com"
|
||||||
MONERO_COM_VERSION="1.8.0"
|
MONERO_COM_VERSION="1.8.1"
|
||||||
MONERO_COM_BUILD_NUMBER=36
|
MONERO_COM_BUILD_NUMBER=37
|
||||||
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
||||||
|
|
||||||
CAKEWALLET_NAME="Cake Wallet"
|
CAKEWALLET_NAME="Cake Wallet"
|
||||||
CAKEWALLET_VERSION="1.14.0"
|
CAKEWALLET_VERSION="1.14.1"
|
||||||
CAKEWALLET_BUILD_NUMBER=95
|
CAKEWALLET_BUILD_NUMBER=96
|
||||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||||
|
|
||||||
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
|
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
|
||||||
|
|
|
@ -13,7 +13,6 @@ universal_sed() {
|
||||||
local file=$2
|
local file=$2
|
||||||
|
|
||||||
if [[ "$SED_TYPE" == "GNU" ]]; then
|
if [[ "$SED_TYPE" == "GNU" ]]; then
|
||||||
pwd
|
|
||||||
sed -i "$expression" "$file"
|
sed -i "$expression" "$file"
|
||||||
else
|
else
|
||||||
sed -i '' "$expression" "$file"
|
sed -i '' "$expression" "$file"
|
||||||
|
|
Loading…
Reference in a new issue