mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
commit
c4a973e9c5
21 changed files with 427 additions and 236 deletions
|
@ -357,7 +357,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 19;
|
CURRENT_PROJECT_VERSION = 20;
|
||||||
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
@ -498,7 +498,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 19;
|
CURRENT_PROJECT_VERSION = 20;
|
||||||
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
@ -533,7 +533,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 19;
|
CURRENT_PROJECT_VERSION = 20;
|
||||||
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
DEVELOPMENT_TEAM = 32J6BB6VUS;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
|
||||||
|
|
||||||
class BitcoinTransactionCredentials {
|
class BitcoinTransactionCredentials {
|
||||||
BitcoinTransactionCredentials(this.address, this.amount, this.priority);
|
BitcoinTransactionCredentials(this.address, this.amount, this.priority);
|
||||||
|
|
||||||
final String address;
|
final String address;
|
||||||
final String amount;
|
final String amount;
|
||||||
TransactionPriority priority;
|
BitcoinTransactionPriority priority;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,12 @@ abstract class BitcoinTransactionHistoryBase
|
||||||
BitcoinTransactionInfo get(String id) => transactions[id];
|
BitcoinTransactionInfo get(String id) => transactions[id];
|
||||||
|
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
|
try {
|
||||||
final data = json.encode({'height': _height, 'transactions': transactions});
|
final data = json.encode({'height': _height, 'transactions': transactions});
|
||||||
await writeData(path: path, password: _password, data: data);
|
await writeData(path: path, password: _password, data: data);
|
||||||
|
} catch(e) {
|
||||||
|
print('Error while save bitcoin transaction history: ${e.toString()}');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -170,6 +174,10 @@ abstract class BitcoinTransactionHistoryBase
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateOrInsert(BitcoinTransactionInfo transaction) {
|
void _updateOrInsert(BitcoinTransactionInfo transaction) {
|
||||||
|
if (transaction.id == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (transactions[transaction.id] == null) {
|
if (transactions[transaction.id] == null) {
|
||||||
transactions[transaction.id] = transaction;
|
transactions[transaction.id] = transaction;
|
||||||
} else {
|
} else {
|
||||||
|
|
29
lib/bitcoin/bitcoin_transaction_priority.dart
Normal file
29
lib/bitcoin/bitcoin_transaction_priority.dart
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
|
|
||||||
|
class BitcoinTransactionPriority extends TransactionPriority {
|
||||||
|
const BitcoinTransactionPriority(this.rate, {String title, int raw})
|
||||||
|
: super(title: title, raw: raw);
|
||||||
|
|
||||||
|
static const List<BitcoinTransactionPriority> all = [slow, medium, fast];
|
||||||
|
static const BitcoinTransactionPriority slow = BitcoinTransactionPriority(11, title: 'Slow', raw: 0);
|
||||||
|
static const BitcoinTransactionPriority medium = BitcoinTransactionPriority(90, title: 'Medium', raw: 1);
|
||||||
|
static const BitcoinTransactionPriority fast = BitcoinTransactionPriority(98, title: 'Fast', raw: 2);
|
||||||
|
|
||||||
|
static BitcoinTransactionPriority deserialize({int raw}) {
|
||||||
|
switch (raw) {
|
||||||
|
case 0:
|
||||||
|
return slow;
|
||||||
|
case 2:
|
||||||
|
return medium;
|
||||||
|
case 3:
|
||||||
|
return fast;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int rate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => '$rate sat/byte';
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:cake_wallet/bitcoin/address_to_output_script.dart';
|
import 'package:cake_wallet/bitcoin/address_to_output_script.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_mnemonic.dart';
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
@ -17,7 +19,6 @@ import 'package:cake_wallet/bitcoin/script_hash.dart';
|
||||||
import 'package:cake_wallet/bitcoin/utils.dart';
|
import 'package:cake_wallet/bitcoin/utils.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
|
||||||
import 'package:cake_wallet/entities/sync_status.dart';
|
import 'package:cake_wallet/entities/sync_status.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
|
||||||
import 'package:cake_wallet/entities/wallet_info.dart';
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_transaction_history.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_history.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
|
||||||
|
@ -53,6 +54,7 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
_password = password,
|
_password = password,
|
||||||
_accountIndex = accountIndex,
|
_accountIndex = accountIndex,
|
||||||
super(walletInfo) {
|
super(walletInfo) {
|
||||||
|
_unspent = [];
|
||||||
_scripthashesUpdateSubject = {};
|
_scripthashesUpdateSubject = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,18 +118,12 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
walletInfo: walletInfo);
|
walletInfo: walletInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int feeAmountForPriority(TransactionPriority priority) {
|
static int feeAmountForPriority(BitcoinTransactionPriority priority,
|
||||||
switch (priority) {
|
int inputsCount, int outputsCount) =>
|
||||||
case TransactionPriority.slow:
|
priority.rate * estimatedTransactionSize(inputsCount, outputsCount);
|
||||||
return 6000;
|
|
||||||
case TransactionPriority.regular:
|
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
||||||
return 22080;
|
inputsCount * 146 + outputsCounts * 33 + 8;
|
||||||
case TransactionPriority.fast:
|
|
||||||
return 24000;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final BitcoinTransactionHistory transactionHistory;
|
final BitcoinTransactionHistory transactionHistory;
|
||||||
|
@ -136,6 +132,8 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
final ElectrumClient eclient;
|
final ElectrumClient eclient;
|
||||||
final String mnemonic;
|
final String mnemonic;
|
||||||
|
|
||||||
|
List<BitcoinUnspent> _unspent;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@observable
|
@observable
|
||||||
String address;
|
String address;
|
||||||
|
@ -234,6 +232,7 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
});
|
});
|
||||||
_subscribeForUpdates();
|
_subscribeForUpdates();
|
||||||
await _updateBalance();
|
await _updateBalance();
|
||||||
|
await _updateUnspent();
|
||||||
syncStatus = SyncedSyncStatus();
|
syncStatus = SyncedSyncStatus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
|
@ -264,29 +263,22 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
Object credentials) async {
|
Object credentials) async {
|
||||||
final transactionCredentials = credentials as BitcoinTransactionCredentials;
|
final transactionCredentials = credentials as BitcoinTransactionCredentials;
|
||||||
final inputs = <BitcoinUnspent>[];
|
final inputs = <BitcoinUnspent>[];
|
||||||
final fee = feeAmountForPriority(transactionCredentials.priority);
|
final allAmountFee =
|
||||||
|
calculateEstimatedFee(transactionCredentials.priority, null);
|
||||||
|
var fee = 0;
|
||||||
final amount = transactionCredentials.amount != null
|
final amount = transactionCredentials.amount != null
|
||||||
? stringDoubleToBitcoinAmount(transactionCredentials.amount)
|
? stringDoubleToBitcoinAmount(transactionCredentials.amount)
|
||||||
: balance.confirmed - fee;
|
: balance.confirmed - allAmountFee;
|
||||||
final totalAmount = amount + fee;
|
|
||||||
final txb = bitcoin.TransactionBuilder(network: bitcoin.bitcoin);
|
final txb = bitcoin.TransactionBuilder(network: bitcoin.bitcoin);
|
||||||
final changeAddress = address;
|
final changeAddress = address;
|
||||||
var leftAmount = totalAmount;
|
var leftAmount = amount;
|
||||||
var totalInputAmount = 0;
|
var totalInputAmount = 0;
|
||||||
|
|
||||||
if (totalAmount > balance.confirmed) {
|
if (_unspent.isEmpty) {
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
await _updateUnspent();
|
||||||
}
|
}
|
||||||
|
|
||||||
final unspent = addresses.map((address) => eclient
|
for (final utx in _unspent) {
|
||||||
.getListUnspentWithAddress(address.address)
|
|
||||||
.then((unspent) => unspent
|
|
||||||
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent))));
|
|
||||||
|
|
||||||
for (final unptsFutures in unspent) {
|
|
||||||
final utxs = await unptsFutures;
|
|
||||||
|
|
||||||
for (final utx in utxs) {
|
|
||||||
leftAmount = leftAmount - utx.value;
|
leftAmount = leftAmount - utx.value;
|
||||||
totalInputAmount += utx.value;
|
totalInputAmount += utx.value;
|
||||||
inputs.add(utx);
|
inputs.add(utx);
|
||||||
|
@ -296,20 +288,23 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftAmount <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputs.isEmpty) {
|
if (inputs.isEmpty) {
|
||||||
throw BitcoinTransactionNoInputsException();
|
throw BitcoinTransactionNoInputsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amount <= 0 || totalInputAmount < amount) {
|
final totalAmount = amount + fee;
|
||||||
|
fee = transactionCredentials.amount != null
|
||||||
|
? feeAmountForPriority(
|
||||||
|
transactionCredentials.priority, inputs.length, 2)
|
||||||
|
: allAmountFee;
|
||||||
|
|
||||||
|
if (totalAmount > balance.confirmed) {
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
throw BitcoinTransactionWrongBalanceException();
|
||||||
}
|
}
|
||||||
|
|
||||||
final changeValue = totalInputAmount - amount - fee;
|
if (amount <= 0 || totalInputAmount < amount) {
|
||||||
|
throw BitcoinTransactionWrongBalanceException();
|
||||||
|
}
|
||||||
|
|
||||||
txb.setVersion(1);
|
txb.setVersion(1);
|
||||||
|
|
||||||
|
@ -330,6 +325,10 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
txb.addOutput(
|
txb.addOutput(
|
||||||
addressToOutputScript(transactionCredentials.address), amount);
|
addressToOutputScript(transactionCredentials.address), amount);
|
||||||
|
|
||||||
|
final estimatedSize = estimatedTransactionSize(inputs.length, 2);
|
||||||
|
final feeAmount = transactionCredentials.priority.rate * estimatedSize;
|
||||||
|
final changeValue = totalInputAmount - amount - feeAmount;
|
||||||
|
|
||||||
if (changeValue > 0) {
|
if (changeValue > 0) {
|
||||||
txb.addOutput(changeAddress, changeValue);
|
txb.addOutput(changeAddress, changeValue);
|
||||||
}
|
}
|
||||||
|
@ -358,8 +357,30 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
double calculateEstimatedFee(TransactionPriority priority) =>
|
int calculateEstimatedFee(TransactionPriority priority, int amount) {
|
||||||
bitcoinAmountToDouble(amount: feeAmountForPriority(priority));
|
if (priority is BitcoinTransactionPriority) {
|
||||||
|
int inputsCount = 0;
|
||||||
|
|
||||||
|
if (amount != null) {
|
||||||
|
int totalValue = 0;
|
||||||
|
|
||||||
|
for (final input in _unspent) {
|
||||||
|
if (totalValue >= amount) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalValue += input.value;
|
||||||
|
inputsCount += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inputsCount = _unspent.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return feeAmountForPriority(priority, inputsCount, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
|
@ -380,13 +401,26 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
|
||||||
await eclient.close();
|
await eclient.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _updateUnspent() async {
|
||||||
|
final unspent = await Future.wait(addresses.map((address) => eclient
|
||||||
|
.getListUnspentWithAddress(address.address)
|
||||||
|
.then((unspent) => unspent
|
||||||
|
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent)))));
|
||||||
|
_unspent = unspent.expand((e) => e).toList();
|
||||||
|
}
|
||||||
|
|
||||||
void _subscribeForUpdates() {
|
void _subscribeForUpdates() {
|
||||||
scriptHashes.forEach((sh) async {
|
scriptHashes.forEach((sh) async {
|
||||||
await _scripthashesUpdateSubject[sh]?.close();
|
await _scripthashesUpdateSubject[sh]?.close();
|
||||||
_scripthashesUpdateSubject[sh] = eclient.scripthashUpdate(sh);
|
_scripthashesUpdateSubject[sh] = eclient.scripthashUpdate(sh);
|
||||||
_scripthashesUpdateSubject[sh].listen((event) async {
|
_scripthashesUpdateSubject[sh].listen((event) async {
|
||||||
|
try {
|
||||||
await _updateBalance();
|
await _updateBalance();
|
||||||
|
await _updateUnspent();
|
||||||
transactionHistory.updateAsync();
|
transactionHistory.updateAsync();
|
||||||
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ String jsonrpcparams(List<Object> params) {
|
||||||
|
|
||||||
String jsonrpc(
|
String jsonrpc(
|
||||||
{String method, List<Object> params, int id, double version = 2.0}) =>
|
{String method, List<Object> params, int id, double version = 2.0}) =>
|
||||||
'{"jsonrpc": "$version", "method": "$method", "id": "$id", "params": ${json.encode(params)}}\n';
|
'{"jsonrpc": "$version", "method": "$method", "id": "$id", "params": ${json
|
||||||
|
.encode(params)}}\n';
|
||||||
|
|
||||||
class SocketTask {
|
class SocketTask {
|
||||||
SocketTask({this.completer, this.isSubscription, this.subject});
|
SocketTask({this.completer, this.isSubscription, this.subject});
|
||||||
|
@ -294,8 +295,7 @@ class ElectrumClient {
|
||||||
params: [scripthash]);
|
params: [scripthash]);
|
||||||
}
|
}
|
||||||
|
|
||||||
BehaviorSubject<T> subscribe<T>(
|
BehaviorSubject<T> subscribe<T>({@required String id,
|
||||||
{@required String id,
|
|
||||||
@required String method,
|
@required String method,
|
||||||
List<Object> params = const []}) {
|
List<Object> params = const []}) {
|
||||||
final subscription = BehaviorSubject<T>();
|
final subscription = BehaviorSubject<T>();
|
||||||
|
@ -306,38 +306,31 @@ class ElectrumClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> call({String method, List<Object> params = const []}) async {
|
Future<dynamic> call({String method, List<Object> params = const []}) async {
|
||||||
await Future<void>.delayed(Duration(milliseconds: 100));
|
|
||||||
final completer = Completer<dynamic>();
|
final completer = Completer<dynamic>();
|
||||||
_id += 1;
|
_id += 1;
|
||||||
final id = _id;
|
final id = _id;
|
||||||
_regisryTask(id, completer);
|
_registryTask(id, completer);
|
||||||
socket.write(jsonrpc(method: method, id: _id, params: params));
|
socket.write(jsonrpc(method: method, id: id, params: params));
|
||||||
|
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> callWithTimeout(
|
Future<dynamic> callWithTimeout({String method,
|
||||||
{String method,
|
|
||||||
List<Object> params = const [],
|
List<Object> params = const [],
|
||||||
int timeout = 2000}) async {
|
int timeout = 2000}) async {
|
||||||
final completer = Completer<dynamic>();
|
final completer = Completer<dynamic>();
|
||||||
_id += 1;
|
_id += 1;
|
||||||
final id = _id;
|
final id = _id;
|
||||||
_regisryTask(id, completer);
|
_registryTask(id, completer);
|
||||||
socket.write(jsonrpc(method: method, id: _id, params: params));
|
socket.write(jsonrpc(method: method, id: id, params: params));
|
||||||
|
|
||||||
Timer(Duration(milliseconds: timeout), () {
|
Timer(Duration(milliseconds: timeout), () {
|
||||||
if (!completer.isCompleted) {
|
if (!completer.isCompleted) {
|
||||||
completer.completeError(RequestFailedTimeoutException(method, _id));
|
completer.completeError(RequestFailedTimeoutException(method, id));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return completer.future;
|
|
||||||
}
|
|
||||||
|
|
||||||
void request({String method, List<Object> params = const []}) {
|
return completer.future;
|
||||||
_id += 1;
|
|
||||||
socket.write(jsonrpc(method: method, id: _id, params: params));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
@ -346,7 +339,8 @@ class ElectrumClient {
|
||||||
onConnectionStatusChange = null;
|
onConnectionStatusChange = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _regisryTask(int id, Completer completer) => _tasks[id.toString()] =
|
void _registryTask(int id, Completer completer) =>
|
||||||
|
_tasks[id.toString()] =
|
||||||
SocketTask(completer: completer, isSubscription: false);
|
SocketTask(completer: completer, isSubscription: false);
|
||||||
|
|
||||||
void _regisrySubscription(String id, BehaviorSubject subject) =>
|
void _regisrySubscription(String id, BehaviorSubject subject) =>
|
||||||
|
|
|
@ -149,8 +149,8 @@ class BackupService {
|
||||||
PreferencesKey.shouldSaveRecipientAddressKey,
|
PreferencesKey.shouldSaveRecipientAddressKey,
|
||||||
data[PreferencesKey.shouldSaveRecipientAddressKey] as bool);
|
data[PreferencesKey.shouldSaveRecipientAddressKey] as bool);
|
||||||
await _sharedPreferences.setInt(
|
await _sharedPreferences.setInt(
|
||||||
PreferencesKey.currentTransactionPriorityKey,
|
PreferencesKey.currentTransactionPriorityKeyLegacy,
|
||||||
data[PreferencesKey.currentTransactionPriorityKey] as int);
|
data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int);
|
||||||
await _sharedPreferences.setBool(
|
await _sharedPreferences.setBool(
|
||||||
PreferencesKey.allowBiometricalAuthenticationKey,
|
PreferencesKey.allowBiometricalAuthenticationKey,
|
||||||
data[PreferencesKey.allowBiometricalAuthenticationKey] as bool);
|
data[PreferencesKey.allowBiometricalAuthenticationKey] as bool);
|
||||||
|
@ -257,8 +257,8 @@ class BackupService {
|
||||||
_sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy),
|
_sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy),
|
||||||
PreferencesKey.currentPinLength:
|
PreferencesKey.currentPinLength:
|
||||||
_sharedPreferences.getInt(PreferencesKey.currentPinLength),
|
_sharedPreferences.getInt(PreferencesKey.currentPinLength),
|
||||||
PreferencesKey.currentTransactionPriorityKey: _sharedPreferences
|
PreferencesKey.currentTransactionPriorityKeyLegacy: _sharedPreferences
|
||||||
.getInt(PreferencesKey.currentTransactionPriorityKey),
|
.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
|
||||||
PreferencesKey.allowBiometricalAuthenticationKey: _sharedPreferences
|
PreferencesKey.allowBiometricalAuthenticationKey: _sharedPreferences
|
||||||
.getBool(PreferencesKey.allowBiometricalAuthenticationKey),
|
.getBool(PreferencesKey.allowBiometricalAuthenticationKey),
|
||||||
PreferencesKey.currentBitcoinElectrumSererIdKey: _sharedPreferences
|
PreferencesKey.currentBitcoinElectrumSererIdKey: _sharedPreferences
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import 'package:cake_wallet/entities/balance.dart';
|
import 'package:cake_wallet/entities/balance.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_info.dart';
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
import 'package:cake_wallet/core/pending_transaction.dart';
|
import 'package:cake_wallet/core/pending_transaction.dart';
|
||||||
import 'package:cake_wallet/core/transaction_history.dart';
|
import 'package:cake_wallet/core/transaction_history.dart';
|
||||||
import 'package:cake_wallet/entities/currency_for_wallet_type.dart';
|
import 'package:cake_wallet/entities/currency_for_wallet_type.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
import 'package:cake_wallet/entities/sync_status.dart';
|
import 'package:cake_wallet/entities/sync_status.dart';
|
||||||
import 'package:cake_wallet/entities/node.dart';
|
import 'package:cake_wallet/entities/node.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
|
|
||||||
abstract class WalletBase<BalaceType extends Balance> {
|
abstract class WalletBase<BalanceType extends Balance> {
|
||||||
WalletBase(this.walletInfo);
|
WalletBase(this.walletInfo);
|
||||||
|
|
||||||
static String idFor(String name, WalletType type) =>
|
static String idFor(String name, WalletType type) =>
|
||||||
|
@ -30,7 +31,7 @@ abstract class WalletBase<BalaceType extends Balance> {
|
||||||
|
|
||||||
set address(String address);
|
set address(String address);
|
||||||
|
|
||||||
BalaceType get balance;
|
BalanceType get balance;
|
||||||
|
|
||||||
SyncStatus get syncStatus;
|
SyncStatus get syncStatus;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ abstract class WalletBase<BalaceType extends Balance> {
|
||||||
|
|
||||||
Future<PendingTransaction> createTransaction(Object credentials);
|
Future<PendingTransaction> createTransaction(Object credentials);
|
||||||
|
|
||||||
double calculateEstimatedFee(TransactionPriority priority);
|
int calculateEstimatedFee(TransactionPriority priority, int amount);
|
||||||
|
|
||||||
Future<void> save();
|
Future<void> save();
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
|
|
||||||
double calculateEstimatedFee({TransactionPriority priority}) {
|
double calculateEstimatedFee({MoneroTransactionPriority priority}) {
|
||||||
if (priority == TransactionPriority.slow) {
|
if (priority == MoneroTransactionPriority.slow) {
|
||||||
return 0.00002459;
|
return 0.00002459;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority == TransactionPriority.regular) {
|
if (priority == MoneroTransactionPriority.regular) {
|
||||||
return 0.00012305;
|
return 0.00012305;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority == TransactionPriority.medium) {
|
if (priority == MoneroTransactionPriority.medium) {
|
||||||
return 0.00024503;
|
return 0.00024503;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority == TransactionPriority.fast) {
|
if (priority == MoneroTransactionPriority.fast) {
|
||||||
return 0.00061453;
|
return 0.00061453;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority == TransactionPriority.fastest) {
|
if (priority == MoneroTransactionPriority.fastest) {
|
||||||
return 0.0260216;
|
return 0.0260216;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:io' show File, Platform;
|
import 'dart:io' show File, Platform;
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/core/generate_wallet_password.dart';
|
import 'package:cake_wallet/core/generate_wallet_password.dart';
|
||||||
import 'package:cake_wallet/core/key_service.dart';
|
import 'package:cake_wallet/core/key_service.dart';
|
||||||
import 'package:cake_wallet/di.dart';
|
import 'package:cake_wallet/di.dart';
|
||||||
|
@ -15,7 +16,7 @@ import 'package:cake_wallet/entities/node.dart';
|
||||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||||
import 'package:cake_wallet/entities/node_list.dart';
|
import 'package:cake_wallet/entities/node_list.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/contact.dart';
|
import 'package:cake_wallet/entities/contact.dart';
|
||||||
import 'package:cake_wallet/entities/fs_migration.dart';
|
import 'package:cake_wallet/entities/fs_migration.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_info.dart';
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
|
@ -53,8 +54,8 @@ Future defaultSettingsMigration(
|
||||||
PreferencesKey.currentFiatCurrencyKey,
|
PreferencesKey.currentFiatCurrencyKey,
|
||||||
FiatCurrency.usd.toString());
|
FiatCurrency.usd.toString());
|
||||||
await sharedPreferences.setInt(
|
await sharedPreferences.setInt(
|
||||||
PreferencesKey.currentTransactionPriorityKey,
|
PreferencesKey.currentTransactionPriorityKeyLegacy,
|
||||||
TransactionPriority.standard.raw);
|
MoneroTransactionPriority.standard.raw);
|
||||||
await sharedPreferences.setInt(
|
await sharedPreferences.setInt(
|
||||||
PreferencesKey.currentBalanceDisplayModeKey,
|
PreferencesKey.currentBalanceDisplayModeKey,
|
||||||
BalanceDisplayMode.availableBalance.raw);
|
BalanceDisplayMode.availableBalance.raw);
|
||||||
|
@ -93,6 +94,13 @@ Future defaultSettingsMigration(
|
||||||
case 9:
|
case 9:
|
||||||
await generateBackupPassword(secureStorage);
|
await generateBackupPassword(secureStorage);
|
||||||
break;
|
break;
|
||||||
|
case 10:
|
||||||
|
await changeTransactionPriorityAndFeeRateKeys(sharedPreferences);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11:
|
||||||
|
await changeDefaultMoneroNode(nodes, sharedPreferences);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -253,3 +261,36 @@ Future<void> generateBackupPassword(FlutterSecureStorage secureStorage) async {
|
||||||
final password = encrypt.Key.fromSecureRandom(32).base16;
|
final password = encrypt.Key.fromSecureRandom(32).base16;
|
||||||
await secureStorage.write(key: key, value: password);
|
await secureStorage.write(key: key, value: password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> changeTransactionPriorityAndFeeRateKeys(
|
||||||
|
SharedPreferences sharedPreferences) async {
|
||||||
|
final legacyTransactionPriority = sharedPreferences
|
||||||
|
.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy);
|
||||||
|
await sharedPreferences.setInt(
|
||||||
|
PreferencesKey.moneroTransactionPriority, legacyTransactionPriority);
|
||||||
|
await sharedPreferences.setInt(PreferencesKey.bitcoinTransactionPriority,
|
||||||
|
BitcoinTransactionPriority.medium.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> changeDefaultMoneroNode(
|
||||||
|
Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
|
||||||
|
const cakeWalletMoneroNodeUriPattern = '.cakewallet.com';
|
||||||
|
const newCakeWalletMoneroUri = 'xmr-node.cakewallet.com:18081';
|
||||||
|
final currentMoneroNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
|
||||||
|
final currentMoneroNode = nodeSource.values.firstWhere((node) => node.key == currentMoneroNodeId);
|
||||||
|
final needToReplaceCurrentMoneroNode = currentMoneroNode.uri.contains(cakeWalletMoneroNodeUriPattern);
|
||||||
|
|
||||||
|
nodeSource.values.forEach((node) async {
|
||||||
|
if (node.type == WalletType.monero && node.uri.contains(cakeWalletMoneroNodeUriPattern)) {
|
||||||
|
await node.delete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero);
|
||||||
|
|
||||||
|
await nodeSource.add(newCakeWalletNode);
|
||||||
|
|
||||||
|
if (needToReplaceCurrentMoneroNode) {
|
||||||
|
await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, newCakeWalletNode.key as int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
74
lib/entities/monero_transaction_priority.dart
Normal file
74
lib/entities/monero_transaction_priority.dart
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/entities/enumerable_item.dart';
|
||||||
|
|
||||||
|
class MoneroTransactionPriority extends TransactionPriority {
|
||||||
|
const MoneroTransactionPriority({String title, int raw})
|
||||||
|
: super(title: title, raw: raw);
|
||||||
|
|
||||||
|
static const all = [
|
||||||
|
MoneroTransactionPriority.slow,
|
||||||
|
MoneroTransactionPriority.regular,
|
||||||
|
MoneroTransactionPriority.medium,
|
||||||
|
MoneroTransactionPriority.fast,
|
||||||
|
MoneroTransactionPriority.fastest
|
||||||
|
];
|
||||||
|
static const slow = MoneroTransactionPriority(title: 'Slow', raw: 0);
|
||||||
|
static const regular = MoneroTransactionPriority(title: 'Regular', raw: 1);
|
||||||
|
static const medium = MoneroTransactionPriority(title: 'Medium', raw: 2);
|
||||||
|
static const fast = MoneroTransactionPriority(title: 'Fast', raw: 3);
|
||||||
|
static const fastest = MoneroTransactionPriority(title: 'Fastest', raw: 4);
|
||||||
|
static const standard = slow;
|
||||||
|
|
||||||
|
|
||||||
|
static List<MoneroTransactionPriority> forWalletType(WalletType type) {
|
||||||
|
switch (type) {
|
||||||
|
case WalletType.monero:
|
||||||
|
return MoneroTransactionPriority.all;
|
||||||
|
case WalletType.bitcoin:
|
||||||
|
return [
|
||||||
|
MoneroTransactionPriority.slow,
|
||||||
|
MoneroTransactionPriority.regular,
|
||||||
|
MoneroTransactionPriority.fast
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MoneroTransactionPriority deserialize({int raw}) {
|
||||||
|
switch (raw) {
|
||||||
|
case 0:
|
||||||
|
return slow;
|
||||||
|
case 1:
|
||||||
|
return regular;
|
||||||
|
case 2:
|
||||||
|
return medium;
|
||||||
|
case 3:
|
||||||
|
return fast;
|
||||||
|
case 4:
|
||||||
|
return fastest;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
switch (this) {
|
||||||
|
case MoneroTransactionPriority.slow:
|
||||||
|
return S.current.transaction_priority_slow;
|
||||||
|
case MoneroTransactionPriority.regular:
|
||||||
|
return S.current.transaction_priority_regular;
|
||||||
|
case MoneroTransactionPriority.medium:
|
||||||
|
return S.current.transaction_priority_medium;
|
||||||
|
case MoneroTransactionPriority.fast:
|
||||||
|
return S.current.transaction_priority_fast;
|
||||||
|
case MoneroTransactionPriority.fastest:
|
||||||
|
return S.current.transaction_priority_fastest;
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ class PreferencesKey {
|
||||||
static const currentNodeIdKey = 'current_node_id';
|
static const currentNodeIdKey = 'current_node_id';
|
||||||
static const currentBitcoinElectrumSererIdKey = 'current_node_id_btc';
|
static const currentBitcoinElectrumSererIdKey = 'current_node_id_btc';
|
||||||
static const currentFiatCurrencyKey = 'current_fiat_currency';
|
static const currentFiatCurrencyKey = 'current_fiat_currency';
|
||||||
static const currentTransactionPriorityKey = 'current_fee_priority';
|
static const currentTransactionPriorityKeyLegacy = 'current_fee_priority';
|
||||||
static const currentBalanceDisplayModeKey = 'current_balance_display_mode';
|
static const currentBalanceDisplayModeKey = 'current_balance_display_mode';
|
||||||
static const shouldSaveRecipientAddressKey = 'save_recipient_address';
|
static const shouldSaveRecipientAddressKey = 'save_recipient_address';
|
||||||
static const allowBiometricalAuthenticationKey =
|
static const allowBiometricalAuthenticationKey =
|
||||||
|
@ -15,4 +15,6 @@ class PreferencesKey {
|
||||||
static const currentPinLength = 'current_pin_length';
|
static const currentPinLength = 'current_pin_length';
|
||||||
static const currentLanguageCode = 'language_code';
|
static const currentLanguageCode = 'language_code';
|
||||||
static const currentDefaultSettingsMigrationVersion = 'current_default_settings_migration_version';
|
static const currentDefaultSettingsMigrationVersion = 'current_default_settings_migration_version';
|
||||||
|
static const moneroTransactionPriority = 'current_fee_priority_monero';
|
||||||
|
static const bitcoinTransactionPriority = 'current_fee_priority_bitcoin';
|
||||||
}
|
}
|
|
@ -1,73 +1,6 @@
|
||||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
|
||||||
import 'package:cake_wallet/entities/enumerable_item.dart';
|
import 'package:cake_wallet/entities/enumerable_item.dart';
|
||||||
|
|
||||||
class TransactionPriority extends EnumerableItem<int> with Serializable<int> {
|
abstract class TransactionPriority extends EnumerableItem<int>
|
||||||
const TransactionPriority({String title, int raw})
|
with Serializable<int> {
|
||||||
: super(title: title, raw: raw);
|
const TransactionPriority({String title, int raw}) : super(title: title, raw: raw);
|
||||||
|
|
||||||
static const all = [
|
|
||||||
TransactionPriority.slow,
|
|
||||||
TransactionPriority.regular,
|
|
||||||
TransactionPriority.medium,
|
|
||||||
TransactionPriority.fast,
|
|
||||||
TransactionPriority.fastest
|
|
||||||
];
|
|
||||||
static const slow = TransactionPriority(title: 'Slow', raw: 0);
|
|
||||||
static const regular = TransactionPriority(title: 'Regular', raw: 1);
|
|
||||||
static const medium = TransactionPriority(title: 'Medium', raw: 2);
|
|
||||||
static const fast = TransactionPriority(title: 'Fast', raw: 3);
|
|
||||||
static const fastest = TransactionPriority(title: 'Fastest', raw: 4);
|
|
||||||
static const standard = slow;
|
|
||||||
|
|
||||||
|
|
||||||
static List<TransactionPriority> forWalletType(WalletType type) {
|
|
||||||
switch (type) {
|
|
||||||
case WalletType.monero:
|
|
||||||
return TransactionPriority.all;
|
|
||||||
case WalletType.bitcoin:
|
|
||||||
return [
|
|
||||||
TransactionPriority.slow,
|
|
||||||
TransactionPriority.regular,
|
|
||||||
TransactionPriority.fast
|
|
||||||
];
|
|
||||||
default:
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static TransactionPriority deserialize({int raw}) {
|
|
||||||
switch (raw) {
|
|
||||||
case 0:
|
|
||||||
return slow;
|
|
||||||
case 1:
|
|
||||||
return regular;
|
|
||||||
case 2:
|
|
||||||
return medium;
|
|
||||||
case 3:
|
|
||||||
return fast;
|
|
||||||
case 4:
|
|
||||||
return fastest;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
switch (this) {
|
|
||||||
case TransactionPriority.slow:
|
|
||||||
return S.current.transaction_priority_slow;
|
|
||||||
case TransactionPriority.regular:
|
|
||||||
return S.current.transaction_priority_regular;
|
|
||||||
case TransactionPriority.medium:
|
|
||||||
return S.current.transaction_priority_medium;
|
|
||||||
case TransactionPriority.fast:
|
|
||||||
return S.current.transaction_priority_fast;
|
|
||||||
case TransactionPriority.fastest:
|
|
||||||
return S.current.transaction_priority_fastest;
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ Future<void> main() async {
|
||||||
exchangeTemplates: exchangeTemplates,
|
exchangeTemplates: exchangeTemplates,
|
||||||
transactionDescriptions: transactionDescriptions,
|
transactionDescriptions: transactionDescriptions,
|
||||||
secureStorage: secureStorage,
|
secureStorage: secureStorage,
|
||||||
initialMigrationVersion: 9);
|
initialMigrationVersion: 11);
|
||||||
runApp(App());
|
runApp(App());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
runApp(MaterialApp(
|
runApp(MaterialApp(
|
||||||
|
@ -123,7 +123,7 @@ Future<void> initialSetup(
|
||||||
@required Box<ExchangeTemplate> exchangeTemplates,
|
@required Box<ExchangeTemplate> exchangeTemplates,
|
||||||
@required Box<TransactionDescription> transactionDescriptions,
|
@required Box<TransactionDescription> transactionDescriptions,
|
||||||
FlutterSecureStorage secureStorage,
|
FlutterSecureStorage secureStorage,
|
||||||
int initialMigrationVersion = 9}) async {
|
int initialMigrationVersion = 11}) async {
|
||||||
await defaultSettingsMigration(
|
await defaultSettingsMigration(
|
||||||
secureStorage: secureStorage,
|
secureStorage: secureStorage,
|
||||||
version: initialMigrationVersion,
|
version: initialMigrationVersion,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:cake_wallet/entities/transaction_creation_credentials.dart';
|
import 'package:cake_wallet/entities/transaction_creation_credentials.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
|
|
||||||
class MoneroTransactionCreationCredentials
|
class MoneroTransactionCreationCredentials
|
||||||
extends TransactionCreationCredentials {
|
extends TransactionCreationCredentials {
|
||||||
|
@ -9,5 +9,5 @@ class MoneroTransactionCreationCredentials
|
||||||
final String address;
|
final String address;
|
||||||
final String paymentId;
|
final String paymentId;
|
||||||
final String amount;
|
final String amount;
|
||||||
final TransactionPriority priority;
|
final MoneroTransactionPriority priority;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:cake_wallet/monero/monero_amount_format.dart';
|
import 'package:cake_wallet/monero/monero_amount_format.dart';
|
||||||
import 'package:cake_wallet/monero/monero_transaction_creation_exception.dart';
|
import 'package:cake_wallet/monero/monero_transaction_creation_exception.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -21,7 +22,7 @@ import 'package:cake_wallet/core/wallet_base.dart';
|
||||||
import 'package:cake_wallet/entities/sync_status.dart';
|
import 'package:cake_wallet/entities/sync_status.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_info.dart';
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
import 'package:cake_wallet/entities/node.dart';
|
import 'package:cake_wallet/entities/node.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
|
|
||||||
part 'monero_wallet.g.dart';
|
part 'monero_wallet.g.dart';
|
||||||
|
|
||||||
|
@ -212,27 +213,22 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
double calculateEstimatedFee(TransactionPriority priority) {
|
int calculateEstimatedFee(TransactionPriority priority, int amount) {
|
||||||
// FIXME: hardcoded value;
|
// FIXME: hardcoded value;
|
||||||
|
|
||||||
if (priority == TransactionPriority.slow) {
|
if (priority is MoneroTransactionPriority) {
|
||||||
return 0.00002459;
|
switch (priority) {
|
||||||
|
case MoneroTransactionPriority.slow:
|
||||||
|
return 24590000;
|
||||||
|
case MoneroTransactionPriority.regular:
|
||||||
|
return 123050000;
|
||||||
|
case MoneroTransactionPriority.medium:
|
||||||
|
return 245029999;
|
||||||
|
case MoneroTransactionPriority.fast:
|
||||||
|
return 614530000;
|
||||||
|
case MoneroTransactionPriority.fastest:
|
||||||
|
return 26021600000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priority == TransactionPriority.regular) {
|
|
||||||
return 0.00012305;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priority == TransactionPriority.medium) {
|
|
||||||
return 0.00024503;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priority == TransactionPriority.fast) {
|
|
||||||
return 0.00061453;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priority == TransactionPriority.fastest) {
|
|
||||||
return 0.0260216;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||||
|
import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
@ -752,7 +754,7 @@ class SendPage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _setTransactionPriority(BuildContext context) async {
|
Future<void> _setTransactionPriority(BuildContext context) async {
|
||||||
final items = TransactionPriority.forWalletType(sendViewModel.walletType);
|
final items = priorityForWalletType(sendViewModel.walletType);
|
||||||
final selectedItem = items.indexOf(sendViewModel.transactionPriority);
|
final selectedItem = items.indexOf(sendViewModel.transactionPriority);
|
||||||
final isShowScrollThumb = items.length > 3;
|
final isShowScrollThumb = items.length > 3;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:cake_wallet/themes/theme_base.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/themes/theme_list.dart';
|
import 'package:cake_wallet/themes/theme_list.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -14,7 +16,7 @@ import 'package:cake_wallet/entities/language_service.dart';
|
||||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||||
import 'package:cake_wallet/entities/node.dart';
|
import 'package:cake_wallet/entities/node.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/action_list_display_mode.dart';
|
import 'package:cake_wallet/entities/action_list_display_mode.dart';
|
||||||
|
|
||||||
part 'settings_store.g.dart';
|
part 'settings_store.g.dart';
|
||||||
|
@ -25,7 +27,6 @@ abstract class SettingsStoreBase with Store {
|
||||||
SettingsStoreBase(
|
SettingsStoreBase(
|
||||||
{@required SharedPreferences sharedPreferences,
|
{@required SharedPreferences sharedPreferences,
|
||||||
@required FiatCurrency initialFiatCurrency,
|
@required FiatCurrency initialFiatCurrency,
|
||||||
@required TransactionPriority initialTransactionPriority,
|
|
||||||
@required BalanceDisplayMode initialBalanceDisplayMode,
|
@required BalanceDisplayMode initialBalanceDisplayMode,
|
||||||
@required bool initialSaveRecipientAddress,
|
@required bool initialSaveRecipientAddress,
|
||||||
@required bool initialAllowBiometricalAuthentication,
|
@required bool initialAllowBiometricalAuthentication,
|
||||||
|
@ -35,15 +36,20 @@ abstract class SettingsStoreBase with Store {
|
||||||
// @required String initialCurrentLocale,
|
// @required String initialCurrentLocale,
|
||||||
@required this.appVersion,
|
@required this.appVersion,
|
||||||
@required Map<WalletType, Node> nodes,
|
@required Map<WalletType, Node> nodes,
|
||||||
|
@required TransactionPriority initialBitcoinTransactionPriority,
|
||||||
|
@required TransactionPriority initialMoneroTransactionPriority,
|
||||||
this.actionlistDisplayMode}) {
|
this.actionlistDisplayMode}) {
|
||||||
fiatCurrency = initialFiatCurrency;
|
fiatCurrency = initialFiatCurrency;
|
||||||
transactionPriority = initialTransactionPriority;
|
|
||||||
balanceDisplayMode = initialBalanceDisplayMode;
|
balanceDisplayMode = initialBalanceDisplayMode;
|
||||||
shouldSaveRecipientAddress = initialSaveRecipientAddress;
|
shouldSaveRecipientAddress = initialSaveRecipientAddress;
|
||||||
allowBiometricalAuthentication = initialAllowBiometricalAuthentication;
|
allowBiometricalAuthentication = initialAllowBiometricalAuthentication;
|
||||||
currentTheme = initialTheme;
|
currentTheme = initialTheme;
|
||||||
pinCodeLength = initialPinLength;
|
pinCodeLength = initialPinLength;
|
||||||
languageCode = initialLanguageCode;
|
languageCode = initialLanguageCode;
|
||||||
|
priority = ObservableMap<WalletType, TransactionPriority>.of({
|
||||||
|
WalletType.monero: initialMoneroTransactionPriority,
|
||||||
|
WalletType.bitcoin: initialBitcoinTransactionPriority
|
||||||
|
});
|
||||||
this.nodes = ObservableMap<WalletType, Node>.of(nodes);
|
this.nodes = ObservableMap<WalletType, Node>.of(nodes);
|
||||||
_sharedPreferences = sharedPreferences;
|
_sharedPreferences = sharedPreferences;
|
||||||
|
|
||||||
|
@ -52,11 +58,13 @@ abstract class SettingsStoreBase with Store {
|
||||||
(FiatCurrency fiatCurrency) => sharedPreferences.setString(
|
(FiatCurrency fiatCurrency) => sharedPreferences.setString(
|
||||||
PreferencesKey.currentFiatCurrencyKey, fiatCurrency.serialize()));
|
PreferencesKey.currentFiatCurrencyKey, fiatCurrency.serialize()));
|
||||||
|
|
||||||
reaction(
|
priority.observe((change) {
|
||||||
(_) => transactionPriority,
|
final key = change.key == WalletType.monero
|
||||||
(TransactionPriority priority) => sharedPreferences.setInt(
|
? PreferencesKey.moneroTransactionPriority
|
||||||
PreferencesKey.currentTransactionPriorityKey,
|
: PreferencesKey.bitcoinTransactionPriority;
|
||||||
priority.serialize()));
|
|
||||||
|
sharedPreferences.setInt(key, change.newValue.serialize());
|
||||||
|
});
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldSaveRecipientAddress,
|
(_) => shouldSaveRecipientAddress,
|
||||||
|
@ -104,9 +112,6 @@ abstract class SettingsStoreBase with Store {
|
||||||
@observable
|
@observable
|
||||||
ObservableList<ActionListDisplayMode> actionlistDisplayMode;
|
ObservableList<ActionListDisplayMode> actionlistDisplayMode;
|
||||||
|
|
||||||
@observable
|
|
||||||
TransactionPriority transactionPriority;
|
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
BalanceDisplayMode balanceDisplayMode;
|
BalanceDisplayMode balanceDisplayMode;
|
||||||
|
|
||||||
|
@ -128,6 +133,9 @@ abstract class SettingsStoreBase with Store {
|
||||||
@observable
|
@observable
|
||||||
String languageCode;
|
String languageCode;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
ObservableMap<WalletType, TransactionPriority> priority;
|
||||||
|
|
||||||
String appVersion;
|
String appVersion;
|
||||||
|
|
||||||
SharedPreferences _sharedPreferences;
|
SharedPreferences _sharedPreferences;
|
||||||
|
@ -139,16 +147,28 @@ abstract class SettingsStoreBase with Store {
|
||||||
static Future<SettingsStore> load(
|
static Future<SettingsStore> load(
|
||||||
{@required Box<Node> nodeSource,
|
{@required Box<Node> nodeSource,
|
||||||
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
|
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
|
||||||
TransactionPriority initialTransactionPriority = TransactionPriority.slow,
|
MoneroTransactionPriority initialMoneroTransactionPriority =
|
||||||
|
MoneroTransactionPriority.slow,
|
||||||
|
BitcoinTransactionPriority initialBitcoinTransactionPriority =
|
||||||
|
BitcoinTransactionPriority.medium,
|
||||||
BalanceDisplayMode initialBalanceDisplayMode =
|
BalanceDisplayMode initialBalanceDisplayMode =
|
||||||
BalanceDisplayMode.availableBalance}) async {
|
BalanceDisplayMode.availableBalance}) async {
|
||||||
final sharedPreferences = await getIt.getAsync<SharedPreferences>();
|
final sharedPreferences = await getIt.getAsync<SharedPreferences>();
|
||||||
final currentFiatCurrency = FiatCurrency(
|
final currentFiatCurrency = FiatCurrency(
|
||||||
symbol:
|
symbol:
|
||||||
sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey));
|
sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey));
|
||||||
final currentTransactionPriority = TransactionPriority.deserialize(
|
final savedMoneroTransactionPriority =
|
||||||
|
MoneroTransactionPriority.deserialize(
|
||||||
raw: sharedPreferences
|
raw: sharedPreferences
|
||||||
.getInt(PreferencesKey.currentTransactionPriorityKey));
|
.getInt(PreferencesKey.moneroTransactionPriority));
|
||||||
|
final savedBitcoinTransactionPriority =
|
||||||
|
BitcoinTransactionPriority.deserialize(
|
||||||
|
raw: sharedPreferences
|
||||||
|
.getInt(PreferencesKey.bitcoinTransactionPriority));
|
||||||
|
final moneroTransactionPriority =
|
||||||
|
savedMoneroTransactionPriority ?? initialMoneroTransactionPriority;
|
||||||
|
final bitcoinTransactionPriority =
|
||||||
|
savedBitcoinTransactionPriority ?? initialBitcoinTransactionPriority;
|
||||||
final currentBalanceDisplayMode = BalanceDisplayMode.deserialize(
|
final currentBalanceDisplayMode = BalanceDisplayMode.deserialize(
|
||||||
raw: sharedPreferences
|
raw: sharedPreferences
|
||||||
.getInt(PreferencesKey.currentBalanceDisplayModeKey));
|
.getInt(PreferencesKey.currentBalanceDisplayModeKey));
|
||||||
|
@ -193,30 +213,36 @@ abstract class SettingsStoreBase with Store {
|
||||||
},
|
},
|
||||||
appVersion: packageInfo.version,
|
appVersion: packageInfo.version,
|
||||||
initialFiatCurrency: currentFiatCurrency,
|
initialFiatCurrency: currentFiatCurrency,
|
||||||
initialTransactionPriority: currentTransactionPriority,
|
|
||||||
initialBalanceDisplayMode: currentBalanceDisplayMode,
|
initialBalanceDisplayMode: currentBalanceDisplayMode,
|
||||||
initialSaveRecipientAddress: shouldSaveRecipientAddress,
|
initialSaveRecipientAddress: shouldSaveRecipientAddress,
|
||||||
initialAllowBiometricalAuthentication: allowBiometricalAuthentication,
|
initialAllowBiometricalAuthentication: allowBiometricalAuthentication,
|
||||||
initialTheme: savedTheme,
|
initialTheme: savedTheme,
|
||||||
actionlistDisplayMode: actionListDisplayMode,
|
actionlistDisplayMode: actionListDisplayMode,
|
||||||
initialPinLength: pinLength,
|
initialPinLength: pinLength,
|
||||||
initialLanguageCode: savedLanguageCode);
|
initialLanguageCode: savedLanguageCode,
|
||||||
|
initialMoneroTransactionPriority: moneroTransactionPriority,
|
||||||
|
initialBitcoinTransactionPriority: bitcoinTransactionPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> reload(
|
Future<void> reload(
|
||||||
{@required Box<Node> nodeSource,
|
{@required Box<Node> nodeSource,
|
||||||
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
|
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
|
||||||
TransactionPriority initialTransactionPriority = TransactionPriority.slow,
|
MoneroTransactionPriority initialMoneroTransactionPriority =
|
||||||
|
MoneroTransactionPriority.slow,
|
||||||
|
BitcoinTransactionPriority initialBitcoinTransactionPriority =
|
||||||
|
BitcoinTransactionPriority.medium,
|
||||||
BalanceDisplayMode initialBalanceDisplayMode =
|
BalanceDisplayMode initialBalanceDisplayMode =
|
||||||
BalanceDisplayMode.availableBalance}) async {
|
BalanceDisplayMode.availableBalance}) async {
|
||||||
final settings = await SettingsStoreBase.load(
|
final settings = await SettingsStoreBase.load(
|
||||||
nodeSource: nodeSource,
|
nodeSource: nodeSource,
|
||||||
initialBalanceDisplayMode: initialBalanceDisplayMode,
|
initialBalanceDisplayMode: initialBalanceDisplayMode,
|
||||||
initialFiatCurrency: initialFiatCurrency,
|
initialFiatCurrency: initialFiatCurrency,
|
||||||
initialTransactionPriority: initialTransactionPriority);
|
initialMoneroTransactionPriority: initialMoneroTransactionPriority,
|
||||||
|
initialBitcoinTransactionPriority: initialBitcoinTransactionPriority);
|
||||||
fiatCurrency = settings.fiatCurrency;
|
fiatCurrency = settings.fiatCurrency;
|
||||||
actionlistDisplayMode = settings.actionlistDisplayMode;
|
actionlistDisplayMode = settings.actionlistDisplayMode;
|
||||||
transactionPriority = settings.transactionPriority;
|
priority[WalletType.monero] = initialMoneroTransactionPriority;
|
||||||
|
priority[WalletType.bitcoin] = initialBitcoinTransactionPriority;
|
||||||
balanceDisplayMode = settings.balanceDisplayMode;
|
balanceDisplayMode = settings.balanceDisplayMode;
|
||||||
shouldSaveRecipientAddress = settings.shouldSaveRecipientAddress;
|
shouldSaveRecipientAddress = settings.shouldSaveRecipientAddress;
|
||||||
allowBiometricalAuthentication = settings.allowBiometricalAuthentication;
|
allowBiometricalAuthentication = settings.allowBiometricalAuthentication;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
||||||
import 'package:cake_wallet/core/wallet_base.dart';
|
import 'package:cake_wallet/core/wallet_base.dart';
|
||||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
|
@ -302,8 +303,8 @@ abstract class ExchangeViewModelBase with Store {
|
||||||
void calculateDepositAllAmount() {
|
void calculateDepositAllAmount() {
|
||||||
if (wallet is BitcoinWallet) {
|
if (wallet is BitcoinWallet) {
|
||||||
final availableBalance = wallet.balance.available;
|
final availableBalance = wallet.balance.available;
|
||||||
final fee = BitcoinWalletBase.feeAmountForPriority(
|
final priority = _settingsStore.priority[wallet.type] as BitcoinTransactionPriority;
|
||||||
_settingsStore.transactionPriority);
|
final fee = wallet.calculateEstimatedFee(priority, null);
|
||||||
|
|
||||||
if (availableBalance < fee || availableBalance == 0) {
|
if (availableBalance < fee || availableBalance == 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||||
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
|
import 'package:cake_wallet/monero/monero_amount_format.dart';
|
||||||
|
import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -21,7 +26,7 @@ import 'package:cake_wallet/monero/monero_transaction_creation_credentials.dart'
|
||||||
import 'package:cake_wallet/entities/sync_status.dart';
|
import 'package:cake_wallet/entities/sync_status.dart';
|
||||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/calculate_fiat_amount.dart';
|
import 'package:cake_wallet/entities/calculate_fiat_amount.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||||
|
@ -40,11 +45,11 @@ abstract class SendViewModelBase with Store {
|
||||||
_cryptoNumberFormat = NumberFormat(),
|
_cryptoNumberFormat = NumberFormat(),
|
||||||
note = '',
|
note = '',
|
||||||
sendAll = false {
|
sendAll = false {
|
||||||
final _priority = _settingsStore.transactionPriority;
|
final priority = _settingsStore.priority[_wallet.type];
|
||||||
|
final priorities = priorityForWalletType(_wallet.type);
|
||||||
|
|
||||||
if (!TransactionPriority.forWalletType(walletType).contains(_priority)) {
|
if (!priorityForWalletType(_wallet.type).contains(priority)) {
|
||||||
_settingsStore.transactionPriority =
|
_settingsStore.priority[_wallet.type] = priorities.first;
|
||||||
TransactionPriority.forWalletType(walletType).first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setCryptoNumMaximumFractionDigits();
|
_setCryptoNumMaximumFractionDigits();
|
||||||
|
@ -69,8 +74,39 @@ abstract class SendViewModelBase with Store {
|
||||||
bool sendAll;
|
bool sendAll;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
double get estimatedFee =>
|
double get estimatedFee {
|
||||||
_wallet.calculateEstimatedFee(_settingsStore.transactionPriority);
|
int amount;
|
||||||
|
|
||||||
|
if (cryptoAmount?.isNotEmpty ?? false) {
|
||||||
|
int _amount = 0;
|
||||||
|
switch (walletType) {
|
||||||
|
case WalletType.monero:
|
||||||
|
_amount = moneroParseAmount(amount: cryptoAmount);
|
||||||
|
break;
|
||||||
|
case WalletType.bitcoin:
|
||||||
|
_amount = stringDoubleToBitcoinAmount(cryptoAmount);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_amount > 0) {
|
||||||
|
amount = _amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final fee = _wallet.calculateEstimatedFee(_settingsStore.priority[_wallet.type], amount);
|
||||||
|
|
||||||
|
if (_wallet is BitcoinWallet) {
|
||||||
|
return bitcoinAmountToDouble(amount: fee);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wallet is MoneroWallet) {
|
||||||
|
return moneroAmountToDouble(amount: fee);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
String get estimatedFeeFiatAmount {
|
String get estimatedFeeFiatAmount {
|
||||||
|
@ -119,7 +155,7 @@ abstract class SendViewModelBase with Store {
|
||||||
FiatCurrency get fiat => _settingsStore.fiatCurrency;
|
FiatCurrency get fiat => _settingsStore.fiatCurrency;
|
||||||
|
|
||||||
TransactionPriority get transactionPriority =>
|
TransactionPriority get transactionPriority =>
|
||||||
_settingsStore.transactionPriority;
|
_settingsStore.priority[_wallet.type];
|
||||||
|
|
||||||
CryptoCurrency get currency => _wallet.currency;
|
CryptoCurrency get currency => _wallet.currency;
|
||||||
|
|
||||||
|
@ -213,7 +249,7 @@ abstract class SendViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void setTransactionPriority(TransactionPriority priority) =>
|
void setTransactionPriority(TransactionPriority priority) =>
|
||||||
_settingsStore.transactionPriority = priority;
|
_settingsStore.priority[_wallet.type] = priority;
|
||||||
|
|
||||||
Future<OpenaliasRecord> decodeOpenaliasRecord(String name) async {
|
Future<OpenaliasRecord> decodeOpenaliasRecord(String name) async {
|
||||||
final record = await OpenaliasRecord.fetchAddressAndName(
|
final record = await OpenaliasRecord.fetchAddressAndName(
|
||||||
|
@ -257,16 +293,17 @@ abstract class SendViewModelBase with Store {
|
||||||
switch (_wallet.type) {
|
switch (_wallet.type) {
|
||||||
case WalletType.bitcoin:
|
case WalletType.bitcoin:
|
||||||
final amount = !sendAll ? _amount : null;
|
final amount = !sendAll ? _amount : null;
|
||||||
|
final priority = _settingsStore.priority[_wallet.type];
|
||||||
|
|
||||||
return BitcoinTransactionCredentials(
|
return BitcoinTransactionCredentials(address, amount, priority as BitcoinTransactionPriority);
|
||||||
address, amount, _settingsStore.transactionPriority);
|
|
||||||
case WalletType.monero:
|
case WalletType.monero:
|
||||||
final amount = !sendAll ? _amount : null;
|
final amount = !sendAll ? _amount : null;
|
||||||
|
final priority = _settingsStore.priority[_wallet.type];
|
||||||
|
|
||||||
return MoneroTransactionCreationCredentials(
|
return MoneroTransactionCreationCredentials(
|
||||||
address: address,
|
address: address,
|
||||||
paymentId: '',
|
paymentId: '',
|
||||||
priority: _settingsStore.transactionPriority,
|
priority: priority as MoneroTransactionPriority,
|
||||||
amount: amount);
|
amount: amount);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/balance.dart';
|
import 'package:cake_wallet/entities/balance.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||||
import 'package:cake_wallet/themes/theme_base.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/themes/theme_list.dart';
|
import 'package:cake_wallet/themes/theme_list.dart';
|
||||||
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
||||||
|
@ -14,7 +16,7 @@ import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||||
import 'package:cake_wallet/entities/node.dart';
|
import 'package:cake_wallet/entities/node.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
|
||||||
import 'package:cake_wallet/entities/action_list_display_mode.dart';
|
import 'package:cake_wallet/entities/action_list_display_mode.dart';
|
||||||
import 'package:cake_wallet/view_model/settings/version_list_item.dart';
|
import 'package:cake_wallet/view_model/settings/version_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/settings/link_list_item.dart';
|
import 'package:cake_wallet/view_model/settings/link_list_item.dart';
|
||||||
|
@ -28,6 +30,17 @@ part 'settings_view_model.g.dart';
|
||||||
|
|
||||||
class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel;
|
class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel;
|
||||||
|
|
||||||
|
List<TransactionPriority> priorityForWalletType(WalletType type) {
|
||||||
|
switch (type) {
|
||||||
|
case WalletType.monero:
|
||||||
|
return MoneroTransactionPriority.all;
|
||||||
|
case WalletType.bitcoin:
|
||||||
|
return BitcoinTransactionPriority.all;
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class SettingsViewModelBase with Store {
|
abstract class SettingsViewModelBase with Store {
|
||||||
SettingsViewModelBase(this._settingsStore, WalletBase<Balance> wallet)
|
SettingsViewModelBase(this._settingsStore, WalletBase<Balance> wallet)
|
||||||
: itemHeaders = {},
|
: itemHeaders = {},
|
||||||
|
@ -37,11 +50,11 @@ abstract class SettingsViewModelBase with Store {
|
||||||
PackageInfo.fromPlatform().then(
|
PackageInfo.fromPlatform().then(
|
||||||
(PackageInfo packageInfo) => currentVersion = packageInfo.version);
|
(PackageInfo packageInfo) => currentVersion = packageInfo.version);
|
||||||
|
|
||||||
final _priority = _settingsStore.transactionPriority;
|
final priority = _settingsStore.priority[wallet.type];
|
||||||
|
final priorities = priorityForWalletType(wallet.type);
|
||||||
|
|
||||||
if (!TransactionPriority.forWalletType(_walletType).contains(_priority)) {
|
if (!priorities.contains(priority)) {
|
||||||
_settingsStore.transactionPriority =
|
_settingsStore.priority[wallet.type] = priorities.first;
|
||||||
TransactionPriority.forWalletType(_walletType).first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sections = [
|
sections = [
|
||||||
|
@ -60,10 +73,10 @@ abstract class SettingsViewModelBase with Store {
|
||||||
setFiatCurrency(currency)),
|
setFiatCurrency(currency)),
|
||||||
PickerListItem(
|
PickerListItem(
|
||||||
title: S.current.settings_fee_priority,
|
title: S.current.settings_fee_priority,
|
||||||
items: TransactionPriority.forWalletType(wallet.type),
|
items: priorityForWalletType(wallet.type),
|
||||||
selectedItem: () => transactionPriority,
|
selectedItem: () => transactionPriority,
|
||||||
onItemSelected: (TransactionPriority priority) =>
|
onItemSelected: (TransactionPriority priority) =>
|
||||||
_settingsStore.transactionPriority = priority),
|
_settingsStore.priority[wallet.type] = priority),
|
||||||
SwitcherListItem(
|
SwitcherListItem(
|
||||||
title: S.current.settings_save_recipient_address,
|
title: S.current.settings_save_recipient_address,
|
||||||
value: () => shouldSaveRecipientAddress,
|
value: () => shouldSaveRecipientAddress,
|
||||||
|
@ -182,7 +195,7 @@ abstract class SettingsViewModelBase with Store {
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
TransactionPriority get transactionPriority =>
|
TransactionPriority get transactionPriority =>
|
||||||
_settingsStore.transactionPriority;
|
_settingsStore.priority[_walletType];
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
BalanceDisplayMode get balanceDisplayMode =>
|
BalanceDisplayMode get balanceDisplayMode =>
|
||||||
|
|
Loading…
Reference in a new issue