Flutter upgrade

This commit is contained in:
M
2022-10-12 13:09:57 -04:00
parent c921ad890a
commit 1beb18b045
505 changed files with 6657 additions and 5875 deletions
+12 -12
View File
@@ -6,14 +6,14 @@ import 'package:cake_wallet/monero/monero.dart';
class AnyPayPayment {
AnyPayPayment({
@required this.time,
@required this.expires,
@required this.memo,
@required this.paymentUrl,
@required this.paymentId,
@required this.chain,
@required this.network,
@required this.instructions});
required this.time,
required this.expires,
required this.memo,
required this.paymentUrl,
required this.paymentId,
required this.chain,
required this.network,
required this.instructions});
factory AnyPayPayment.fromMap(Map<String, dynamic> obj) {
final instructions = (obj['instructions'] as List<dynamic>)
@@ -45,13 +45,13 @@ class AnyPayPayment {
.fold<int>(0, (int outAcc, out) => outAcc + out.amount));
switch (chain) {
case AnyPayChain.xmr:
return monero.formatterMoneroAmountToString(amount: total);
return monero!.formatterMoneroAmountToString(amount: total);
case AnyPayChain.btc:
return bitcoin.formatterBitcoinAmountToString(amount: total);
return bitcoin!.formatterBitcoinAmountToString(amount: total);
case AnyPayChain.ltc:
return bitcoin.formatterBitcoinAmountToString(amount: total);
return bitcoin!.formatterBitcoinAmountToString(amount: total);
default:
return null;
return '';
}
}
@@ -3,11 +3,11 @@ import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
class AnyPayPaymentCommittedInfo {
const AnyPayPaymentCommittedInfo({
@required this.uri,
@required this.currency,
@required this.chain,
@required this.transactions,
@required this.memo});
required this.uri,
required this.currency,
required this.chain,
required this.transactions,
required this.memo});
final String uri;
final String currency;
+5 -5
View File
@@ -3,11 +3,11 @@ import 'package:cake_wallet/anypay/any_pay_payment_instruction_output.dart';
class AnyPayPaymentInstruction {
AnyPayPaymentInstruction({
@required this.type,
@required this.requiredFeeRate,
@required this.txKey,
@required this.txHash,
@required this.outputs});
required this.type,
required this.requiredFeeRate,
required this.txKey,
required this.txHash,
required this.outputs});
factory AnyPayPaymentInstruction.fromMap(Map<String, dynamic> obj) {
final outputs = (obj['outputs'] as List<dynamic>)
+2 -4
View File
@@ -1,9 +1,7 @@
import 'package:flutter/foundation.dart';
class AnyPayTransaction {
const AnyPayTransaction(this.tx, {@required this.id, @required this.key});
const AnyPayTransaction(this.tx, {required this.id, required this.key});
final String tx;
final String id;
final String key;
final String? key;
}
+12 -12
View File
@@ -33,15 +33,15 @@ class AnyPayApi {
case 'litecoin':
return CryptoCurrency.ltc;
default:
return null;
throw Exception('Unexpected scheme: ${scheme}');
}
}
Future<AnyPayPayment> paymentRequest(String uri) async {
final fragments = uri.split(':?r=');
final scheme = fragments.first;
final url = fragments[1];
final headers = <String, String>{
final url = Uri.parse(fragments[1]);
final headers = <String, String>{
'Content-Type': contentTypePaymentRequest,
'X-Paypro-Version': xPayproVersion,
'Accept': '*/*',};
@@ -50,20 +50,20 @@ class AnyPayApi {
'currency': currencyByScheme(scheme).title};
final response = await post(url, headers: headers, body: utf8.encode(json.encode(body)));
if (response.statusCode != 200) {
return null;
if (response.statusCode != 200) {
throw Exception('Unexpected response http code: ${response.statusCode}');
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
return AnyPayPayment.fromMap(decodedBody);
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
return AnyPayPayment.fromMap(decodedBody);
}
Future<AnyPayPaymentCommittedInfo> payment(
String uri,
{@required String chain,
@required String currency,
@required List<AnyPayTransaction> transactions}) async {
final headers = <String, String>{
{required String chain,
required String currency,
required List<AnyPayTransaction> transactions}) async {
final headers = <String, String>{
'Content-Type': contentTypePayment,
'X-Paypro-Version': xPayproVersion,
'Accept': '*/*',};
@@ -71,7 +71,7 @@ class AnyPayApi {
'chain': chain,
'currency': currency,
'transactions': transactions.map((tx) => {'tx': tx.tx, 'tx_hash': tx.id, 'tx_key': tx.key}).toList()};
final response = await post(uri, headers: headers, body: utf8.encode(json.encode(body)));
final response = await post(Uri.parse(uri), headers: headers, body: utf8.encode(json.encode(body)));
if (response.statusCode == 400) {
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
throw Exception(decodedBody['message'] as String);
+16 -7
View File
@@ -5,15 +5,24 @@ class CWBitcoin extends Bitcoin {
TransactionPriority getMediumTransactionPriority() => BitcoinTransactionPriority.medium;
@override
WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({String name, String mnemonic, String password})
WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({
required String name,
required String mnemonic,
required String password})
=> BitcoinRestoreWalletFromSeedCredentials(name: name, mnemonic: mnemonic, password: password);
@override
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({String name, String password, String wif, WalletInfo walletInfo})
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({
required String name,
required String password,
required String wif,
WalletInfo? walletInfo})
=> BitcoinRestoreWalletFromWIFCredentials(name: name, password: password, wif: wif, walletInfo: walletInfo);
@override
WalletCredentials createBitcoinNewWalletCredentials({String name, WalletInfo walletInfo})
WalletCredentials createBitcoinNewWalletCredentials({
required String name,
WalletInfo? walletInfo})
=> BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo);
@override
@@ -55,7 +64,7 @@ class CWBitcoin extends Bitcoin {
}
@override
Object createBitcoinTransactionCredentials(List<Output> outputs, {TransactionPriority priority, int feeRate})
Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate})
=> BitcoinTransactionCredentials(
outputs.map((out) => OutputInfo(
fiatAmount: out.fiatAmount,
@@ -71,7 +80,7 @@ class CWBitcoin extends Bitcoin {
feeRate: feeRate);
@override
Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority priority, int feeRate})
Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority? priority, required int feeRate})
=> BitcoinTransactionCredentials(
outputs,
priority: priority != null ? priority as BitcoinTransactionPriority : null,
@@ -92,11 +101,11 @@ class CWBitcoin extends Bitcoin {
}
@override
String formatterBitcoinAmountToString({int amount})
String formatterBitcoinAmountToString({required int amount})
=> bitcoinAmountToString(amount: amount);
@override
double formatterBitcoinAmountToDouble({int amount})
double formatterBitcoinAmountToDouble({required int amount})
=> bitcoinAmountToDouble(amount: amount);
@override
+3 -3
View File
@@ -2,13 +2,13 @@ import 'package:flutter/foundation.dart';
class BuyAmount {
BuyAmount({
@required this.sourceAmount,
@required this.destAmount,
required this.sourceAmount,
required this.destAmount,
this.achSourceAmount,
this.minAmount = 0});
final double sourceAmount;
final double destAmount;
final double achSourceAmount;
final double? achSourceAmount;
final int minAmount;
}
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
class BuyException implements Exception {
BuyException({@required this.description, @required this.text});
BuyException({required this.description, required this.text});
final BuyProviderDescription description;
final String text;
+1 -1
View File
@@ -5,7 +5,7 @@ import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
abstract class BuyProvider {
BuyProvider({this.wallet, this.isTestEnvironment});
BuyProvider({required this.wallet, required this.isTestEnvironment});
final WalletBase wallet;
final bool isTestEnvironment;
+3 -3
View File
@@ -2,20 +2,20 @@ import 'package:cw_core/enumerable_item.dart';
class BuyProviderDescription extends EnumerableItem<int>
with Serializable<int> {
const BuyProviderDescription({String title, int raw})
const BuyProviderDescription({required String title, required int raw})
: super(title: title, raw: raw);
static const wyre = BuyProviderDescription(title: 'Wyre', raw: 0);
static const moonPay = BuyProviderDescription(title: 'MoonPay', raw: 1);
static BuyProviderDescription deserialize({int raw}) {
static BuyProviderDescription deserialize({required int raw}) {
switch (raw) {
case 0:
return wyre;
case 1:
return moonPay;
default:
return null;
throw Exception('Incorrect token $raw for BuyProviderDescription deserialize');
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
Image getBuyProviderIcon(BuyProviderDescription providerDescription,
Image? getBuyProviderIcon(BuyProviderDescription providerDescription,
{Color iconColor = Colors.black}) {
final _wyreIcon =
+10 -11
View File
@@ -23,7 +23,7 @@ class MoonPaySellProvider {
final bool isTest;
final String baseUrl;
Future<String> requestUrl({CryptoCurrency currency, String refundWalletAddress}) async {
Future<String> requestUrl({required CryptoCurrency currency, required String refundWalletAddress}) async {
final originalUri = Uri.https(
baseUrl, '', <String, dynamic>{
'apiKey': _apiKey,
@@ -48,10 +48,9 @@ class MoonPaySellProvider {
}
class MoonPayBuyProvider extends BuyProvider {
MoonPayBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
: super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl;
}
MoonPayBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
: baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl,
super(wallet: wallet, isTestEnvironment: isTestEnvironment);
static const _baseTestUrl = 'https://buy-staging.moonpay.com';
static const _baseProductUrl = 'https://buy.moonpay.com';
@@ -109,8 +108,8 @@ class MoonPayBuyProvider extends BuyProvider {
_quoteSuffix + '/?apiKey=' + _apiKey +
'&baseCurrencyAmount=' + amount +
'&baseCurrencyCode=' + sourceCurrency.toLowerCase();
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
if (response.statusCode != 200) {
throw BuyException(
@@ -133,8 +132,8 @@ class MoonPayBuyProvider extends BuyProvider {
Future<Order> findOrderById(String id) async {
final url = _apiUrl + _transactionsSuffix + '/$id' +
'?apiKey=' + _apiKey;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
if (response.statusCode != 200) {
throw BuyException(
@@ -164,8 +163,8 @@ class MoonPayBuyProvider extends BuyProvider {
static Future<bool> onEnabled() async {
final url = _apiUrl + _ipAddressSuffix + '?apiKey=' + _apiKey;
var isBuyEnable = false;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
try {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
+20 -15
View File
@@ -8,18 +8,23 @@ part 'order.g.dart';
@HiveType(typeId: Order.typeId)
class Order extends HiveObject {
Order(
{this.id,
BuyProviderDescription provider,
this.transferId,
{required this.id,
required this.transferId,
required this.createdAt,
required this.amount,
required this.receiveAddress,
required this.walletId,
BuyProviderDescription? provider,
TradeState? state,
this.from,
this.to,
TradeState state,
this.createdAt,
this.amount,
this.receiveAddress,
this.walletId})
: providerRaw = provider?.raw,
stateRaw = state?.raw;
this.to}) {
if (provider != null) {
providerRaw = provider.raw;
}
if (state != null) {
stateRaw = state.raw;
}
}
static const typeId = 8;
static const boxName = 'Orders';
@@ -32,13 +37,13 @@ class Order extends HiveObject {
String transferId;
@HiveField(2)
String from;
String? from;
@HiveField(3)
String to;
String? to;
@HiveField(4)
String stateRaw;
late String stateRaw;
TradeState get state => TradeState.deserialize(raw: stateRaw);
@@ -55,7 +60,7 @@ class Order extends HiveObject {
String walletId;
@HiveField(9)
int providerRaw;
late int providerRaw;
BuyProviderDescription get provider =>
BuyProviderDescription.deserialize(raw: providerRaw);
+12 -11
View File
@@ -11,12 +11,11 @@ import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
class WyreBuyProvider extends BuyProvider {
WyreBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
: super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
baseApiUrl = isTestEnvironment
WyreBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
: baseApiUrl = isTestEnvironment
? _baseTestApiUrl
: _baseProductApiUrl;
}
: _baseProductApiUrl,
super(wallet: wallet, isTestEnvironment: isTestEnvironment);
static const _baseTestApiUrl = 'https://api.testwyre.com';
static const _baseProductApiUrl = 'https://api.sendwyre.com';
@@ -50,6 +49,7 @@ class WyreBuyProvider extends BuyProvider {
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
_timeStampSuffix + timestamp;
final uri = Uri.parse(url);
final body = {
'amount': amount,
'sourceCurrency': sourceCurrency,
@@ -58,8 +58,7 @@ class WyreBuyProvider extends BuyProvider {
'referrerAccountId': _accountId,
'lockFields': ['amount', 'sourceCurrency', 'destCurrency', 'dest']
};
final response = await post(url,
final response = await post(uri,
headers: {
'Authorization': 'Bearer $_secretKey',
'Content-Type': 'application/json',
@@ -89,8 +88,8 @@ class WyreBuyProvider extends BuyProvider {
'accountId': _accountId,
'country': _countryCode
};
final response = await post(quoteUrl,
final uri = Uri.parse(quoteUrl);
final response = await post(uri,
headers: {
'Authorization': 'Bearer $_secretKey',
'Content-Type': 'application/json',
@@ -115,7 +114,8 @@ class WyreBuyProvider extends BuyProvider {
@override
Future<Order> findOrderById(String id) async {
final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
final orderResponse = await get(orderUrl);
final orderUri = Uri.parse(orderUrl);
final orderResponse = await get(orderUri);
if (orderResponse.statusCode != 200) {
throw BuyException(
@@ -136,7 +136,8 @@ class WyreBuyProvider extends BuyProvider {
final transferUrl =
baseApiUrl + _transferSuffix + transferId + _trackSuffix;
final transferResponse = await get(transferUrl);
final transferUri = Uri.parse(transferUrl);
final transferResponse = await get(transferUri);
if (transferResponse.statusCode != 200) {
throw BuyException(
+1 -1
View File
@@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/wallet_type.dart';
class AddressLabelValidator extends TextValidator {
AddressLabelValidator({WalletType type})
AddressLabelValidator({WalletType? type})
: super(
errorMessage: S.current.error_text_subaddress_name,
pattern: '''^[^`,'"]{1,20}\$''',
+2 -2
View File
@@ -4,7 +4,7 @@ import 'package:cake_wallet/core/validator.dart';
import 'package:cw_core/crypto_currency.dart';
class AddressValidator extends TextValidator {
AddressValidator({@required CryptoCurrency type})
AddressValidator({required CryptoCurrency type})
: super(
errorMessage: S.current.error_text_address,
pattern: getPattern(type),
@@ -79,7 +79,7 @@ class AddressValidator extends TextValidator {
}
}
static List<int> getLength(CryptoCurrency type) {
static List<int>? getLength(CryptoCurrency type) {
switch (type) {
case CryptoCurrency.xmr:
return null;
+27 -27
View File
@@ -1,37 +1,37 @@
abstract class Amount {
Amount(this.value);
// abstract class Amount {
// Amount(this.value);
int value;
// int value;
int minorDigits;
// int minorDigits;
String code;
// String code;
String formatted();
}
// String formatted();
// }
class MoneroAmount extends Amount {
MoneroAmount(int value) : super(value) {
minorDigits = 12;
code = 'XMR';
}
// class MoneroAmount extends Amount {
// MoneroAmount(int value) : super(value) {
// minorDigits = 12;
// code = 'XMR';
// }
// const moneroAmountLength = 12;
// const moneroAmountDivider = 1000000000000;
// final moneroAmountFormat = NumberFormat()
// ..maximumFractionDigits = moneroAmountLength
// ..minimumFractionDigits = 1;
// // const moneroAmountLength = 12;
// // const moneroAmountDivider = 1000000000000;
// // final moneroAmountFormat = NumberFormat()
// // ..maximumFractionDigits = moneroAmountLength
// // ..minimumFractionDigits = 1;
// String moneroAmountToString({int amount}) =>
// moneroAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider));
// // String moneroAmountToString({int amount}) =>
// // moneroAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider));
// double moneroAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
// // double moneroAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
// int moneroParseAmount({String amount}) => moneroAmountFormat.parse(amount).toInt();
// // int moneroParseAmount({String amount}) => moneroAmountFormat.parse(amount).toInt();
@override
String formatted() {
// TODO: implement formatted
throw UnimplementedError();
}
}
// @override
// String formatted() {
// // TODO: implement formatted
// throw UnimplementedError();
// }
// }
+4 -4
View File
@@ -47,7 +47,7 @@ class AmountConverter {
case CryptoCurrency.xusd:
return _moneroAmountToDouble(amount);
default:
return null;
return 0.0;
}
}
@@ -71,7 +71,7 @@ class AmountConverter {
case CryptoCurrency.xusd:
return _moneroParseAmount(amount);
default:
return null;
return 0;
}
}
@@ -97,11 +97,11 @@ class AmountConverter {
case CryptoCurrency.xusd:
return _moneroAmountToString(amount);
default:
return null;
return '';
}
}
static double cryptoAmountToDouble({num amount, num divider}) =>
static double cryptoAmountToDouble({required num amount, required num divider}) =>
amount / divider;
static String _moneroAmountToString(int amount) => _moneroAmountFormat.format(
+1 -1
View File
@@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/wallet_type.dart';
class AmountValidator extends TextValidator {
AmountValidator({WalletType type, bool isAutovalidate = false})
AmountValidator({required WalletType type, bool isAutovalidate = false})
: super(
errorMessage: S.current.error_text_amount,
pattern: _pattern(type),
+4 -4
View File
@@ -6,12 +6,12 @@ import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cake_wallet/entities/encrypt.dart';
class AuthService with Store {
AuthService({this.secureStorage, this.sharedPreferences});
AuthService({required this.secureStorage, required this.sharedPreferences});
final FlutterSecureStorage secureStorage;
final SharedPreferences sharedPreferences;
Future setPassword(String password) async {
Future<void> setPassword(String password) async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPassword = encodedPinCode(pin: password);
await secureStorage.write(key: key, value: encodedPassword);
@@ -24,7 +24,7 @@ class AuthService with Store {
var password = '';
try {
password = await secureStorage.read(key: key);
password = await secureStorage.read(key: key) ?? '';
} catch (e) {
print(e);
}
@@ -35,7 +35,7 @@ class AuthService with Store {
Future<bool> authenticate(String pin) async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPin = await secureStorage.read(key: key);
final decodedPin = decodedPinCode(pin: encodedPin);
final decodedPin = decodedPinCode(pin: encodedPin!);
return decodedPin == pin;
}
+2 -2
View File
@@ -7,13 +7,13 @@ class AuthenticationInProgress extends AuthState {}
class AuthenticatedSuccessfully extends AuthState {}
class AuthenticationFailure extends AuthState {
AuthenticationFailure({this.error});
AuthenticationFailure({required this.error});
final String error;
}
class AuthenticationBanned extends AuthState {
AuthenticationBanned({this.error});
AuthenticationBanned({required this.error});
final String error;
}
+43 -32
View File
@@ -20,7 +20,8 @@ import 'package:cake_wallet/wallet_types.g.dart';
class BackupService {
BackupService(this._flutterSecureStorage, this._walletInfoSource,
this._keyService, this._sharedPreferences)
: _cipher = chacha20Poly1305Aead;
: _cipher = Cryptography.instance.chacha20Poly1305Aead(),
_correctWallets = <WalletInfo>[];
static const currentVersion = _v1;
@@ -54,7 +55,7 @@ class BackupService {
case _v1:
return await _exportBackupV1(password, nonce: nonce);
default:
return null;
throw Exception('Incorrect version: $version for exportBackup');
}
}
@@ -91,8 +92,8 @@ class BackupService {
});
await keychainDumpFile.writeAsBytes(keychainDump.toList());
await preferencesDumpFile.writeAsString(preferencesDump);
zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump');
zipEncoder.addFile(keychainDumpFile, '~_keychain_dump');
await zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump');
await zipEncoder.addFile(keychainDumpFile, '~_keychain_dump');
zipEncoder.close();
final content = File(archivePath).readAsBytesSync();
@@ -103,7 +104,7 @@ class BackupService {
}
Future<void> _importBackupV1(Uint8List data, String password,
{@required String nonce}) async {
{required String nonce}) async {
final appDir = await getApplicationDocumentsDirectory();
final decryptedData = await _decrypt(data, password, nonce);
final zip = ZipDecoder().decodeBytes(decryptedData);
@@ -214,7 +215,7 @@ class BackupService {
}
Future<void> _importKeychainDump(String password,
{@required String nonce,
{required String nonce,
String keychainSalt = secrets.backupKeychainSalt}) async {
final appDir = await getApplicationDocumentsDirectory();
final keychainDumpFile = File('${appDir.path}/~_keychain_dump');
@@ -251,11 +252,11 @@ class BackupService {
}
Future<Uint8List> _exportKeychainDump(String password,
{@required String nonce,
{required String nonce,
String keychainSalt = secrets.backupKeychainSalt}) async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPin = await _flutterSecureStorage.read(key: key);
final decodedPin = decodedPinCode(pin: encodedPin);
final decodedPin = decodedPinCode(pin: encodedPin!);
final wallets =
await Future.wait(_walletInfoSource.values.map((walletInfo) async {
return {
@@ -281,41 +282,42 @@ class BackupService {
}
Future<String> _exportPreferencesJSON() async {
// FIX-ME: Force unwrap
final preferences = <String, Object>{
PreferencesKey.currentWalletName:
_sharedPreferences.getString(PreferencesKey.currentWalletName),
_sharedPreferences.getString(PreferencesKey.currentWalletName)!,
PreferencesKey.currentNodeIdKey:
_sharedPreferences.getInt(PreferencesKey.currentNodeIdKey),
_sharedPreferences.getInt(PreferencesKey.currentNodeIdKey)!,
PreferencesKey.currentBalanceDisplayModeKey: _sharedPreferences
.getInt(PreferencesKey.currentBalanceDisplayModeKey),
.getInt(PreferencesKey.currentBalanceDisplayModeKey)!,
PreferencesKey.currentWalletType:
_sharedPreferences.getInt(PreferencesKey.currentWalletType),
_sharedPreferences.getInt(PreferencesKey.currentWalletType)!,
PreferencesKey.currentFiatCurrencyKey:
_sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey),
_sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!,
PreferencesKey.shouldSaveRecipientAddressKey: _sharedPreferences
.getBool(PreferencesKey.shouldSaveRecipientAddressKey),
.getBool(PreferencesKey.shouldSaveRecipientAddressKey)!,
PreferencesKey.isDarkThemeLegacy:
_sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy),
_sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy)!,
PreferencesKey.currentPinLength:
_sharedPreferences.getInt(PreferencesKey.currentPinLength),
_sharedPreferences.getInt(PreferencesKey.currentPinLength)!,
PreferencesKey.currentTransactionPriorityKeyLegacy: _sharedPreferences
.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy)!,
PreferencesKey.allowBiometricalAuthenticationKey: _sharedPreferences
.getBool(PreferencesKey.allowBiometricalAuthenticationKey),
.getBool(PreferencesKey.allowBiometricalAuthenticationKey)!,
PreferencesKey.currentBitcoinElectrumSererIdKey: _sharedPreferences
.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey),
.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey)!,
PreferencesKey.currentLanguageCode:
_sharedPreferences.getString(PreferencesKey.currentLanguageCode),
_sharedPreferences.getString(PreferencesKey.currentLanguageCode)!,
PreferencesKey.displayActionListModeKey:
_sharedPreferences.getInt(PreferencesKey.displayActionListModeKey),
_sharedPreferences.getInt(PreferencesKey.displayActionListModeKey)!,
PreferencesKey.currentTheme:
_sharedPreferences.getInt(PreferencesKey.currentTheme),
_sharedPreferences.getInt(PreferencesKey.currentTheme)!,
PreferencesKey.currentDefaultSettingsMigrationVersion: _sharedPreferences
.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion),
.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion)!,
PreferencesKey.bitcoinTransactionPriority:
_sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority),
_sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!,
PreferencesKey.moneroTransactionPriority:
_sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority),
_sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!,
};
return json.encode(preferences);
@@ -330,17 +332,26 @@ class BackupService {
Future<Uint8List> _encrypt(
Uint8List data, String secretKeySource, String nonceBase64) async {
final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource));
final secretKeyHash = await Cryptography.instance.sha256().hash(utf8.encode(secretKeySource));
final secretKey = SecretKey(secretKeyHash.bytes);
final nonce = Nonce(base64.decode(nonceBase64));
return await _cipher.encrypt(data, secretKey: secretKey, nonce: nonce);
final nonce = base64.decode(nonceBase64).toList();
final box = await _cipher.encrypt(data.toList(), secretKey: secretKey, nonce: nonce);
return Uint8List.fromList(box.cipherText);
}
Future<Uint8List> _decrypt(
Uint8List data, String secretKeySource, String nonceBase64) async {
final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource));
final secretKey = SecretKey(secretKeyHash.bytes);
final nonce = Nonce(base64.decode(nonceBase64));
return await _cipher.decrypt(data, secretKey: secretKey, nonce: nonce);
throw Exception('Unimplemented');
//final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource));
//final secretKey = SecretKey(secretKeyHash.bytes);
//final nonce = Nonce(base64.decode(nonceBase64));
//return await _cipher.decrypt(data, secretKey: secretKey, nonce: nonce);
// final secretKeyHash = await Cryptography.instance.sha256().hash(utf8.encode(secretKeySource));
// final secretKey = SecretKey(secretKeyHash.bytes);
// final nonce = base64.decode(nonceBase64).toList();
// final box = SecretBox(data.toList(), nonce: nonce, mac: Mac);
// final plainData = await _cipher.decrypt(box, secretKey: secretKey);
// return Uint8List.fromList(plainData);
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
final fiatStringified = fiat.toString();
final uri = Uri.https(fiatApiAuthority, fiatApiPath,
<String, String>{'convert': fiatStringified});
final response = await get(uri.toString());
final response = await get(uri);
if (response.statusCode != 200) {
return 0.0;
+3 -4
View File
@@ -7,15 +7,14 @@ class KeyService {
final FlutterSecureStorage _secureStorage;
Future<String> getWalletPassword({String walletName}) async {
Future<String> getWalletPassword({required String walletName}) async {
final key = generateStoreKeyFor(
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = await _secureStorage.read(key: key);
return decodeWalletPassword(password: encodedPassword);
return decodeWalletPassword(password: encodedPassword!);
}
Future<void> saveWalletPassword({String walletName, String password}) async {
Future<void> saveWalletPassword({required String walletName, required String password}) async {
final key = generateStoreKeyFor(
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = encodeWalletPassword(password: password);
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:cake_wallet/core/validator.dart';
import 'package:cw_core/crypto_currency.dart';
class MoneroLabelValidator extends TextValidator {
MoneroLabelValidator({@required CryptoCurrency type})
MoneroLabelValidator()
: super(
errorMessage: S.current.error_text_account_name,
pattern: '^[a-zA-Z0-9_ ]{1,15}\$',
+8 -7
View File
@@ -7,23 +7,24 @@ import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/utils/language_list.dart';
class SeedValidator extends Validator<MnemonicItem> {
SeedValidator({this.type, this.language})
: _words = getWordList(type: type, language: language);
SeedValidator({required this.type, required this.language})
: _words = getWordList(type: type, language: language),
super(errorMessage: 'Wrong seed mnemonic');
final WalletType type;
final String language;
final List<String> _words;
static List<String> getWordList({WalletType type, String language}) {
static List<String> getWordList({required WalletType type, required String language}) {
switch (type) {
case WalletType.bitcoin:
return getBitcoinWordList(language);
case WalletType.litecoin:
return getBitcoinWordList(language);
case WalletType.monero:
return monero.getMoneroWordList(language);
return monero!.getMoneroWordList(language);
case WalletType.haven:
return haven.getMoneroWordList(language);
return haven!.getMoneroWordList(language);
default:
return [];
}
@@ -31,9 +32,9 @@ class SeedValidator extends Validator<MnemonicItem> {
static List<String> getBitcoinWordList(String language) {
assert(language.toLowerCase() == LanguageList.english.toLowerCase());
return bitcoin.getWordList();
return bitcoin!.getWordList();
}
@override
bool isValid(MnemonicItem value) => _words.contains(value.text);
bool isValid(MnemonicItem? value) => _words.contains(value?.text);
}
+2
View File
@@ -33,4 +33,6 @@ String syncStatusTitle(SyncStatus syncStatus) {
if (syncStatus is LostConnectionSyncStatus) {
return S.current.sync_status_failed_connect;
}
return '';
}
+12 -12
View File
@@ -1,13 +1,13 @@
import 'package:flutter/foundation.dart';
abstract class Validator<T> {
Validator({@required this.errorMessage});
Validator({required this.errorMessage});
final String errorMessage;
bool isValid(T value);
bool isValid(T? value);
String call(T value) => !isValid(value) ? errorMessage : null;
String? call(T? value) => !isValid(value) ? errorMessage : null;
}
class TextValidator extends Validator<String> {
@@ -15,28 +15,28 @@ class TextValidator extends Validator<String> {
{this.minLength,
this.maxLength,
this.pattern,
String errorMessage = '',
this.length,
this.isAutovalidate = false,
String errorMessage})
this.isAutovalidate = false})
: super(errorMessage: errorMessage);
final int minLength;
final int maxLength;
final List<int> length;
final int? minLength;
final int? maxLength;
final List<int>? length;
final bool isAutovalidate;
String pattern;
String? pattern;
@override
bool isValid(String value) {
bool isValid(String? value) {
if (value == null || value.isEmpty) {
return isAutovalidate ? true : false;
}
return value.length > (minLength ?? 0) &&
(length?.contains(value.length) ?? true) &&
((maxLength ?? 0) > 0 ? (value.length <= maxLength) : true) &&
((maxLength ?? 0) > 0 ? (value.length <= maxLength!) : true) &&
(pattern != null ? match(value) : true);
}
bool match(String value) => RegExp(pattern).hasMatch(value);
bool match(String value) => pattern != null ? RegExp(pattern!).hasMatch(value) : false;
}
+11 -13
View File
@@ -14,15 +14,13 @@ import 'package:cw_core/wallet_type.dart';
class WalletCreationService {
WalletCreationService(
{WalletType initialType,
this.secureStorage,
this.keyService,
this.sharedPreferences,
this.walletInfoSource})
{required WalletType initialType,
required this.secureStorage,
required this.keyService,
required this.sharedPreferences,
required this.walletInfoSource})
: type = initialType {
if (type != null) {
changeWalletType(type: type);
}
changeWalletType(type: type);
}
WalletType type;
@@ -30,11 +28,11 @@ class WalletCreationService {
final SharedPreferences sharedPreferences;
final KeyService keyService;
final Box<WalletInfo> walletInfoSource;
WalletService _service;
WalletService? _service;
static const _isNewMoneroWalletPasswordUpdated = true;
void changeWalletType({@required WalletType type}) {
void changeWalletType({required WalletType type}) {
this.type = type;
_service = getIt.get<WalletService>(param1: type);
}
@@ -64,7 +62,7 @@ class WalletCreationService {
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
final wallet = await _service.create(credentials);
final wallet = await _service!.create(credentials);
if (wallet.type == WalletType.monero) {
await sharedPreferences
@@ -82,7 +80,7 @@ class WalletCreationService {
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
final wallet = await _service.restoreFromKeys(credentials);
final wallet = await _service!.restoreFromKeys(credentials);
if (wallet.type == WalletType.monero) {
await sharedPreferences
@@ -100,7 +98,7 @@ class WalletCreationService {
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
final wallet = await _service.restoreFromSeed(credentials);
final wallet = await _service!.restoreFromSeed(credentials);
if (wallet.type == WalletType.monero) {
await sharedPreferences
+1 -1
View File
@@ -7,7 +7,7 @@ class WalletCreating extends WalletCreationState {}
class WalletCreatedSuccessfully extends WalletCreationState {}
class WalletCreationFailure extends WalletCreationState {
WalletCreationFailure({@required this.error});
WalletCreationFailure({required this.error});
final String error;
}
+6 -9
View File
@@ -17,18 +17,15 @@ class WalletLoadingService {
final WalletService Function(WalletType type) walletServiceFactory;
Future<WalletBase> load(WalletType type, String name) async {
if (walletServiceFactory == null) {
throw Exception('WalletLoadingService.walletServiceFactory is not set');
}
final walletService = walletServiceFactory?.call(type);
final walletService = walletServiceFactory.call(type);
final password = await keyService.getWalletPassword(walletName: name);
final wallet = await walletService.openWallet(name, password);
final wallet = await walletService.openWallet(name, password);
if (type == WalletType.monero) {
await upateMoneroWalletPassword(wallet);
}
if (type == WalletType.monero) {
await upateMoneroWalletPassword(wallet);
}
return wallet;
return wallet;
}
Future<void> upateMoneroWalletPassword(WalletBase wallet) async {
+56 -58
View File
@@ -156,26 +156,26 @@ import 'package:cake_wallet/core/wallet_loading_service.dart';
final getIt = GetIt.instance;
var _isSetupFinished = false;
Box<WalletInfo> _walletInfoSource;
Box<Node> _nodeSource;
Box<Contact> _contactSource;
Box<Trade> _tradesSource;
Box<Template> _templates;
Box<ExchangeTemplate> _exchangeTemplates;
Box<TransactionDescription> _transactionDescriptionBox;
Box<Order> _ordersSource;
Box<UnspentCoinsInfo> _unspentCoinsInfoSource;
late Box<WalletInfo> _walletInfoSource;
late Box<Node> _nodeSource;
late Box<Contact> _contactSource;
late Box<Trade> _tradesSource;
late Box<Template> _templates;
late Box<ExchangeTemplate> _exchangeTemplates;
late Box<TransactionDescription> _transactionDescriptionBox;
late Box<Order> _ordersSource;
late Box<UnspentCoinsInfo>? _unspentCoinsInfoSource;
Future setup(
{Box<WalletInfo> walletInfoSource,
Box<Node> nodeSource,
Box<Contact> contactSource,
Box<Trade> tradesSource,
Box<Template> templates,
Box<ExchangeTemplate> exchangeTemplates,
Box<TransactionDescription> transactionDescriptionBox,
Box<Order> ordersSource,
Box<UnspentCoinsInfo> unspentCoinsInfoSource}) async {
{required Box<WalletInfo> walletInfoSource,
required Box<Node> nodeSource,
required Box<Contact> contactSource,
required Box<Trade> tradesSource,
required Box<Template> templates,
required Box<ExchangeTemplate> exchangeTemplates,
required Box<TransactionDescription> transactionDescriptionBox,
required Box<Order> ordersSource,
Box<UnspentCoinsInfo>? unspentCoinsInfoSource}) async {
_walletInfoSource = walletInfoSource;
_nodeSource = nodeSource;
_contactSource = contactSource;
@@ -328,9 +328,9 @@ Future setup(
.changeProcessText('ERROR: ${loginError.toString()}');
}
ReactionDisposer _reaction;
_reaction = reaction((_) => appStore.wallet, (Object _) {
_reaction?.reaction?.dispose();
ReactionDisposer? _reaction;
_reaction = reaction((_) => appStore.wallet, (Object? _) {
_reaction?.reaction.dispose();
authStore.allowed();
});
}, closable: false),
@@ -354,7 +354,7 @@ Future setup(
getIt.registerFactoryParam<WalletAddressEditOrCreateViewModel, dynamic, void>(
(dynamic item, _) => WalletAddressEditOrCreateViewModel(
wallet: getIt.get<AppStore>().wallet, item: item));
wallet: getIt.get<AppStore>().wallet!, item: item));
getIt.registerFactoryParam<AddressEditOrCreatePage, dynamic, void>(
(dynamic item, _) => AddressEditOrCreatePage(
@@ -362,13 +362,13 @@ Future setup(
getIt.get<WalletAddressEditOrCreateViewModel>(param1: item)));
getIt.registerFactory<SendTemplateViewModel>(() => SendTemplateViewModel(
getIt.get<AppStore>().wallet,
getIt.get<AppStore>().wallet!,
getIt.get<AppStore>().settingsStore,
getIt.get<SendTemplateStore>(),
getIt.get<FiatConversionStore>()));
getIt.registerFactory<SendViewModel>(() => SendViewModel(
getIt.get<AppStore>().wallet,
getIt.get<AppStore>().wallet!,
getIt.get<AppStore>().settingsStore,
getIt.get<SendTemplateViewModel>(),
getIt.get<FiatConversionStore>(),
@@ -391,14 +391,13 @@ Future setup(
WalletListPage(walletListViewModel: getIt.get<WalletListViewModel>()));
getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet;
final wallet = getIt.get<AppStore>().wallet!;
if (wallet.type == WalletType.monero || wallet.type == WalletType.haven) {
return MoneroAccountListViewModel(wallet);
}
// FIXME: throw exception.
return null;
throw Exception('Unexpected wallet type: ${wallet.type} for generate MoneroAccountListViewModel');
});
getIt.registerFactory(() => MoneroAccountListPage(
@@ -422,9 +421,9 @@ Future setup(
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel,
AccountListItem, void>(
(AccountListItem account, _) => MoneroAccountEditOrCreateViewModel(
monero.getAccountList(getIt.get<AppStore>().wallet),
haven?.getAccountList(getIt.get<AppStore>().wallet),
wallet: getIt.get<AppStore>().wallet,
monero!.getAccountList(getIt.get<AppStore>().wallet!),
haven?.getAccountList(getIt.get<AppStore>().wallet!),
wallet: getIt.get<AppStore>().wallet!,
accountListItem: account));
getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem,
@@ -436,13 +435,13 @@ Future setup(
getIt.registerFactory(() {
final appStore = getIt.get<AppStore>();
final yatStore = getIt.get<YatStore>();
return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet);
return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet!);
});
getIt.registerFactory(() => SettingsPage(getIt.get<SettingsViewModel>()));
getIt
.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet));
.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
getIt.registerFactoryParam<WalletSeedPage, bool, void>(
(bool isWalletCreated, _) => WalletSeedPage(
@@ -450,12 +449,12 @@ Future setup(
isNewWalletCreated: isWalletCreated));
getIt
.registerFactory(() => WalletKeysViewModel(getIt.get<AppStore>().wallet));
.registerFactory(() => WalletKeysViewModel(getIt.get<AppStore>().wallet!));
getIt.registerFactory(() => WalletKeysPage(getIt.get<WalletKeysViewModel>()));
getIt.registerFactoryParam<ContactViewModel, ContactRecord, void>(
(ContactRecord contact, _) =>
getIt.registerFactoryParam<ContactViewModel, ContactRecord?, void>(
(ContactRecord? contact, _) =>
ContactViewModel(_contactSource, contact: contact));
getIt.registerFactory(
@@ -465,26 +464,26 @@ Future setup(
(bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
isEditable: isEditable));
getIt.registerFactoryParam<ContactPage, ContactRecord, void>(
(ContactRecord contact, _) =>
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
(ContactRecord? contact, _) =>
ContactPage(getIt.get<ContactViewModel>(param1: contact)));
getIt.registerFactory(() {
final appStore = getIt.get<AppStore>();
return NodeListViewModel(
_nodeSource, appStore.wallet, appStore.settingsStore);
_nodeSource, appStore.wallet!, appStore.settingsStore);
});
getIt.registerFactory(() => NodeListPage(getIt.get<NodeListViewModel>()));
getIt.registerFactory(() =>
NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet));
NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet!));
getIt.registerFactory(
() => NodeCreateOrEditPage(getIt.get<NodeCreateOrEditViewModel>()));
getIt.registerFactory(() => ExchangeViewModel(
getIt.get<AppStore>().wallet,
getIt.get<AppStore>().wallet!,
_tradesSource,
getIt.get<ExchangeTemplateStore>(),
getIt.get<TradesStore>(),
@@ -493,7 +492,7 @@ Future setup(
));
getIt.registerFactory(() => ExchangeTradeViewModel(
wallet: getIt.get<AppStore>().wallet,
wallet: getIt.get<AppStore>().wallet!,
trades: _tradesSource,
tradesStore: getIt.get<TradesStore>(),
sendViewModel: getIt.get<SendViewModel>()));
@@ -513,17 +512,17 @@ Future setup(
(WalletType param1, __) {
switch (param1) {
case WalletType.haven:
return haven.createHavenWalletService(_walletInfoSource);
return haven!.createHavenWalletService(_walletInfoSource);
case WalletType.monero:
return monero.createMoneroWalletService(_walletInfoSource);
return monero!.createMoneroWalletService(_walletInfoSource);
case WalletType.bitcoin:
return bitcoin.createBitcoinWalletService(
_walletInfoSource, _unspentCoinsInfoSource);
return bitcoin!.createBitcoinWalletService(
_walletInfoSource, _unspentCoinsInfoSource!);
case WalletType.litecoin:
return bitcoin.createLitecoinWalletService(
_walletInfoSource, _unspentCoinsInfoSource);
return bitcoin!.createLitecoinWalletService(
_walletInfoSource, _unspentCoinsInfoSource!);
default:
return null;
throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
}
});
@@ -536,7 +535,7 @@ Future setup(
getIt.get<SetupPinCodeViewModel>(),
onSuccessfulPinSetup: onSuccessfulPinSetup));
getIt.registerFactory(() => RescanViewModel(getIt.get<AppStore>().wallet));
getIt.registerFactory(() => RescanViewModel(getIt.get<AppStore>().wallet!));
getIt.registerFactory(() => RescanPage(getIt.get<RescanViewModel>()));
@@ -553,7 +552,7 @@ Future setup(
getIt
.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>(
(TransactionInfo transactionInfo, _) {
final wallet = getIt.get<AppStore>().wallet;
final wallet = getIt.get<AppStore>().wallet!;
return TransactionDetailsViewModel(
transactionInfo: transactionInfo,
transactionDescriptionBox: _transactionDescriptionBox,
@@ -567,9 +566,8 @@ Future setup(
getIt.get<TransactionDetailsViewModel>(param1: transactionInfo)));
getIt.registerFactoryParam<NewWalletTypePage,
void Function(BuildContext, WalletType), bool>(
(para1, param2) => NewWalletTypePage(getIt.get<WalletNewVM>(),
onTypeSelected: para1, isNewWallet: param2));
void Function(BuildContext, WalletType), void>(
(param1, _) => NewWalletTypePage(onTypeSelected: param1));
getIt.registerFactoryParam<PreSeedPage, WalletType, void>(
(WalletType type, _) => PreSeedPage(type));
@@ -610,7 +608,7 @@ Future setup(
return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(),
getIt.get<SettingsStore>(), getIt.get<BuyAmountViewModel>(),
wallet: wallet);
wallet: wallet!);
});
getIt.registerFactory(() {
@@ -627,7 +625,7 @@ Future setup(
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) {
final wallet = getIt.get<AppStore>().wallet;
return OrderDetailsViewModel(wallet: wallet, orderForDetails: order);
return OrderDetailsViewModel(wallet: wallet!, orderForDetails: order);
});
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
@@ -641,7 +639,7 @@ Future setup(
final wallet = getIt.get<AppStore>().wallet;
return UnspentCoinsListViewModel(
wallet: wallet, unspentCoinsInfo: _unspentCoinsInfoSource);
wallet: wallet!, unspentCoinsInfo: _unspentCoinsInfoSource!);
});
getIt.registerFactory(() => UnspentCoinsListPage(
@@ -667,7 +665,7 @@ Future setup(
getIt.registerFactory(() => YatService());
getIt.registerFactory(() => AddressResolver(yatService: getIt.get<YatService>(),
walletType: getIt.get<AppStore>().wallet.type));
walletType: getIt.get<AppStore>().wallet!.type));
getIt.registerFactoryParam<FullscreenQRPage, String, bool>(
(String qrData, bool isLight) => FullscreenQRPage(qrData: qrData, isLight: isLight,));
@@ -683,7 +681,7 @@ Future setup(
() => IoniaAnyPay(
getIt.get<IoniaService>(),
getIt.get<AnyPayApi>(),
getIt.get<AppStore>().wallet));
getIt.get<AppStore>().wallet!));
getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get<IoniaService>()));
+1 -1
View File
@@ -18,7 +18,7 @@ int serializeActionlistDisplayModes(List<ActionListDisplayMode> modes) {
}
List<ActionListDisplayMode> deserializeActionlistDisplayModes(int raw) {
final modes = List<ActionListDisplayMode>();
final modes = <ActionListDisplayMode>[];
if (raw == 1 || raw - 10 == 1) {
modes.add(ActionListDisplayMode.trades);
+3 -3
View File
@@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/enumerable_item.dart';
class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
const BalanceDisplayMode({@required String title, @required int raw})
const BalanceDisplayMode({required String title, required int raw})
: super(title: title, raw: raw);
static const all = [
@@ -18,7 +18,7 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
static const displayableBalance =
BalanceDisplayMode(raw: 3, title: 'Displayable Balance');
static BalanceDisplayMode deserialize({int raw}) {
static BalanceDisplayMode deserialize({required int raw}) {
switch (raw) {
case 0:
return fullBalance;
@@ -29,7 +29,7 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
case 3:
return displayableBalance;
default:
return null;
throw Exception('Unexpected token: $raw for BalanceDisplayMode deserialize');
}
}
+3 -2
View File
@@ -9,8 +9,9 @@ class BiometricAuth {
try {
return await _localAuth.authenticate(
localizedReason: S.current.biometric_auth_reason,
useErrorDialogs: true,
stickyAuth: false);
options: AuthenticationOptions(
useErrorDialogs: true,
stickyAuth: false));
} on PlatformException catch (e) {
print(e);
}
+1 -1
View File
@@ -1,4 +1,4 @@
String calculateFiatAmount({double price, String cryptoAmount}) {
String calculateFiatAmount({double? price, String? cryptoAmount}) {
if (price == null || cryptoAmount == null) {
return '0.00';
}
+1 -1
View File
@@ -1,4 +1,4 @@
String calculateFiatAmountRaw({double price, double cryptoAmount}) {
String calculateFiatAmountRaw({required double cryptoAmount, double? price}) {
if (price == null) {
return '0.00';
}
+7 -4
View File
@@ -8,8 +8,11 @@ part 'contact.g.dart';
@HiveType(typeId: Contact.typeId)
class Contact extends HiveObject with Keyable {
Contact({@required this.name, @required this.address, CryptoCurrency type})
: raw = type?.raw;
Contact({required this.name, required this.address, CryptoCurrency? type}) {
if (type != null) {
raw = type.raw;
}
}
static const typeId = 0;
static const boxName = 'Contacts';
@@ -21,7 +24,7 @@ class Contact extends HiveObject with Keyable {
String address;
@HiveField(2)
int raw;
late int raw;
CryptoCurrency get type => CryptoCurrency.deserialize(raw: raw);
@@ -34,6 +37,6 @@ class Contact extends HiveObject with Keyable {
@override
int get hashCode => key.hashCode;
void updateCryptoCurrency({@required CryptoCurrency currency}) =>
void updateCryptoCurrency({required CryptoCurrency currency}) =>
raw = currency.raw;
}
+2
View File
@@ -1,6 +1,8 @@
import 'package:cw_core/crypto_currency.dart';
abstract class ContactBase {
ContactBase(this.name, this.address, this.type);
String name;
String address;
+4 -1
View File
@@ -13,7 +13,10 @@ abstract class ContactRecordBase extends Record<Contact>
with Store
implements ContactBase {
ContactRecordBase(Box<Contact> source, Contact original)
: super(source, original);
: name = original.name,
address = original.address,
type = original.type,
super(source, original);
@override
@observable
+60 -68
View File
@@ -18,6 +18,7 @@ import 'package:cake_wallet/entities/fs_migration.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cake_wallet/exchange/trade.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:collection/collection.dart';
const newCakeWalletMoneroUri = 'xmr-node.cakewallet.com:18081';
const cakeWalletBitcoinElectrumUri = 'electrum.cakewallet.com:50002';
@@ -25,13 +26,13 @@ const cakeWalletLitecoinElectrumUri = 'ltc-electrum.cakewallet.com:50002';
const havenDefaultNodeUri = 'nodes.havenprotocol.org:443';
Future defaultSettingsMigration(
{@required int version,
@required SharedPreferences sharedPreferences,
@required FlutterSecureStorage secureStorage,
@required Box<Node> nodes,
@required Box<WalletInfo> walletInfoSource,
@required Box<Trade> tradeSource,
@required Box<Contact> contactSource}) async {
{required int version,
required SharedPreferences sharedPreferences,
required FlutterSecureStorage secureStorage,
required Box<Node> nodes,
required Box<WalletInfo> walletInfoSource,
required Box<Trade> tradeSource,
required Box<Contact> contactSource}) async {
if (Platform.isIOS) {
await ios_migrate_v1(walletInfoSource, tradeSource, contactSource);
}
@@ -56,7 +57,7 @@ Future defaultSettingsMigration(
FiatCurrency.usd.toString());
await sharedPreferences.setInt(
PreferencesKey.currentTransactionPriorityKeyLegacy,
monero.getDefaultTransactionPriority().raw);
monero!.getDefaultTransactionPriority().raw);
await sharedPreferences.setInt(
PreferencesKey.currentBalanceDisplayModeKey,
BalanceDisplayMode.availableBalance.raw);
@@ -147,7 +148,7 @@ Future defaultSettingsMigration(
'current_default_settings_migration_version', version);
}
Future<void> replaceNodesMigration({@required Box<Node> nodes}) async {
Future<void> replaceNodesMigration({required Box<Node> nodes}) async {
final replaceNodes = <String, Node>{
'eu-node.cakewallet.io:18081':
Node(uri: 'xmr-node-eu.cakewallet.com:18081', type: WalletType.monero),
@@ -170,39 +171,33 @@ Future<void> replaceNodesMigration({@required Box<Node> nodes}) async {
}
Future<void> changeMoneroCurrentNodeToDefault(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes}) async {
{required SharedPreferences sharedPreferences,
required Box<Node> nodes}) async {
final node = getMoneroDefaultNode(nodes: nodes);
final nodeId = node?.key as int ?? 0; // 0 - England
await sharedPreferences.setInt('current_node_id', nodeId);
}
Node getBitcoinDefaultElectrumServer({@required Box<Node> nodes}) {
return nodes.values.firstWhere(
(Node node) => node.uri == cakeWalletBitcoinElectrumUri,
orElse: () => null) ??
nodes.values.firstWhere((node) => node.type == WalletType.bitcoin,
orElse: () => null);
Node? getBitcoinDefaultElectrumServer({required Box<Node> nodes}) {
return nodes.values.firstWhereOrNull(
(Node node) => node.uriRaw == cakeWalletBitcoinElectrumUri)
?? nodes.values.firstWhereOrNull((node) => node.type == WalletType.bitcoin);
}
Node getLitecoinDefaultElectrumServer({@required Box<Node> nodes}) {
return nodes.values.firstWhere(
(Node node) => node.uri == cakeWalletLitecoinElectrumUri,
orElse: () => null) ??
nodes.values.firstWhere((node) => node.type == WalletType.litecoin,
orElse: () => null);
Node? getLitecoinDefaultElectrumServer({required Box<Node> nodes}) {
return nodes.values.firstWhereOrNull(
(Node node) => node.uriRaw == cakeWalletLitecoinElectrumUri)
?? nodes.values.firstWhereOrNull((node) => node.type == WalletType.litecoin);
}
Node getHavenDefaultNode({@required Box<Node> nodes}) {
return nodes.values.firstWhere(
(Node node) => node.uriRaw == havenDefaultNodeUri,
orElse: () => null) ??
nodes.values.firstWhere((node) => node.type == WalletType.haven,
orElse: () => null);
Node? getHavenDefaultNode({required Box<Node> nodes}) {
return nodes.values.firstWhereOrNull(
(Node node) => node.uriRaw == havenDefaultNodeUri)
?? nodes.values.firstWhereOrNull((node) => node.type == WalletType.haven);
}
Node getMoneroDefaultNode({@required Box<Node> nodes}) {
Node getMoneroDefaultNode({required Box<Node> nodes}) {
final timeZone = DateTime.now().timeZoneOffset.inHours;
var nodeUri = '';
@@ -214,14 +209,17 @@ Node getMoneroDefaultNode({@required Box<Node> nodes}) {
nodeUri = 'xmr-node-usa-east.cakewallet.com:18081';
}
return nodes.values
.firstWhere((Node node) => node.uri == nodeUri, orElse: () => null) ??
nodes.values.first;
try {
return nodes.values
.firstWhere((Node node) => node.uriRaw == nodeUri);
} catch(_) {
return nodes.values.first;
}
}
Future<void> changeBitcoinCurrentElectrumServerToDefault(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes}) async {
{required SharedPreferences sharedPreferences,
required Box<Node> nodes}) async {
final server = getBitcoinDefaultElectrumServer(nodes: nodes);
final serverId = server?.key as int ?? 0;
@@ -229,8 +227,8 @@ Future<void> changeBitcoinCurrentElectrumServerToDefault(
}
Future<void> changeLitecoinCurrentElectrumServerToDefault(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes}) async {
{required SharedPreferences sharedPreferences,
required Box<Node> nodes}) async {
final server = getLitecoinDefaultElectrumServer(nodes: nodes);
final serverId = server?.key as int ?? 0;
@@ -238,8 +236,8 @@ Future<void> changeLitecoinCurrentElectrumServerToDefault(
}
Future<void> changeHavenCurrentNodeToDefault(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes}) async {
{required SharedPreferences sharedPreferences,
required Box<Node> nodes}) async {
final node = getHavenDefaultNode(nodes: nodes);
final nodeId = node?.key as int ?? 0;
@@ -247,8 +245,8 @@ Future<void> changeHavenCurrentNodeToDefault(
}
Future<void> replaceDefaultNode(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes}) async {
{required SharedPreferences sharedPreferences,
required Box<Node> nodes}) async {
const nodesForReplace = <String>[
'xmr-node-uk.cakewallet.com:18081',
'eu-node.cakewallet.io:18081',
@@ -256,9 +254,9 @@ Future<void> replaceDefaultNode(
];
final currentNodeId = sharedPreferences.getInt('current_node_id');
final currentNode =
nodes.values.firstWhere((Node node) => node.key == currentNodeId);
nodes.values.firstWhereOrNull((Node node) => node.key == currentNodeId);
final needToReplace =
currentNode == null ? true : nodesForReplace.contains(currentNode.uri);
currentNode == null ? true : nodesForReplace.contains(currentNode.uriRaw);
if (!needToReplace) {
return;
@@ -268,7 +266,7 @@ Future<void> replaceDefaultNode(
sharedPreferences: sharedPreferences, nodes: nodes);
}
Future<void> updateNodeTypes({@required Box<Node> nodes}) async {
Future<void> updateNodeTypes({required Box<Node> nodes}) async {
nodes.values.forEach((node) async {
if (node.type == null) {
node.type = WalletType.monero;
@@ -277,17 +275,17 @@ Future<void> updateNodeTypes({@required Box<Node> nodes}) async {
});
}
Future<void> addBitcoinElectrumServerList({@required Box<Node> nodes}) async {
Future<void> addBitcoinElectrumServerList({required Box<Node> nodes}) async {
final serverList = await loadBitcoinElectrumServerList();
await nodes.addAll(serverList);
}
Future<void> addLitecoinElectrumServerList({@required Box<Node> nodes}) async {
Future<void> addLitecoinElectrumServerList({required Box<Node> nodes}) async {
final serverList = await loadLitecoinElectrumServerList();
await nodes.addAll(serverList);
}
Future<void> addHavenNodeList({@required Box<Node> nodes}) async {
Future<void> addHavenNodeList({required Box<Node> nodes}) async {
final nodeList = await loadDefaultHavenNodes();
await nodes.addAll(nodeList);
}
@@ -318,7 +316,7 @@ Future<void> addAddressesForMoneroWallets(
Future<void> updateDisplayModes(SharedPreferences sharedPreferences) async {
final currentBalanceDisplayMode =
sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey);
sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey) ?? -1;
final balanceDisplayMode = currentBalanceDisplayMode < 2 ? 3 : 2;
await sharedPreferences.setInt(
PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode);
@@ -338,11 +336,11 @@ Future<void> generateBackupPassword(FlutterSecureStorage secureStorage) async {
Future<void> changeTransactionPriorityAndFeeRateKeys(
SharedPreferences sharedPreferences) async {
final legacyTransactionPriority = sharedPreferences
.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy);
.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy)!;
await sharedPreferences.setInt(
PreferencesKey.moneroTransactionPriority, legacyTransactionPriority);
await sharedPreferences.setInt(PreferencesKey.bitcoinTransactionPriority,
bitcoin.getMediumTransactionPriority().serialize());
bitcoin!.getMediumTransactionPriority().serialize());
}
Future<void> changeDefaultMoneroNode(
@@ -383,18 +381,14 @@ Future<void> checkCurrentNodes(
.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
final currentHavenNodeId = sharedPreferences
.getInt(PreferencesKey.currentHavenNodeIdKey);
final currentMoneroNode = nodeSource.values.firstWhere(
(node) => node.key == currentMoneroNodeId,
orElse: () => null);
final currentBitcoinElectrumServer = nodeSource.values.firstWhere(
(node) => node.key == currentBitcoinElectrumSeverId,
orElse: () => null);
final currentLitecoinElectrumServer = nodeSource.values.firstWhere(
(node) => node.key == currentLitecoinElectrumSeverId,
orElse: () => null);
final currentHavenNodeServer = nodeSource.values.firstWhere(
(node) => node.key == currentHavenNodeId,
orElse: () => null);
final currentMoneroNode = nodeSource.values.firstWhereOrNull(
(node) => node.key == currentMoneroNodeId);
final currentBitcoinElectrumServer = nodeSource.values.firstWhereOrNull(
(node) => node.key == currentBitcoinElectrumSeverId);
final currentLitecoinElectrumServer = nodeSource.values.firstWhereOrNull(
(node) => node.key == currentLitecoinElectrumSeverId);
final currentHavenNodeServer = nodeSource.values.firstWhereOrNull(
(node) => node.key == currentHavenNodeId);
if (currentMoneroNode == null) {
final newCakeWalletNode =
@@ -435,12 +429,10 @@ Future<void> resetBitcoinElectrumServer(
Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
final currentElectrumSeverId =
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
final oldElectrumServer = nodeSource.values.firstWhere(
(node) => node.uri.toString().contains('electrumx.cakewallet.com'),
orElse: () => null);
var cakeWalletNode = nodeSource.values.firstWhere(
(node) => node.uri.toString() == cakeWalletBitcoinElectrumUri,
orElse: () => null);
final oldElectrumServer = nodeSource.values.firstWhereOrNull(
(node) => node.uri.toString().contains('electrumx.cakewallet.com'));
var cakeWalletNode = nodeSource.values.firstWhereOrNull(
(node) => node.uri.toString() == cakeWalletBitcoinElectrumUri);
if (cakeWalletNode == null) {
cakeWalletNode =
+13 -11
View File
@@ -1,8 +1,8 @@
import 'package:encrypt/encrypt.dart';
import 'package:password/password.dart';
// import 'package:password/password.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
String encrypt({String source, String key, int keyLength = 16}) {
String encrypt({required String source, required String key, int keyLength = 16}) {
final _key = Key.fromUtf8(key);
final iv = IV.fromLength(keyLength);
final encrypter = Encrypter(AES(_key));
@@ -11,7 +11,7 @@ String encrypt({String source, String key, int keyLength = 16}) {
return encrypted.base64;
}
String decrypt({String source, String key, int keyLength = 16}) {
String decrypt({required String source, required String key, int keyLength = 16}) {
final _key = Key.fromUtf8(key);
final iv = IV.fromLength(keyLength);
final encrypter = Encrypter(AES(_key));
@@ -20,33 +20,35 @@ String decrypt({String source, String key, int keyLength = 16}) {
return decrypted;
}
String hash({String source}) {
final algorithm = PBKDF2();
final hash = Password.hash(source, algorithm);
String hash({required String source}) {
// FIX-ME: Uninplemented
throw Exception('Unimplemented');
// final algorithm = PBKDF2();
// final hash = Password.hash(source, algorithm);
return hash;
// return hash;
}
String encodedPinCode({String pin}) {
String encodedPinCode({required String pin}) {
final source = '${secrets.salt}$pin';
return encrypt(source: source, key: secrets.key);
}
String decodedPinCode({String pin}) {
String decodedPinCode({required String pin}) {
final decrypted = decrypt(source: pin, key: secrets.key);
return decrypted.substring(secrets.key.length, decrypted.length);
}
String encodeWalletPassword({String password}) {
String encodeWalletPassword({required String password}) {
final source = password;
final _key = secrets.shortKey + secrets.walletSalt;
return encrypt(source: source, key: _key);
}
String decodeWalletPassword({String password}) {
String decodeWalletPassword({required String password}) {
final source = password;
final _key = secrets.shortKey + secrets.walletSalt;
+2 -2
View File
@@ -1,7 +1,7 @@
import 'package:cw_core/enumerable_item.dart';
class FiatCurrency extends EnumerableItem<String> with Serializable<String> {
const FiatCurrency({String symbol, this.countryCode, this.fullName}) : super(title: symbol, raw: symbol);
const FiatCurrency({required String symbol, required this.countryCode, required this.fullName}) : super(title: symbol, raw: symbol);
final String countryCode;
final String fullName;
@@ -81,7 +81,7 @@ class FiatCurrency extends EnumerableItem<String> with Serializable<String> {
FiatCurrency.vef.raw: FiatCurrency.vef
};
static FiatCurrency deserialize({String raw}) => _all[raw];
static FiatCurrency deserialize({required String raw}) => _all[raw]!;
@override
bool operator ==(Object other) => other is FiatCurrency && other.raw == raw;
+1 -1
View File
@@ -46,7 +46,7 @@ class FioAddressProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected response http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
+53 -26
View File
@@ -1,5 +1,6 @@
import 'dart:io';
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:hive/hive.dart';
@@ -61,31 +62,45 @@ Future<void> ios_migrate_user_defaults() async {
//should we provide default btc node key?
final activeCurrency = await ios_legacy_helper.getInt('currency');
final convertedCurrency = convertFiatLegacy(activeCurrency);
if (convertedCurrency != null) {
await prefs.setString(
if (activeCurrency != null) {
final convertedCurrency = convertFiatLegacy(activeCurrency);
if (convertedCurrency != null) {
await prefs.setString(
'current_fiat_currency', convertedCurrency.serialize());
}
}
//translate fee priority
final activeFeeTier = await ios_legacy_helper.getInt('saved_fee_priority');
await prefs.setInt('current_fee_priority', activeFeeTier);
if (activeFeeTier != null) {
await prefs.setInt('current_fee_priority', activeFeeTier);
}
//translate current balance mode
final currentBalanceMode =
await ios_legacy_helper.getInt('display_balance_mode');
await prefs.setInt('current_balance_display_mode', currentBalanceMode);
if (currentBalanceMode != null) {
await prefs.setInt('current_balance_display_mode', currentBalanceMode);
}
//translate should save recipient address
final shouldSave =
await ios_legacy_helper.getBool('should_save_recipient_address');
await prefs.setBool('save_recipient_address', shouldSave);
if (shouldSave != null) {
await prefs.setBool('save_recipient_address', shouldSave);
}
//translate biometric
final biometricOn =
await ios_legacy_helper.getBool('biometric_authentication_on');
await prefs.setBool('allow_biometrical_authentication', biometricOn);
if (biometricOn != null) {
await prefs.setBool('allow_biometrical_authentication', biometricOn);
}
//read the current theme as integer, write it back as a bool
final currentTheme = prefs.getInt('current-theme');
@@ -97,11 +112,17 @@ Future<void> ios_migrate_user_defaults() async {
//assign the pin length
final pinLength = await ios_legacy_helper.getInt('pin-length');
await prefs.setInt(PreferencesKey.currentPinLength, pinLength);
if (pinLength != null) {
await prefs.setInt(PreferencesKey.currentPinLength, pinLength);
}
//default value for display list key?
final walletName = await ios_legacy_helper.getString('current_wallet_name');
await prefs.setString('current_wallet_name', walletName);
if (walletName != null) {
await prefs.setString('current_wallet_name', walletName);
}
await prefs.setInt('current_wallet_type', serializeToInt(WalletType.monero));
@@ -117,7 +138,13 @@ Future<void> ios_migrate_pin() async {
final flutterSecureStorage = FlutterSecureStorage();
final pinPassword = await flutterSecureStorage.read(
key: 'pin_password', iOptions: IOSOptions(syncFlag: "syna"));
key: 'pin_password', iOptions: IOSOptions());
// No pin
if (pinPassword == null) {
await prefs.setBool('ios_migration_pin_completed', true);
return;
}
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPassword = encodedPinCode(pin: pinPassword);
await flutterSecureStorage.write(key: key, value: encodedPassword);
@@ -148,9 +175,9 @@ Future<void> ios_migrate_wallet_passwords() async {
final name = item.path.split('/').last;
final oldKey = 'wallet_monero_' + name + '_password';
final password = await flutterSecureStorage.read(
key: oldKey, iOptions: IOSOptions(syncFlag: "syna"));
key: oldKey, iOptions: IOSOptions());
await keyService.saveWalletPassword(
walletName: name, password: password);
walletName: name, password: password!);
}
} catch (e) {
print(e.toString());
@@ -197,14 +224,14 @@ FiatCurrency convertFiatLegacy(int raw) {
32: 'zar',
33: 'vef'
};
final fiatAsString = _map[raw];
final fiatAsString = _map[raw]!;
return FiatCurrency.deserialize(raw: fiatAsString.toUpperCase());
}
Future<void> android_migrate_hives({Directory appDocDir}) async {
Future<void> android_migrate_hives({required Directory appDocDir}) async {
final dbDir = Directory('${appDocDir.path}/db');
final files = List<File>();
final files = <File>[];
appDocDir.listSync().forEach((FileSystemEntity item) {
final ext = item.path.split('.').last;
@@ -225,10 +252,10 @@ Future<void> android_migrate_hives({Directory appDocDir}) async {
});
}
Future<void> android_migrate_wallets({Directory appDocDir}) async {
Future<void> android_migrate_wallets({required Directory appDocDir}) async {
final walletsDir = Directory('${appDocDir.path}/wallets');
final moneroWalletsDir = Directory('${walletsDir.path}/monero');
final dirs = List<Directory>();
final dirs = <Directory>[];
appDocDir.listSync().forEach((FileSystemEntity item) {
final name = item.path.split('/').last;
@@ -292,9 +319,8 @@ Future<void> ios_migrate_wallet_info(Box<WalletInfo> walletsInfoSource) async {
'_' +
name;
final exist = walletsInfoSource.values
.firstWhere((el) => el.id == id, orElse: () => null) !=
null;
.firstWhereOrNull((el) => el.id == id) != null;
if (exist) {
return null;
}
@@ -307,7 +333,8 @@ Future<void> ios_migrate_wallet_info(Box<WalletInfo> walletsInfoSource) async {
restoreHeight: 0,
date: date,
dirPath: item.path,
path: '${item.path}/$name');
path: '${item.path}/$name',
address: '');
return walletInfo;
}
@@ -317,8 +344,8 @@ Future<void> ios_migrate_wallet_info(Box<WalletInfo> walletsInfoSource) async {
}
})
.where((el) => el != null)
.whereType<WalletInfo>()
.toList();
print(infoRecords);
await walletsInfoSource.addAll(infoRecords);
await prefs.setBool('ios_migration_wallet_info_completed', true);
} catch (e) {
@@ -346,8 +373,8 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
final content = file.readAsBytesSync();
final flutterSecureStorage = FlutterSecureStorage();
final masterPassword = await flutterSecureStorage.read(
key: 'master_password', iOptions: IOSOptions(syncFlag: "syna"));
final key = masterPassword.replaceAll('-', '');
key: 'master_password', iOptions: IOSOptions());
final key = masterPassword!.replaceAll('-', '');
final decoded =
await ios_legacy_helper.decrypt(content, key: key, salt: secrets.salt);
final decodedJson = json.decode(decoded) as List<dynamic>;
@@ -362,7 +389,7 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
final from = CryptoCurrency.fromString(fromAsString);
final timestamp = dateAsDouble.toInt() * 1000;
final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
ExchangeProviderDescription provider;
ExchangeProviderDescription? provider;
switch (providerAsString.toLowerCase()) {
case 'changenow':
@@ -379,7 +406,7 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
}
return Trade(
id: tradeId, provider: provider, from: from, to: to, createdAt: date);
id: tradeId, provider: provider!, from: from, to: to, createdAt: date, amount: '');
});
await tradeSource.addAll(trades);
await prefs.setBool('ios_migration_trade_list_completed', true);
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
Future<List<int>> getEncryptionKey(
{String forKey, FlutterSecureStorage secureStorage}) async {
{required String forKey, required FlutterSecureStorage secureStorage}) async {
final stringifiedKey =
await secureStorage.read(key: 'transactionDescriptionsBoxKey');
List<int> key;
+10 -10
View File
@@ -7,19 +7,19 @@ const platform =
const MethodChannel('com.cakewallet.cakewallet/legacy_wallet_migration');
Future<String> decrypt(Uint8List bytes,
{@required String key, @required String salt}) async =>
await platform
.invokeMethod('decrypt', {'bytes': bytes, 'key': key, 'salt': salt});
{required String key, required String salt}) async =>
(await platform
.invokeMethod<String>('decrypt', {'bytes': bytes, 'key': key, 'salt': salt}))!;
Future<dynamic> readUserDefaults(String key, {@required String type}) async =>
Future<dynamic> readUserDefaults(String key, {required String type}) async =>
await platform
.invokeMethod<dynamic>('read_user_defaults', {'key': key, 'type': type});
Future<String> getString(String key) async =>
await readUserDefaults(key, type: 'string') as String;
Future<String?> getString(String key) async =>
await readUserDefaults(key, type: 'string') as String?;
Future<bool> getBool(String key) async =>
await readUserDefaults(key, type: 'bool') as bool;
Future<bool?> getBool(String key) async =>
await readUserDefaults(key, type: 'bool') as bool?;
Future<int> getInt(String key) async =>
await readUserDefaults(key, type: 'int') as int;
Future<int?> getInt(String key) async =>
await readUserDefaults(key, type: 'int') as int?;
+1 -1
View File
@@ -50,7 +50,7 @@ class LanguageService {
}
static Future<String> localeDetection() async {
var locale = await Devicelocale.currentLocale;
var locale = await Devicelocale.currentLocale ?? '';
locale = Intl.shortLocale(locale);
return list.keys.contains(locale) ? locale : 'en';
+5
View File
@@ -15,6 +15,11 @@ Future<void> loadCurrentWallet() async {
final typeRaw =
getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType) ??
0;
if (name == null) {
throw Exception('Incorrect current wallet name: $name');
}
final type = deserializeFromInt(typeRaw);
final walletLoadingService = getIt.get<WalletLoadingService>();
final wallet = await walletLoadingService.load(type, name);
+1 -1
View File
@@ -1,5 +1,5 @@
class MnemonicItem {
MnemonicItem({String text}) : _text = text;
MnemonicItem({required String text}) : _text = text;
String get text => _text;
String _text;
+34 -34
View File
@@ -6,68 +6,68 @@ import 'package:cw_core/wallet_type.dart';
Future<List<Node>> loadDefaultNodes() async {
final nodesRaw = await rootBundle.loadString('assets/node_list.yml');
final nodes = loadYaml(nodesRaw) as YamlList;
final loadedNodes = loadYaml(nodesRaw) as YamlList;
final nodes = <Node>[];
return nodes.map((dynamic raw) {
for (final raw in loadedNodes) {
if (raw is Map) {
final node = Node.fromMap(raw);
node?.type = WalletType.monero;
return node;
final node = Node.fromMap(raw as Map<String, Object>);
node.type = WalletType.monero;
nodes.add(node);
}
}
return null;
}).toList();
return nodes;
}
Future<List<Node>> loadBitcoinElectrumServerList() async {
final serverListRaw =
await rootBundle.loadString('assets/bitcoin_electrum_server_list.yml');
final serverList = loadYaml(serverListRaw) as YamlList;
final loadedServerList = loadYaml(serverListRaw) as YamlList;
final serverList = <Node>[];
return serverList.map((dynamic raw) {
if (raw is Map) {
final node = Node.fromMap(raw);
node?.type = WalletType.bitcoin;
return node;
for (final raw in loadedServerList) {
if (raw is Map) {
final node = Node.fromMap(raw as Map<String, Object>);
node.type = WalletType.bitcoin;
serverList.add(node);
}
}
return null;
}).toList();
return serverList;
}
Future<List<Node>> loadLitecoinElectrumServerList() async {
final serverListRaw =
await rootBundle.loadString('assets/litecoin_electrum_server_list.yml');
final serverList = loadYaml(serverListRaw) as YamlList;
final loadedServerList = loadYaml(serverListRaw) as YamlList;
final serverList = <Node>[];
return serverList.map((dynamic raw) {
for (final raw in loadedServerList) {
if (raw is Map) {
final node = Node.fromMap(raw);
node?.type = WalletType.litecoin;
return node;
final node = Node.fromMap(raw as Map<String, Object>);
node.type = WalletType.litecoin;
serverList.add(node);
}
}
return null;
}).toList();
return serverList;
}
Future<List<Node>> loadDefaultHavenNodes() async {
final nodesRaw = await rootBundle.loadString('assets/haven_node_list.yml');
final nodes = loadYaml(nodesRaw) as YamlList;
final loadedNodes = loadYaml(nodesRaw) as YamlList;
final nodes = <Node>[];
return nodes.map((dynamic raw) {
for (final raw in loadedNodes) {
if (raw is Map) {
final node = Node.fromMap(raw);
node?.type = WalletType.haven;
return node;
final node = Node.fromMap(raw as Map<String, Object>);
node.type = WalletType.haven;
nodes.add(node);
}
return null;
}).toList();
}
return nodes;
}
Future resetToDefault(Box<Node> nodeSource) async {
+5 -6
View File
@@ -1,12 +1,11 @@
import 'package:basic_utils/basic_utils.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
class OpenaliasRecord {
OpenaliasRecord({
this.address,
this.name,
this.description,
required this.address,
required this.name,
required this.description,
});
final String name;
@@ -24,8 +23,8 @@ class OpenaliasRecord {
}
static Future<OpenaliasRecord> fetchAddressAndName({
@required String formattedName,
@required String ticker,
required String formattedName,
required String ticker,
}) async {
String address = formattedName;
String name = formattedName;
+1 -1
View File
@@ -9,7 +9,7 @@ import 'package:cake_wallet/entities/fio_address_provider.dart';
class AddressResolver {
AddressResolver({@required this.yatService, this.walletType});
AddressResolver({required this.yatService, required this.walletType});
final YatService yatService;
final WalletType walletType;
+16 -17
View File
@@ -6,47 +6,42 @@ enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed }
class ParsedAddress {
ParsedAddress({
this.addresses,
required this.addresses,
this.name = '',
this.description = '',
this.parseFrom = ParseFrom.notParsed,
});
final List<String> addresses;
final String name;
final String description;
final ParseFrom parseFrom;
factory ParsedAddress.fetchEmojiAddress({
@required List<YatRecord> addresses,
@required String name,
List<YatRecord>? addresses,
required String name,
}){
if (addresses?.isEmpty ?? true) {
return ParsedAddress(
addresses: [name], parseFrom: ParseFrom.yatRecord);
}
}
return ParsedAddress(
addresses: addresses.map((e) => e.address).toList(),
addresses: addresses!.map((e) => e.address).toList(),
name: name,
parseFrom: ParseFrom.yatRecord,
);
}
factory ParsedAddress.fetchUnstoppableDomainAddress({
@required String address,
@required String name,
String? address,
required String name,
}){
if (address?.isEmpty ?? true) {
if (address?.isEmpty ?? true) {
return ParsedAddress(addresses: [name]);
}
return ParsedAddress(
addresses: [address],
addresses: [address!],
name: name,
parseFrom: ParseFrom.unstoppableDomains,
);
}
factory ParsedAddress.fetchOpenAliasAddress({@required OpenaliasRecord record, @required String name}){
factory ParsedAddress.fetchOpenAliasAddress({OpenaliasRecord? record, required String name}){
final formattedName = OpenaliasRecord.formatDomainName(name);
if (record == null || record.address.contains(formattedName)) {
return ParsedAddress(addresses: [name]);
@@ -59,12 +54,16 @@ class ParsedAddress {
);
}
factory ParsedAddress.fetchFioAddress({@required String address, @required String name}){
factory ParsedAddress.fetchFioAddress({required String address, required String name}){
return ParsedAddress(
addresses: [address],
name: name,
parseFrom: ParseFrom.fio,
);
}
final List<String> addresses;
final String name;
final String description;
final ParseFrom parseFrom;
}
+11 -9
View File
@@ -1,15 +1,17 @@
import 'package:barcode_scan/barcode_scan.dart';
// import 'package:barcode_scan/barcode_scan.dart';
var isQrScannerShown = false;
Future<String> presentQRScanner() async {
isQrScannerShown = true;
try {
final result = await BarcodeScanner.scan();
isQrScannerShown = false;
return result.rawContent;
} catch (e) {
isQrScannerShown = false;
rethrow;
}
// FIX-ME: BarcodeScanner
throw Exception('Unimplemented');
// try {
// final result = await BarcodeScanner.scan();
// isQrScannerShown = false;
// return result.rawContent;
// } catch (e) {
// isQrScannerShown = false;
// rethrow;
// }
}
+1 -1
View File
@@ -27,7 +27,7 @@ abstract class Record<T extends HiveObject> with Keyable {
final Box<T> _source;
StreamSubscription<BoxEvent> _listener;
StreamSubscription<BoxEvent>? _listener;
void fromBind(T original);
+1 -1
View File
@@ -5,7 +5,7 @@ const pinCodePassword = "PIN_CODE_PASSWORD";
const backupPassword = "BACKUP_CODE_PASSWORD";
String generateStoreKeyFor({
SecretStoreKey key,
required SecretStoreKey key,
String walletName = "",
}) {
var _key = "";
+8 -1
View File
@@ -4,7 +4,14 @@ part 'template.g.dart';
@HiveType(typeId: Template.typeId)
class Template extends HiveObject {
Template({this.name,this.isCurrencySelected, this.address, this.cryptoCurrency, this.amount, this.fiatCurrency, this.amountFiat});
Template({
required this.name,
required this.isCurrencySelected,
required this.address,
required this.cryptoCurrency,
required this.amount,
required this.fiatCurrency,
required this.amountFiat});
static const typeId = 6;
static const boxName = 'Template';
+3 -3
View File
@@ -4,7 +4,7 @@ part 'transaction_description.g.dart';
@HiveType(typeId: TransactionDescription.typeId)
class TransactionDescription extends HiveObject {
TransactionDescription({this.id, this.recipientAddress, this.transactionNote});
TransactionDescription({required this.id, this.recipientAddress, this.transactionNote});
static const typeId = 2;
static const boxName = 'TransactionDescriptions';
@@ -14,10 +14,10 @@ class TransactionDescription extends HiveObject {
String id;
@HiveField(1)
String recipientAddress;
String? recipientAddress;
@HiveField(2)
String transactionNote;
String? transactionNote;
String get note => transactionNote ?? '';
}
+3
View File
@@ -2,6 +2,9 @@ import 'package:mobx/mobx.dart';
import 'package:cw_core/transaction_info.dart';
abstract class TransactionHistory {
TransactionHistory()
: transactions = Observable<List<TransactionInfo>>([]);
Observable<List<TransactionInfo>> transactions;
Future<List<TransactionInfo>> getAll();
Future update();
+2 -2
View File
@@ -6,13 +6,13 @@ Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async
var address = '';
try {
address = await channel.invokeMethod(
address = await channel.invokeMethod<String>(
'getUnstoppableDomainAddress',
<String, String> {
'domain' : domain,
'ticker' : ticker
}
);
) ?? '';
} catch (e) {
print('Unstoppable domain error: ${e.toString()}');
address = '';
+17 -12
View File
@@ -4,18 +4,23 @@ import 'package:cw_core/monero_amount_format.dart';
import 'package:cake_wallet/haven/haven.dart';
Future<void> updateHavenRate(FiatConversionStore fiatConversionStore) async {
final rate = haven.getAssetRate();
final base = rate.firstWhere((row) => row.asset == 'XUSD', orElse: () => null);
rate.forEach((row) {
final cur = CryptoCurrency.fromString(row.asset);
final baseRate = moneroAmountToDouble(amount: base.rate);
final rowRate = moneroAmountToDouble(amount: row.rate);
try {
final rate = haven!.getAssetRate();
final base = rate.firstWhere((row) => row.asset == 'XUSD');
if (cur == CryptoCurrency.xusd) {
fiatConversionStore.prices[cur] = 1.0;
return;
}
rate.forEach((row) {
final cur = CryptoCurrency.fromString(row.asset);
final baseRate = moneroAmountToDouble(amount: base.rate);
final rowRate = moneroAmountToDouble(amount: row.rate);
fiatConversionStore.prices[cur] = baseRate / rowRate;
});
if (cur == CryptoCurrency.xusd) {
fiatConversionStore.prices[cur] = 1.0;
return;
}
fiatConversionStore.prices[cur] = baseRate / rowRate;
});
} catch(_) {
// FIX-ME: handle exception
}
}
+1
View File
@@ -3,6 +3,7 @@ import 'package:cw_core/crypto_currency.dart';
class WalletContact implements ContactBase {
WalletContact(this.address, this.name, this.type);
//: super(name, address, type);
@override
String address;
+1 -1
View File
@@ -1,7 +1,7 @@
import 'package:cw_core/wallet_type.dart';
class WalletDescription {
WalletDescription({this.name, this.type});
WalletDescription({required this.name, required this.type});
final String name;
final WalletType type;
+7 -10
View File
@@ -1,16 +1,13 @@
class YatRecord {
String category;
String address;
YatRecord({
this.category,
this.address,
required this.category,
required this.address,
});
YatRecord.fromJson(Map<String, dynamic> json) {
address = json['address'] as String;
category = json['category'] as String;
}
YatRecord.fromJson(Map<String, dynamic> json)
: address = json['address'] as String,
category = json['category'] as String;
String category;
String address;
}
@@ -1,6 +1,5 @@
import 'dart:convert';
import 'package:cake_wallet/exchange/trade_not_found_exeption.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cw_core/crypto_currency.dart';
@@ -56,8 +55,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
static String getFlow(bool isFixedRate) => isFixedRate ? 'fixed-rate' : 'standard';
@override
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to,
bool isFixedRateMode}) async {
Future<Limits> fetchLimits({
required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode}) async {
final headers = {apiHeaderKey: apiKey};
final normalizedFrom = normalizeCryptoCurrency(from);
final normalizedTo = normalizeCryptoCurrency(to);
@@ -79,7 +80,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -89,7 +90,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
final _request = request as ChangeNowRequest;
final headers = {
apiHeaderKey: apiKey,
@@ -122,7 +123,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -145,7 +146,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> findTradeById({@required String id}) async {
Future<Trade> findTradeById({required String id}) async {
final headers = {apiHeaderKey: apiKey};
final params = <String, String>{'id': id};
final uri = Uri.https(apiAuthority,findTradeByIdPath, params);
@@ -164,7 +165,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -198,11 +199,11 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
@override
Future<double> calculateAmount(
{CryptoCurrency from,
CryptoCurrency to,
double amount,
bool isFixedRateMode,
bool isReceiveAmount}) async {
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) {
return 0.0;
@@ -250,7 +251,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
return CryptoCurrency.btc.title.toLowerCase();
default:
return currency.tag != null
? currency.tag.toLowerCase()
? currency.tag!.toLowerCase()
: currency.title.toLowerCase();
}
}
@@ -4,13 +4,13 @@ import 'package:cake_wallet/exchange/trade_request.dart';
class ChangeNowRequest extends TradeRequest {
ChangeNowRequest(
{@required this.from,
@required this.to,
@required this.address,
@required this.fromAmount,
@required this.toAmount,
@required this.refundAddress,
@required this.isReverse});
{required this.from,
required this.to,
required this.address,
required this.fromAmount,
required this.toAmount,
required this.refundAddress,
required this.isReverse});
CryptoCurrency from;
CryptoCurrency to;
+4 -1
View File
@@ -1,7 +1,10 @@
import 'package:cw_core/crypto_currency.dart';
class ExchangePair {
ExchangePair({this.from, this.to, this.reverse = true});
ExchangePair({
required this.from,
required this.to,
this.reverse = true});
final CryptoCurrency from;
final CryptoCurrency to;
+15 -7
View File
@@ -7,11 +7,11 @@ import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
abstract class ExchangeProvider {
ExchangeProvider({this.pairList});
ExchangeProvider({required this.pairList});
String get title;
List<ExchangePair> pairList;
ExchangeProviderDescription description;
ExchangeProviderDescription get description;
bool get isAvailable;
bool get isEnabled;
@@ -19,10 +19,18 @@ abstract class ExchangeProvider {
String toString() => title;
Future<Limits> fetchLimits(
{CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode});
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode});
Future<Trade> findTradeById({@required String id});
Future<double> calculateAmount({CryptoCurrency from, CryptoCurrency to,
double amount, bool isFixedRateMode, bool isReceiveAmount});
{required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode});
Future<Trade> createTrade({
required TradeRequest request,
required bool isFixedRateMode});
Future<Trade> findTradeById({required String id});
Future<double> calculateAmount({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount});
Future<bool> checkIsAvailable();
}
@@ -2,7 +2,11 @@ import 'package:cw_core/enumerable_item.dart';
class ExchangeProviderDescription extends EnumerableItem<int>
with Serializable<int> {
const ExchangeProviderDescription({String title, int raw, this.horizontalLogo = false, this.image})
const ExchangeProviderDescription({
required String title,
required int raw,
required this.image,
this.horizontalLogo = false})
: super(title: title, raw: raw);
final bool horizontalLogo;
@@ -20,7 +24,7 @@ class ExchangeProviderDescription extends EnumerableItem<int>
static const simpleSwap =
ExchangeProviderDescription(title: 'SimpleSwap', raw: 4, image: 'assets/images/simpleSwap.png');
static ExchangeProviderDescription deserialize({int raw}) {
static ExchangeProviderDescription deserialize({required int raw}) {
switch (raw) {
case 0:
return xmrto;
@@ -33,7 +37,7 @@ class ExchangeProviderDescription extends EnumerableItem<int>
case 4:
return simpleSwap;
default:
return null;
throw Exception('Unexpected token: $raw for ExchangeProviderDescription deserialize');
}
}
}
+6 -6
View File
@@ -5,12 +5,12 @@ part 'exchange_template.g.dart';
@HiveType(typeId: ExchangeTemplate.typeId)
class ExchangeTemplate extends HiveObject {
ExchangeTemplate({
this.amount,
this.depositCurrency,
this.receiveCurrency,
this.provider,
this.depositAddress,
this.receiveAddress
required this.amount,
required this.depositCurrency,
required this.receiveCurrency,
required this.provider,
required this.depositAddress,
required this.receiveAddress
});
static const typeId = 7;
+2 -2
View File
@@ -8,13 +8,13 @@ class ExchangeTradeStateInitial extends ExchangeTradeState {}
class TradeIsCreating extends ExchangeTradeState {}
class TradeIsCreatedSuccessfully extends ExchangeTradeState {
TradeIsCreatedSuccessfully({@required this.trade});
TradeIsCreatedSuccessfully({required this.trade});
final Trade trade;
}
class TradeIsCreatedFailure extends ExchangeTradeState {
TradeIsCreatedFailure({@required this.title, @required this.error});
TradeIsCreatedFailure({required this.title, required this.error});
final String title;
final String error;
+2 -2
View File
@@ -1,6 +1,6 @@
class Limits {
const Limits({this.min, this.max});
final double min;
final double max;
final double? min;
final double? max;
}
+2 -2
View File
@@ -8,13 +8,13 @@ class LimitsInitialState extends LimitsState {}
class LimitsIsLoading extends LimitsState {}
class LimitsLoadedSuccessfully extends LimitsState {
LimitsLoadedSuccessfully({@required this.limits});
LimitsLoadedSuccessfully({required this.limits});
final Limits limits;
}
class LimitsLoadedFailure extends LimitsState {
LimitsLoadedFailure({@required this.error});
LimitsLoadedFailure({required this.error});
final String error;
}
@@ -16,7 +16,7 @@ import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/exchange/trade_not_created_exeption.dart';
class MorphTokenExchangeProvider extends ExchangeProvider {
MorphTokenExchangeProvider({@required this.trades})
MorphTokenExchangeProvider({required this.trades})
: super(pairList: [
ExchangePair(from: CryptoCurrency.xmr, to: CryptoCurrency.eth),
ExchangePair(from: CryptoCurrency.xmr, to: CryptoCurrency.bch),
@@ -74,8 +74,12 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
Future<bool> checkIsAvailable() async => true;
@override
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
Future<Limits> fetchLimits({
required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode}) async {
final url = apiUri + _limitsURISuffix;
final uri = Uri.parse(url);
final headers = {'Content-type': 'application/json'};
final body = json.encode({
"input": {"asset": from.toString()},
@@ -83,11 +87,11 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
{"asset": to.toString(), "weight": weight}
]
});
final response = await post(url, headers: headers, body: body);
final response = await post(uri, headers: headers, body: body);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final min = responseJSON['input']['limits']['min'] as int;
int max;
int max = 0;
double ethMax;
if (from == CryptoCurrency.eth) {
@@ -96,14 +100,16 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
max = responseJSON['input']['limits']['max'] as int;
}
double minFormatted = AmountConverter.amountIntToDouble(from, min);
double maxFormatted = AmountConverter.amountIntToDouble(from, max);
final minFormatted = AmountConverter.amountIntToDouble(from, min);
final maxFormatted = AmountConverter.amountIntToDouble(from, max);
return Limits(min: minFormatted, max: maxFormatted);
}
@override
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
Future<Trade> createTrade({
required TradeRequest request,
required bool isFixedRateMode}) async {
const url = apiUri + _morphURISuffix;
final _request = request as MorphTokenRequest;
final body = {
@@ -120,8 +126,8 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
],
"tag": "cakewallet"
};
final response = await post(url,
final uri = Uri.parse(url);
final response = await post(uri,
headers: {'Content-Type': 'application/json'}, body: json.encode(body));
if (response.statusCode != 200) {
@@ -149,9 +155,10 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> findTradeById({@required String id}) async {
Future<Trade> findTradeById({required String id}) async {
final url = apiUri + _morphURISuffix + '/' + id;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
if (response.statusCode != 200) {
if (response.statusCode == 400) {
@@ -194,17 +201,21 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
@override
Future<double> calculateAmount(
{CryptoCurrency from, CryptoCurrency to, double amount, bool isFixedRateMode,
bool isReceiveAmount}) async {
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
final url = apiUri + _ratesURISuffix;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final rate = responseJSON['data'][from.toString()][to.toString()] as String;
try {
final estimatedAmount = double.parse(rate) * amount;
return estimatedAmount;
} catch (e) {
} catch (_) {
return 0.0;
}
}
@@ -4,11 +4,11 @@ import 'package:cake_wallet/exchange/trade_request.dart';
class MorphTokenRequest extends TradeRequest {
MorphTokenRequest(
{@required this.from,
@required this.to,
@required this.address,
@required this.amount,
@required this.refundAddress});
{required this.from,
required this.to,
required this.address,
required this.amount,
required this.refundAddress});
CryptoCurrency from;
CryptoCurrency to;
@@ -40,11 +40,11 @@ class SideShiftExchangeProvider extends ExchangeProvider {
@override
Future<double> calculateAmount(
{CryptoCurrency from,
CryptoCurrency to,
double amount,
bool isFixedRateMode,
bool isReceiveAmount}) async {
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) {
return 0.0;
@@ -53,7 +53,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final toCurrency = _normalizeCryptoCurrency(to);
final url =
apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final rate = double.parse(responseJSON['rate'] as String);
final max = double.parse(responseJSON['max'] as String);
@@ -71,7 +72,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
@override
Future<bool> checkIsAvailable() async {
const url = apiBaseUrl + permissionPath;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -92,7 +94,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
@override
Future<Trade> createTrade(
{TradeRequest request, bool isFixedRateMode}) async {
{required TradeRequest request, required bool isFixedRateMode}) async {
final _request = request as SideShiftRequest;
final quoteId = await _createQuote(_request);
final url = apiBaseUrl + orderPath;
@@ -104,7 +106,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
'settleAddress': _request.settleAddress,
'refundAddress': _request.refundAddress
};
final response = await post(url, headers: headers, body: json.encode(body));
final uri = Uri.parse(url);
final response = await post(uri, headers: headers, body: json.encode(body));
if (response.statusCode != 201) {
if (response.statusCode == 400) {
@@ -146,7 +149,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
'affiliateId': affiliateId,
'depositAmount': request.depositAmount,
};
final response = await post(url, headers: headers, body: json.encode(body));
final uri = Uri.parse(url);
final response = await post(uri, headers: headers, body: json.encode(body));
if (response.statusCode != 201) {
if (response.statusCode == 400) {
@@ -167,11 +171,14 @@ class SideShiftExchangeProvider extends ExchangeProvider {
@override
Future<Limits> fetchLimits(
{CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
{required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode}) async {
final fromCurrency = _normalizeCryptoCurrency(from);
final toCurrency = _normalizeCryptoCurrency(to);
final url = apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -181,7 +188,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -192,9 +199,10 @@ class SideShiftExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> findTradeById({@required String id}) async {
Future<Trade> findTradeById({required String id}) async {
final url = apiBaseUrl + orderPath + '/' + id;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
if (response.statusCode == 404) {
throw TradeNotFoundException(id, provider: description);
@@ -209,7 +217,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -219,8 +227,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final to = CryptoCurrency.fromString(toCurrency);
final inputAddress = responseJSON['depositAddress']['address'] as String;
final expectedSendAmount = responseJSON['depositAmount'].toString();
final deposits = responseJSON['deposits'] as List;
TradeState state;
final deposits = responseJSON['deposits'] as List?;
TradeState? state;
if (deposits != null && deposits.isNotEmpty) {
final status = deposits[0]['status'] as String;
@@ -259,7 +267,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
case CryptoCurrency.zec:
return 'zec';
case CryptoCurrency.bnb:
return currency.tag.toLowerCase();
return currency.tag!.toLowerCase();
case CryptoCurrency.usdterc20:
return 'usdtErc20';
default:
@@ -2,16 +2,16 @@ import 'package:cake_wallet/exchange/trade_request.dart';
import 'package:cw_core/crypto_currency.dart';
class SideShiftRequest extends TradeRequest {
SideShiftRequest(
{required this.depositMethod,
required this.settleMethod,
required this.depositAmount,
required this.settleAddress,
required this.refundAddress});
final CryptoCurrency depositMethod;
final CryptoCurrency settleMethod;
final String depositAmount;
final String settleAddress;
final String refundAddress;
SideShiftRequest(
{this.depositMethod,
this.settleMethod,
this.depositAmount,
this.settleAddress,
this.refundAddress,});
}
@@ -1,5 +1,4 @@
import 'dart:convert';
import 'package:cake_wallet/exchange/exchange_pair.dart';
import 'package:cake_wallet/exchange/exchange_provider.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
@@ -36,7 +35,11 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
@override
Future<double> calculateAmount(
{CryptoCurrency from, CryptoCurrency to, double amount, bool isFixedRateMode, bool isReceiveAmount}) async {
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) {
return 0.0;
@@ -51,7 +54,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
'fixed': isFixedRateMode.toString()
};
final uri = Uri.https(apiAuthority, getEstimatePath, params);
final response = await get(uri);
if (response.body == null) return 0.00;
@@ -68,11 +70,11 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
final uri = Uri.https(apiAuthority, getEstimatePath, <String, String>{'api_key': apiKey});
final response = await get(uri);
return !(response.statusCode == 403);
return !(response.statusCode == 403);
}
@override
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
final _request = request as SimpleSwapRequest;
final headers = {
'Content-Type': 'application/json'};
@@ -121,7 +123,10 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
}
@override
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
Future<Limits> fetchLimits({
required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode}) async {
final fromCurrency = _normalizeCryptoCurrency(from);
final toCurrency = _normalizeCryptoCurrency(to);
final params = <String, dynamic>{
@@ -142,7 +147,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -153,7 +158,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> findTradeById({String id}) async {
Future<Trade> findTradeById({required String id}) async {
final params = {'api_key': apiKey, 'id': id};
final uri = Uri.https(apiAuthority, getExchangePath, params);
final response = await get(uri);
@@ -170,7 +175,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
}
if (response.statusCode != 200) {
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -210,7 +215,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
case CryptoCurrency.zec:
return 'zec';
case CryptoCurrency.bnb:
return currency.tag.toLowerCase();
return currency.tag!.toLowerCase();
case CryptoCurrency.usdterc20:
return 'usdterc';
default:
@@ -4,11 +4,12 @@ import 'package:flutter/material.dart';
class SimpleSwapRequest extends TradeRequest {
SimpleSwapRequest({
@required this.from,
@required this.to,
@required this.address,
@required this.amount,
@required this.refundAddress,
required this.from,
required this.to,
required this.address,
required this.amount,
required this.refundAddress,
this.toAmount = ''
});
CryptoCurrency from;
+33 -24
View File
@@ -9,23 +9,32 @@ part 'trade.g.dart';
@HiveType(typeId: Trade.typeId)
class Trade extends HiveObject {
Trade(
{this.id,
ExchangeProviderDescription provider,
CryptoCurrency from,
CryptoCurrency to,
TradeState state,
{required this.id,
required this.amount,
ExchangeProviderDescription? provider,
CryptoCurrency? from,
CryptoCurrency? to,
TradeState? state,
this.createdAt,
this.expiredAt,
this.amount,
this.inputAddress,
this.extraId,
this.outputTransaction,
this.refundAddress,
this.walletId})
: providerRaw = provider?.raw,
fromRaw = from?.raw,
toRaw = to?.raw,
stateRaw = state?.raw;
this.walletId}) {
if (provider != null) {
providerRaw = provider.raw;
}
if (from != null) {
fromRaw = from.raw;
}
if (to != null) {
toRaw = to.raw;
}
if (state != null) {
stateRaw = state.raw;
}
}
static const typeId = 3;
static const boxName = 'Trades';
@@ -35,51 +44,51 @@ class Trade extends HiveObject {
String id;
@HiveField(1)
int providerRaw;
late int providerRaw;
ExchangeProviderDescription get provider =>
ExchangeProviderDescription.deserialize(raw: providerRaw);
@HiveField(2)
int fromRaw;
late int fromRaw;
CryptoCurrency get from => CryptoCurrency.deserialize(raw: fromRaw);
@HiveField(3)
int toRaw;
late int toRaw;
CryptoCurrency get to => CryptoCurrency.deserialize(raw: toRaw);
@HiveField(4)
String stateRaw;
late String stateRaw;
TradeState get state => TradeState.deserialize(raw: stateRaw);
@HiveField(5)
DateTime createdAt;
DateTime? createdAt;
@HiveField(6)
DateTime expiredAt;
DateTime? expiredAt;
@HiveField(7)
String amount;
@HiveField(8)
String inputAddress;
String? inputAddress;
@HiveField(9)
String extraId;
String? extraId;
@HiveField(10)
String outputTransaction;
String? outputTransaction;
@HiveField(11)
String refundAddress;
String? refundAddress;
@HiveField(12)
String walletId;
String? walletId;
static Trade fromMap(Map map) {
static Trade fromMap(Map<String, Object?> map) {
return Trade(
id: map['id'] as String,
provider: ExchangeProviderDescription.deserialize(
@@ -99,7 +108,7 @@ class Trade extends HiveObject {
'provider': provider.serialize(),
'input': from.serialize(),
'output': to.serialize(),
'date': createdAt != null ? createdAt.millisecondsSinceEpoch : null,
'date': createdAt != null ? createdAt!.millisecondsSinceEpoch : null,
'amount': amount,
'wallet_id': walletId
};
+3 -3
View File
@@ -4,14 +4,14 @@ import 'package:cake_wallet/generated/i18n.dart';
class TradeNotFoundException implements Exception {
TradeNotFoundException(this.tradeId, {this.provider, this.description = ''});
String tradeId;
ExchangeProviderDescription provider;
String? tradeId;
ExchangeProviderDescription? provider;
String description;
@override
String toString() {
var text = tradeId != null && provider != null
? S.current.trade_id_not_found(tradeId, provider.title)
? S.current.trade_id_not_found(tradeId!, provider!.title)
: S.current.trade_not_found;
text += ' $description';
+3 -3
View File
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:cw_core/enumerable_item.dart';
class TradeState extends EnumerableItem<String> with Serializable<String> {
const TradeState({@required String raw, @required String title})
const TradeState({required String raw, required String title})
: super(raw: raw, title: title);
@override
@@ -35,7 +35,7 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
static const completed = TradeState(raw: 'completed', title: 'Completed');
static const settling = TradeState(raw: 'settling', title: 'Settlement in progress');
static const settled = TradeState(raw: 'settled', title: 'Settlement completed');
static TradeState deserialize({String raw}) {
static TradeState deserialize({required String raw}) {
switch (raw) {
case 'pending':
return pending;
@@ -78,7 +78,7 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
case 'completed':
return completed;
default:
return null;
throw Exception('Unexpected token: $raw in TradeState deserialize');
}
}
+23 -18
View File
@@ -34,7 +34,8 @@ class XMRTOExchangeProvider extends ExchangeProvider {
static Future<bool> _checkIsAvailable() async {
const url = originalApiUri + _orderParameterUriSuffix;
final response = await get(url, headers: _headers);
final uri = Uri.parse(url);
final response = await get(uri, headers: _headers);
return !(response.statusCode == 403);
}
@@ -61,9 +62,13 @@ class XMRTOExchangeProvider extends ExchangeProvider {
}
@override
Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
Future<Limits> fetchLimits({
required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode}) async {
final url = originalApiUri + _orderParameterUriSuffix;
final response = await get(url);
final uri = Uri.parse(url);
final response = await get(uri);
final correction = 0.001;
if (response.statusCode != 200) {
@@ -94,16 +99,14 @@ class XMRTOExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
final _request = request as XMRTOTradeRequest;
final url = originalApiUri + _orderCreateUriSuffix;
final _amount =
_request.isBTCRequest ? _request.receiveAmount : _request.amount;
final _amountCurrency = _request.isBTCRequest
? _request.to.toString()
: _request.from.toString();
final pattern = '^([0-9]+([.\,][0-9]{0,8})?|[.\,][0-9]{1,8})\$';
final isValid = RegExp(pattern).hasMatch(_amount);
@@ -115,10 +118,10 @@ class XMRTOExchangeProvider extends ExchangeProvider {
final body = {
'amount': _amount,
'amount_currency': _amountCurrency,
'btc_dest_address': _request.address
};
'btc_dest_address': _request.address};
final uri = Uri.parse(url);
final response =
await post(url, headers: _headers, body: json.encode(body));
await post(uri, headers: _headers, body: json.encode(body));
if (response.statusCode != 201) {
if (response.statusCode == 400) {
@@ -145,11 +148,12 @@ class XMRTOExchangeProvider extends ExchangeProvider {
}
@override
Future<Trade> findTradeById({@required String id}) async {
Future<Trade> findTradeById({required String id}) async {
final url = originalApiUri + _orderStatusUriSuffix;
final uri = Uri.parse(url);
final body = {'uuid': id};
final response =
await post(url, headers: _headers, body: json.encode(body));
await post(uri, headers: _headers, body: json.encode(body));
if (response.statusCode != 200) {
if (response.statusCode == 400) {
@@ -188,16 +192,16 @@ class XMRTOExchangeProvider extends ExchangeProvider {
@override
Future<double> calculateAmount(
{CryptoCurrency from,
CryptoCurrency to,
double amount,
bool isFixedRateMode,
bool isReceiveAmount}) async {
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
if (from != CryptoCurrency.xmr && to != CryptoCurrency.btc) {
return 0;
}
if (_rate == null || _rate == 0) {
if (_rate == 0) {
_rate = await _fetchRates();
}
@@ -213,7 +217,8 @@ class XMRTOExchangeProvider extends ExchangeProvider {
Future<double> _fetchRates() async {
try {
final url = originalApiUri + _orderParameterUriSuffix;
final response = await get(url, headers: _headers);
final uri = Uri.parse(url);
final response = await get(uri, headers: _headers);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final price = double.parse(responseJSON['price'] as String);
+7 -7
View File
@@ -4,13 +4,13 @@ import 'package:cake_wallet/exchange/trade_request.dart';
class XMRTOTradeRequest extends TradeRequest {
XMRTOTradeRequest(
{@required this.from,
@required this.to,
@required this.amount,
@required this.receiveAmount,
@required this.address,
@required this.refundAddress,
@required this.isBTCRequest});
{required this.from,
required this.to,
required this.amount,
required this.receiveAmount,
required this.address,
required this.refundAddress,
required this.isBTCRequest});
final CryptoCurrency from;
final CryptoCurrency to;
+66 -29
View File
@@ -2,7 +2,7 @@ part of 'haven.dart';
class CWHavenAccountList extends HavenAccountList {
CWHavenAccountList(this._wallet);
Object _wallet;
final Object _wallet;
@override
@computed
@@ -37,13 +37,13 @@ class CWHavenAccountList extends HavenAccountList {
}
@override
Future<void> addAccount(Object wallet, {String label}) async {
Future<void> addAccount(Object wallet, {required String label}) async {
final havenWallet = wallet as HavenWallet;
await havenWallet.walletAddresses.accountList.addAccount(label: label);
}
@override
Future<void> setLabelAccount(Object wallet, {int accountIndex, String label}) async {
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async {
final havenWallet = wallet as HavenWallet;
await havenWallet.walletAddresses.accountList
.setLabelAccount(
@@ -54,7 +54,7 @@ class CWHavenAccountList extends HavenAccountList {
class CWHavenSubaddressList extends MoneroSubaddressList {
CWHavenSubaddressList(this._wallet);
Object _wallet;
final Object _wallet;
@override
@computed
@@ -71,13 +71,13 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
}
@override
void update(Object wallet, {int accountIndex}) {
void update(Object wallet, {required int accountIndex}) {
final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
}
@override
void refresh(Object wallet, {int accountIndex}) {
void refresh(Object wallet, {required int accountIndex}) {
final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
}
@@ -93,7 +93,7 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
}
@override
Future<void> addSubaddress(Object wallet, {int accountIndex, String label}) async {
Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async {
final havenWallet = wallet as HavenWallet;
await havenWallet.walletAddresses.subaddressList
.addSubaddress(
@@ -103,7 +103,7 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
@override
Future<void> setLabelSubaddress(Object wallet,
{int accountIndex, int addressIndex, String label}) async {
{required int accountIndex, required int addressIndex, required String label}) async {
final havenWallet = wallet as HavenWallet;
await havenWallet.walletAddresses.subaddressList
.setLabelSubaddress(
@@ -115,9 +115,10 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
class CWHavenWalletDetails extends HavenWalletDetails {
CWHavenWalletDetails(this._wallet);
Object _wallet;
final Object _wallet;
@computed
@override
Account get account {
final havenWallet = _wallet as HavenWallet;
final acc = havenWallet.walletAddresses.account as monero_account.Account;
@@ -125,10 +126,11 @@ class CWHavenWalletDetails extends HavenWalletDetails {
}
@computed
@override
HavenBalance get balance {
final havenWallet = _wallet as HavenWallet;
final balance = havenWallet.balance;
return null;
throw Exception('Unimplemented');
//return HavenBalance(
// fullBalance: balance.fullBalance,
// unlockedBalance: balance.unlockedBalance);
@@ -136,39 +138,48 @@ class CWHavenWalletDetails extends HavenWalletDetails {
}
class CWHaven extends Haven {
HavenAccountList getAccountList(Object wallet) {
@override
HavenAccountList getAccountList(Object wallet) {
return CWHavenAccountList(wallet);
}
@override
MoneroSubaddressList getSubaddressList(Object wallet) {
return CWHavenSubaddressList(wallet);
}
@override
TransactionHistoryBase getTransactionHistory(Object wallet) {
final havenWallet = wallet as HavenWallet;
return havenWallet.transactionHistory;
}
@override
HavenWalletDetails getMoneroWalletDetails(Object wallet) {
return CWHavenWalletDetails(wallet);
}
int getHeigthByDate({DateTime date}) {
@override
int getHeigthByDate({required DateTime date}) {
return getMoneroHeigthByDate(date: date);
}
@override
TransactionPriority getDefaultTransactionPriority() {
return MoneroTransactionPriority.slow;
}
TransactionPriority deserializeMoneroTransactionPriority({int raw}) {
@override
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
return MoneroTransactionPriority.deserialize(raw: raw);
}
@override
List<TransactionPriority> getTransactionPriorities() {
return MoneroTransactionPriority.all;
}
@override
List<String> getMoneroWordList(String language) {
switch (language.toLowerCase()) {
case 'english':
@@ -196,14 +207,15 @@ class CWHaven extends Haven {
}
}
@override
WalletCredentials createHavenRestoreWalletFromKeysCredentials({
String name,
String spendKey,
String viewKey,
String address,
String password,
String language,
int height}) {
required String name,
required String spendKey,
required String viewKey,
required String address,
required String password,
required String language,
required int height}) {
return HavenRestoreWalletFromKeysCredentials(
name: name,
spendKey: spendKey,
@@ -213,8 +225,13 @@ class CWHaven extends Haven {
language: language,
height: height);
}
WalletCredentials createHavenRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic}) {
@override
WalletCredentials createHavenRestoreWalletFromSeedCredentials({
required String name,
required String password,
required int height,
required String mnemonic}) {
return HavenRestoreWalletFromSeedCredentials(
name: name,
password: password,
@@ -222,13 +239,18 @@ class CWHaven extends Haven {
mnemonic: mnemonic);
}
WalletCredentials createHavenNewWalletCredentials({String name, String password, String language}) {
@override
WalletCredentials createHavenNewWalletCredentials({
required String name,
required String language,
String? password}) {
return HavenNewWalletCredentials(
name: name,
password: password,
language: language);
}
@override
Map<String, String> getKeys(Object wallet) {
final havenWallet = wallet as HavenWallet;
final keys = havenWallet.keys;
@@ -239,7 +261,11 @@ class CWHaven extends Haven {
'publicViewKey': keys.publicViewKey};
}
Object createHavenTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority, String assetType}) {
@override
Object createHavenTransactionCreationCredentials({
required List<Output> outputs,
required TransactionPriority priority,
required String assetType}) {
return HavenTransactionCreationCredentials(
outputs: outputs.map((out) => OutputInfo(
fiatAmount: out.fiatAmount,
@@ -255,53 +281,64 @@ class CWHaven extends Haven {
assetType: assetType);
}
String formatterMoneroAmountToString({int amount}) {
@override
String formatterMoneroAmountToString({required int amount}) {
return moneroAmountToString(amount: amount);
}
double formatterMoneroAmountToDouble({int amount}) {
@override
double formatterMoneroAmountToDouble({required int amount}) {
return moneroAmountToDouble(amount: amount);
}
int formatterMoneroParseAmount({String amount}) {
@override
int formatterMoneroParseAmount({required String amount}) {
return moneroParseAmount(amount: amount);
}
@override
Account getCurrentAccount(Object wallet) {
final havenWallet = wallet as HavenWallet;
final acc = havenWallet.walletAddresses.account as monero_account.Account;
return Account(id: acc.id, label: acc.label);
}
@override
void setCurrentAccount(Object wallet, int id, String label) {
final havenWallet = wallet as HavenWallet;
havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
}
@override
void onStartup() {
monero_wallet_api.onStartup();
}
@override
int getTransactionInfoAccountId(TransactionInfo tx) {
final havenTransactionInfo = tx as HavenTransactionInfo;
return havenTransactionInfo.accountIndex;
}
@override
WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) {
return HavenWalletService(walletInfoSource);
}
@override
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
final havenWallet = wallet as HavenWallet;
return havenWallet.getTransactionAddress(accountIndex, addressIndex);
}
@override
CryptoCurrency assetOfTransaction(TransactionInfo tx) {
final transaction = tx as HavenTransactionInfo;
final asset = CryptoCurrency.fromString(transaction.assetType);
return asset;
}
@override
List<AssetRate> getAssetRate()
=> getRate()
.map((rate) => AssetRate(rate.getAssetType(), rate.getRate()))
+7 -9
View File
@@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_core/output_info.dart';
@@ -14,7 +13,6 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
class IoniaAnyPay {
IoniaAnyPay(this.ioniaService, this.anyPayApi, this.wallet);
@@ -24,8 +22,8 @@ class IoniaAnyPay {
final WalletBase wallet;
Future<IoniaAnyPayPaymentInfo> purchase({
@required String merchId,
@required double amount}) async {
required String merchId,
required double amount}) async {
final invoice = await ioniaService.purchaseGiftCard(
merchId: merchId,
amount: amount,
@@ -40,7 +38,7 @@ class IoniaAnyPay {
.map((AnyPayPaymentInstruction instruction) {
switch(payment.chain.toUpperCase()) {
case AnyPayChain.xmr:
return monero.createMoneroTransactionCreationCredentialsRaw(
return monero!.createMoneroTransactionCreationCredentialsRaw(
outputs: instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
@@ -50,7 +48,7 @@ class IoniaAnyPay {
sendAll: false)).toList(),
priority: MoneroTransactionPriority.medium); // FIXME: HARDCODED PRIORITY
case AnyPayChain.btc:
return bitcoin.createBitcoinTransactionCredentialsRaw(
return bitcoin!.createBitcoinTransactionCredentialsRaw(
instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
@@ -59,7 +57,7 @@ class IoniaAnyPay {
sendAll: false)).toList(),
feeRate: instruction.requiredFeeRate);
case AnyPayChain.ltc:
return bitcoin.createBitcoinTransactionCredentialsRaw(
return bitcoin!.createBitcoinTransactionCredentialsRaw(
instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
@@ -76,8 +74,8 @@ class IoniaAnyPay {
.map((PendingTransaction pendingTransaction) {
switch (payment.chain.toUpperCase()){
case AnyPayChain.xmr:
final ptx = monero.pendingTransactionInfo(pendingTransaction);
return AnyPayTransaction(ptx['hex'], id: ptx['id'], key: ptx['key']);
final ptx = monero!.pendingTransactionInfo(pendingTransaction);
return AnyPayTransaction(ptx['hex'] ?? '', id: ptx['id'] ?? '', key: ptx['key']);
default:
return AnyPayTransaction(pendingTransaction.hex, id: pendingTransaction.id, key: null);
}
+88 -91
View File
@@ -1,7 +1,6 @@
import 'dart:convert';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/ionia/ionia_user_credentials.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
@@ -27,15 +26,14 @@ class IoniaApi {
// Create user
Future<String> createUser(String email, {@required String clientId}) async {
Future<String> createUser(String email, {required String clientId}) async {
final headers = <String, String>{'clientId': clientId};
final query = <String, String>{'emailAddress': email};
final uri = createUserUri.replace(queryParameters: query);
final response = await put(uri, headers: headers);
if (response.statusCode != 200) {
// throw exception
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -52,10 +50,10 @@ class IoniaApi {
// Verify email
Future<IoniaUserCredentials> verifyEmail({
@required String username,
@required String email,
@required String code,
@required String clientId}) async {
required String username,
required String email,
required String code,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -65,8 +63,7 @@ class IoniaApi {
final response = await put(uri, headers: headers);
if (response.statusCode != 200) {
// throw exception
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -84,15 +81,14 @@ class IoniaApi {
// Sign In
Future<String> signIn(String email, {@required String clientId}) async {
Future<String> signIn(String email, {required String clientId}) async {
final headers = <String, String>{'clientId': clientId};
final query = <String, String>{'emailAddress': email};
final uri = signInUri.replace(queryParameters: query);
final response = await put(uri, headers: headers);
if (response.statusCode != 200) {
// throw exception
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -109,9 +105,9 @@ class IoniaApi {
// Get virtual card
Future<IoniaVirtualCard> getCards({
@required String username,
@required String password,
@required String clientId}) async {
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -119,8 +115,7 @@ class IoniaApi {
final response = await post(getCardsUri, headers: headers);
if (response.statusCode != 200) {
// throw exception
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -138,9 +133,9 @@ class IoniaApi {
// Create virtual card
Future<IoniaVirtualCard> createCard({
@required String username,
@required String password,
@required String clientId}) async {
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -148,13 +143,12 @@ class IoniaApi {
final response = await post(createCardUri, headers: headers);
if (response.statusCode != 200) {
// throw exception
return null;
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, Object>;
final data = bodyJson['Data'] as Map<String, Object>;
final isSuccessful = bodyJson['Successful'] as bool;
final isSuccessful = bodyJson['Successful'] as bool? ?? false;
if (!isSuccessful) {
throw Exception(data['message'] as String);
@@ -166,9 +160,9 @@ class IoniaApi {
// Get Merchants
Future<List<IoniaMerchant>> getMerchants({
@required String username,
@required String password,
@required String clientId}) async {
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -180,32 +174,33 @@ class IoniaApi {
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
return data.map((dynamic e) {
try {
final element = e as Map<String, dynamic>;
return IoniaMerchant.fromJsonMap(element);
} catch(_) {
return null;
}
}).where((e) => e != null)
.toList();
final merch = <IoniaMerchant>[];
for (final item in data) {
try {
final element = item as Map<String, dynamic>;
merch.add(IoniaMerchant.fromJsonMap(element));
} catch(_) {}
}
return merch;
}
// Get Merchants By Filter
Future<List<IoniaMerchant>> getMerchantsByFilter({
@required String username,
@required String password,
@required String clientId,
String search,
List<IoniaCategory> categories,
required String username,
required String password,
required String clientId,
String? search,
List<IoniaCategory>? categories,
int merchantFilterType = 0}) async {
// MerchantFilterType: {All = 0, Nearby = 1, Popular = 2, Online = 3, MyFaves = 4, Search = 5}
@@ -234,34 +229,35 @@ class IoniaApi {
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
return data.map((dynamic e) {
try {
final element = e['Merchant'] as Map<String, dynamic>;
return IoniaMerchant.fromJsonMap(element);
} catch(_) {
return null;
}
}).where((e) => e != null)
.toList();
final merch = <IoniaMerchant>[];
for (final item in data) {
try {
final element = item['Merchant'] as Map<String, dynamic>;
merch.add(IoniaMerchant.fromJsonMap(element));
} catch(_) {}
}
return merch;
}
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
@required String requestedUUID,
@required String merchId,
@required double amount,
@required String currency,
@required String username,
@required String password,
@required String clientId}) async {
required String requestedUUID,
required String merchId,
required double amount,
required String currency,
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -279,7 +275,7 @@ class IoniaApi {
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
throw Exception(decodedBody['ErrorMessage'] as String);
@@ -292,9 +288,9 @@ class IoniaApi {
// Get Current User Gift Card Summaries
Future<List<IoniaGiftCard>> getCurrentUserGiftCardSummaries({
@required String username,
@required String password,
@required String clientId}) async {
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -306,32 +302,33 @@ class IoniaApi {
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
return data.map((dynamic e) {
try {
final element = e as Map<String, dynamic>;
return IoniaGiftCard.fromJsonMap(element);
} catch(e) {
return null;
}
}).where((e) => e != null)
.toList();
final cards = <IoniaGiftCard>[];
for (final item in data) {
try {
final element = item as Map<String, dynamic>;
cards.add(IoniaGiftCard.fromJsonMap(element));
} catch(_) {}
}
return cards;
}
// Charge Gift Card
Future<void> chargeGiftCard({
@required String username,
@required String password,
@required String clientId,
@required int giftCardId,
@required double amount}) async {
required String username,
required String password,
required String clientId,
required int giftCardId,
required double amount}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -350,11 +347,11 @@ class IoniaApi {
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
final data = decodedBody['Data'] as Map<String, dynamic>;
final msg = data['Message'] as String ?? '';
final msg = data['Message'] as String? ?? '';
if (msg.isNotEmpty) {
throw Exception(msg);
@@ -367,10 +364,10 @@ class IoniaApi {
// Get Gift Card
Future<IoniaGiftCard> getGiftCard({
@required String username,
@required String password,
@required String clientId,
@required int id}) async {
required String username,
required String password,
required String clientId,
required int id}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -387,7 +384,7 @@ class IoniaApi {
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
final msg = decodedBody['ErrorMessage'] as String ?? '';
@@ -406,11 +403,11 @@ class IoniaApi {
// Payment Status
Future<int> getPaymentStatus({
@required String username,
@required String password,
@required String clientId,
@required String orderId,
@required String paymentId}) async {
required String username,
required String password,
required String clientId,
required String orderId,
required String paymentId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
@@ -429,7 +426,7 @@ class IoniaApi {
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
final msg = decodedBody['ErrorMessage'] as String ?? '';
+5 -1
View File
@@ -1,5 +1,9 @@
class IoniaCategory {
const IoniaCategory({this.index, this.title, this.ids, this.iconPath});
const IoniaCategory({
required this.index,
required this.title,
required this.ids,
required this.iconPath});
static const allCategories = <IoniaCategory>[all, apparel, onlineOnly, food, entertainment, delivery, travel];
static const all = IoniaCategory(index: 0, title: 'All', ids: [], iconPath: 'assets/images/category.png');
+6 -4
View File
@@ -10,7 +10,7 @@ class IoniaCreateStateSuccess extends IoniaCreateAccountState {}
class IoniaCreateStateLoading extends IoniaCreateAccountState {}
class IoniaCreateStateFailure extends IoniaCreateAccountState {
IoniaCreateStateFailure({@required this.error});
IoniaCreateStateFailure({required this.error});
final String error;
}
@@ -26,7 +26,7 @@ class IoniaOtpSendDisabled extends IoniaOtpState {}
class IoniaOtpSendEnabled extends IoniaOtpState {}
class IoniaOtpFailure extends IoniaOtpState {
IoniaOtpFailure({@required this.error});
IoniaOtpFailure({required this.error});
final String error;
}
@@ -38,7 +38,7 @@ class IoniaCreateCardSuccess extends IoniaCreateCardState {}
class IoniaCreateCardLoading extends IoniaCreateCardState {}
class IoniaCreateCardFailure extends IoniaCreateCardState {
IoniaCreateCardFailure({@required this.error});
IoniaCreateCardFailure({required this.error});
final String error;
}
@@ -52,13 +52,15 @@ class IoniaFetchingCard extends IoniaFetchCardState {}
class IoniaFetchCardFailure extends IoniaFetchCardState {}
class IoniaCardSuccess extends IoniaFetchCardState {
IoniaCardSuccess({@required this.card});
IoniaCardSuccess({required this.card});
final IoniaVirtualCard card;
}
abstract class IoniaMerchantState {}
class InitialIoniaMerchantLoadingState extends IoniaMerchantState {}
class IoniaLoadingMerchantState extends IoniaMerchantState {}
class IoniaLoadedMerchantState extends IoniaMerchantState {}
+19 -19
View File
@@ -4,25 +4,25 @@ import 'package:flutter/foundation.dart';
class IoniaGiftCard {
IoniaGiftCard({
@required this.id,
@required this.merchantId,
@required this.legalName,
@required this.systemName,
@required this.barcodeUrl,
@required this.cardNumber,
@required this.cardPin,
@required this.instructions,
@required this.tip,
@required this.purchaseAmount,
@required this.actualAmount,
@required this.totalTransactionAmount,
@required this.totalDashTransactionAmount,
@required this.remainingAmount,
@required this.createdDateFormatted,
@required this.lastTransactionDateFormatted,
@required this.isActive,
@required this.isEmpty,
@required this.logoUrl});
required this.id,
required this.merchantId,
required this.legalName,
required this.systemName,
required this.barcodeUrl,
required this.cardNumber,
required this.cardPin,
required this.instructions,
required this.tip,
required this.purchaseAmount,
required this.actualAmount,
required this.totalTransactionAmount,
required this.totalDashTransactionAmount,
required this.remainingAmount,
required this.createdDateFormatted,
required this.lastTransactionDateFormatted,
required this.isActive,
required this.isEmpty,
required this.logoUrl});
factory IoniaGiftCard.fromJsonMap(Map<String, dynamic> element) {
return IoniaGiftCard(
+1 -1
View File
@@ -6,7 +6,7 @@ class IoniaGiftCardInstruction {
factory IoniaGiftCardInstruction.fromJsonMap(Map<String, dynamic> element) {
return IoniaGiftCardInstruction(
toBeginningOfSentenceCase(element['title'] as String ?? ''),
toBeginningOfSentenceCase(element['title'] as String? ?? '') ?? '',
element['description'] as String);
}
+35 -129
View File
@@ -1,63 +1,31 @@
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/ionia/ionia_gift_card_instruction.dart';
import 'package:cake_wallet/generated/i18n.dart';
class IoniaMerchant {
IoniaMerchant({
@required this.id,
@required this.legalName,
@required this.systemName,
@required this.description,
@required this.website,
@required this.termsAndConditions,
@required this.logoUrl,
@required this.cardImageUrl,
@required this.cardholderAgreement,
@required this.purchaseFee,
@required this.revenueShare,
@required this.marketingFee,
@required this.minimumDiscount,
@required this.level1,
@required this.level2,
@required this.level3,
@required this.level4,
@required this.level5,
@required this.level6,
@required this.level7,
@required this.isActive,
@required this.isDeleted,
@required this.isOnline,
@required this.isPhysical,
@required this.isVariablePurchase,
@required this.minimumCardPurchase,
@required this.maximumCardPurchase,
@required this.acceptsTips,
@required this.createdDateFormatted,
@required this.createdBy,
@required this.isRegional,
@required this.modifiedDateFormatted,
@required this.modifiedBy,
@required this.usageInstructions,
@required this.usageInstructionsBak,
@required this.paymentGatewayId,
@required this.giftCardGatewayId,
@required this.isHtmlDescription,
@required this.purchaseInstructions,
@required this.balanceInstructions,
@required this.amountPerCard,
@required this.processingMessage,
@required this.hasBarcode,
@required this.hasInventory,
@required this.isVoidable,
@required this.receiptMessage,
@required this.cssBorderCode,
@required this.instructions,
@required this.alderSku,
@required this.ngcSku,
@required this.acceptedCurrency,
@required this.deepLink,
@required this.isPayLater,
@required this.savingsPercentage});
required this.id,
required this.legalName,
required this.systemName,
required this.description,
required this.website,
required this.termsAndConditions,
required this.logoUrl,
required this.cardImageUrl,
required this.cardholderAgreement,
required this.isActive,
required this.isOnline,
required this.isPhysical,
required this.isVariablePurchase,
required this.minimumCardPurchase,
required this.maximumCardPurchase,
required this.acceptsTips,
required this.createdDateFormatted,
required this.modifiedDateFormatted,
required this.usageInstructions,
required this.usageInstructionsBak,
required this.hasBarcode,
required this.instructions,
required this.savingsPercentage});
factory IoniaMerchant.fromJsonMap(Map<String, dynamic> element) {
return IoniaMerchant(
@@ -70,50 +38,19 @@ class IoniaMerchant {
logoUrl: element["LogoUrl"] as String,
cardImageUrl: element["CardImageUrl"] as String,
cardholderAgreement: element["CardholderAgreement"] as String,
purchaseFee: element["PurchaseFee"] as double,
revenueShare: element["RevenueShare"] as double,
marketingFee: element["MarketingFee"] as double,
minimumDiscount: element["MinimumDiscount"] as double,
level1: element["Level1"] as double,
level2: element["Level2"] as double,
level3: element["Level3"] as double,
level4: element["Level4"] as double,
level5: element["Level5"] as double,
level6: element["Level6"] as double,
level7: element["Level7"] as double,
isActive: element["IsActive"] as bool,
isDeleted: element["IsDeleted"] as bool,
isActive: element["IsActive"] as bool?,
isOnline: element["IsOnline"] as bool,
isPhysical: element["IsPhysical"] as bool,
isVariablePurchase: element["IsVariablePurchase"] as bool,
minimumCardPurchase: element["MinimumCardPurchase"] as double,
maximumCardPurchase: element["MaximumCardPurchase"] as double,
acceptsTips: element["AcceptsTips"] as bool,
createdDateFormatted: element["CreatedDate"] as String,
createdBy: element["CreatedBy"] as int,
isRegional: element["IsRegional"] as bool,
modifiedDateFormatted: element["ModifiedDate"] as String,
modifiedBy: element["ModifiedBy"] as int,
usageInstructions: element["UsageInstructions"] as String,
usageInstructionsBak: element["UsageInstructionsBak"] as String,
paymentGatewayId: element["PaymentGatewayId"] as int,
giftCardGatewayId: element["GiftCardGatewayId"] as int ,
isHtmlDescription: element["IsHtmlDescription"] as bool,
purchaseInstructions: element["PurchaseInstructions"] as String,
balanceInstructions: element["BalanceInstructions"] as String,
amountPerCard: element["AmountPerCard"] as double,
processingMessage: element["ProcessingMessage"] as String,
createdDateFormatted: element["CreatedDate"] as String?,
modifiedDateFormatted: element["ModifiedDate"] as String?,
usageInstructions: element["UsageInstructions"] as String?,
usageInstructionsBak: element["UsageInstructionsBak"] as String?,
hasBarcode: element["HasBarcode"] as bool,
hasInventory: element["HasInventory"] as bool,
isVoidable: element["IsVoidable"] as bool,
receiptMessage: element["ReceiptMessage"] as String,
cssBorderCode: element["CssBorderCode"] as String,
instructions: IoniaGiftCardInstruction.parseListOfInstructions(element['PaymentInstructions'] as String),
alderSku: element["AlderSku"] as String,
ngcSku: element["NgcSku"] as String,
acceptedCurrency: element["AcceptedCurrency"] as String,
deepLink: element["DeepLink"] as String,
isPayLater: element["IsPayLater"] as bool,
savingsPercentage: element["SavingsPercentage"] as double);
}
@@ -126,50 +63,19 @@ class IoniaMerchant {
final String logoUrl;
final String cardImageUrl;
final String cardholderAgreement;
final double purchaseFee;
final double revenueShare;
final double marketingFee;
final double minimumDiscount;
final double level1;
final double level2;
final double level3;
final double level4;
final double level5;
final double level6;
final double level7;
final bool isActive;
final bool isDeleted;
final bool? isActive;
final bool isOnline;
final bool isPhysical;
final bool? isPhysical;
final bool isVariablePurchase;
final double minimumCardPurchase;
final double maximumCardPurchase;
final bool acceptsTips;
final String createdDateFormatted;
final int createdBy;
final bool isRegional;
final String modifiedDateFormatted;
final int modifiedBy;
final String usageInstructions;
final String usageInstructionsBak;
final int paymentGatewayId;
final int giftCardGatewayId;
final bool isHtmlDescription;
final String purchaseInstructions;
final String balanceInstructions;
final double amountPerCard;
final String processingMessage;
final String? createdDateFormatted;
final String? modifiedDateFormatted;
final String? usageInstructions;
final String? usageInstructionsBak;
final bool hasBarcode;
final bool hasInventory;
final bool isVoidable;
final String receiptMessage;
final String cssBorderCode;
final List<IoniaGiftCardInstruction> instructions;
final String alderSku;
final String ngcSku;
final String acceptedCurrency;
final String deepLink;
final bool isPayLater;
final double savingsPercentage;
double get discount => savingsPercentage;
@@ -181,7 +87,7 @@ class IoniaMerchant {
status += S.current.online;
}
if (isPhysical) {
if (isPhysical ?? false) {
if (status.isNotEmpty) {
status = '$status & ';
}
+5 -5
View File
@@ -1,11 +1,11 @@
import 'package:flutter/foundation.dart';
class IoniaOrder {
IoniaOrder({@required this.id,
@required this.uri,
@required this.currency,
@required this.amount,
@required this.paymentId});
IoniaOrder({required this.id,
required this.uri,
required this.currency,
required this.amount,
required this.paymentId});
factory IoniaOrder.fromMap(Map<String, dynamic> obj) {
return IoniaOrder(
id: obj['order_id'] as String,
+32 -33
View File
@@ -1,7 +1,6 @@
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/ionia/ionia_api.dart';
@@ -32,8 +31,8 @@ class IoniaService {
// Verify email
Future<void> verifyEmail(String code) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final email = await secureStorage.read(key: ioniaEmailStorageKey);
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final email = (await secureStorage.read(key: ioniaEmailStorageKey))!;
final credentials = await ioniaApi.verifyEmail(email: email, username: username, code: code, clientId: clientId);
await secureStorage.write(key: ioniaPasswordStorageKey, value: credentials.password);
await secureStorage.write(key: ioniaUsernameStorageKey, value: credentials.username);
@@ -48,7 +47,7 @@ class IoniaService {
}
Future<String> getUserEmail() async {
return secureStorage.read(key: ioniaEmailStorageKey);
return (await secureStorage.read(key: ioniaEmailStorageKey))!;
}
// Check is user logined
@@ -69,35 +68,35 @@ class IoniaService {
// Create virtual card
Future<IoniaVirtualCard> createCard() async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.createCard(username: username, password: password, clientId: clientId);
}
// Get virtual card
Future<IoniaVirtualCard> getCard() async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getCards(username: username, password: password, clientId: clientId);
}
// Get Merchants
Future<List<IoniaMerchant>> getMerchants() async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getMerchants(username: username, password: password, clientId: clientId);
}
// Get Merchants By Filter
Future<List<IoniaMerchant>> getMerchantsByFilter({
String search,
List<IoniaCategory> categories,
String? search,
List<IoniaCategory>? categories,
int merchantFilterType = 0}) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getMerchantsByFilter(
username: username,
password: password,
@@ -110,14 +109,14 @@ class IoniaService {
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
@required String merchId,
@required double amount,
@required String currency}) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
required String merchId,
required double amount,
required String currency}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
final deviceId = await PlatformDeviceId.getDeviceId;
return ioniaApi.purchaseGiftCard(
requestedUUID: deviceId,
requestedUUID: deviceId!,
merchId: merchId,
amount: amount,
currency: currency,
@@ -129,18 +128,18 @@ class IoniaService {
// Get Current User Gift Card Summaries
Future<List<IoniaGiftCard>> getCurrentUserGiftCardSummaries() async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getCurrentUserGiftCardSummaries(username: username, password: password, clientId: clientId);
}
// Charge Gift Card
Future<void> chargeGiftCard({
@required int giftCardId,
@required double amount}) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
required int giftCardId,
required double amount}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
await ioniaApi.chargeGiftCard(
username: username,
password: password,
@@ -157,19 +156,19 @@ class IoniaService {
// Get Gift Card
Future<IoniaGiftCard> getGiftCard({@required int id}) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
Future<IoniaGiftCard> getGiftCard({required int id}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getGiftCard(username: username, password: password, clientId: clientId,id: id);
}
// Payment Status
Future<int> getPaymentStatus({
@required String orderId,
@required String paymentId}) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
required String orderId,
required String paymentId}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getPaymentStatus(username: username, password: password, clientId: clientId, orderId: orderId, paymentId: paymentId);
}
}
+6 -1
View File
@@ -1,8 +1,13 @@
class IoniaTip {
const IoniaTip({this.originalAmount, this.percentage, this.isCustom = false});
const IoniaTip({
required this.originalAmount,
required this.percentage,
this.isCustom = false});
final double originalAmount;
final double percentage;
final bool isCustom;
double get additionalAmount => double.parse((originalAmount * percentage / 100).toStringAsFixed(2));
static const tipList = [
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
import 'dart:convert';
class IoniaTokenData {
IoniaTokenData({@required this.accessToken, @required this.tokenType, @required this.expiredAt});
IoniaTokenData({required this.accessToken, required this.tokenType, required this.expiredAt});
factory IoniaTokenData.fromJson(String source) {
final decoded = json.decode(source) as Map<String, dynamic>;
+11 -13
View File
@@ -1,17 +1,15 @@
import 'package:flutter/foundation.dart';
class IoniaVirtualCard {
IoniaVirtualCard({
@required this.token,
@required this.createdAt,
@required this.lastFour,
@required this.state,
@required this.pan,
@required this.cvv,
@required this.expirationMonth,
@required this.expirationYear,
@required this.fundsLimit,
@required this.spendLimit});
required this.token,
required this.createdAt,
required this.lastFour,
required this.state,
required this.pan,
required this.cvv,
required this.expirationMonth,
required this.expirationYear,
required this.fundsLimit,
required this.spendLimit});
factory IoniaVirtualCard.fromMap(Map<String, Object> source) {
final created = source['created'] as String;
@@ -37,7 +35,7 @@ class IoniaVirtualCard {
final String cvv;
final String expirationMonth;
final String expirationYear;
final DateTime createdAt;
final DateTime? createdAt;
final double fundsLimit;
final double spendLimit;
}
+20 -18
View File
@@ -109,7 +109,7 @@ Future<void> main() async {
final templates = await Hive.openBox<Template>(Template.boxName);
final exchangeTemplates =
await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
Box<UnspentCoinsInfo> unspentCoinsInfoSource;
Box<UnspentCoinsInfo>? unspentCoinsInfoSource;
if (!isMoneroOnly) {
unspentCoinsInfoSource = await Hive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
@@ -145,18 +145,18 @@ Future<void> main() async {
}
Future<void> initialSetup(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes,
@required Box<WalletInfo> walletInfoSource,
@required Box<Contact> contactSource,
@required Box<Trade> tradesSource,
@required Box<Order> ordersSource,
// @required FiatConvertationService fiatConvertationService,
@required Box<Template> templates,
@required Box<ExchangeTemplate> exchangeTemplates,
@required Box<TransactionDescription> transactionDescriptions,
@required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
FlutterSecureStorage secureStorage,
{required SharedPreferences sharedPreferences,
required Box<Node> nodes,
required Box<WalletInfo> walletInfoSource,
required Box<Contact> contactSource,
required Box<Trade> tradesSource,
required Box<Order> ordersSource,
// required FiatConvertationService fiatConvertationService,
required Box<Template> templates,
required Box<ExchangeTemplate> exchangeTemplates,
required Box<TransactionDescription> transactionDescriptions,
required FlutterSecureStorage secureStorage,
Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
int initialMigrationVersion = 15}) async {
LanguageService.loadLocaleList();
await defaultSettingsMigration(
@@ -188,14 +188,14 @@ class App extends StatefulWidget {
}
class AppState extends State<App> with SingleTickerProviderStateMixin {
AppState() {
yatStore = getIt.get<YatStore>();
AppState()
: yatStore = getIt.get<YatStore>() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
}
YatStore yatStore;
StreamSubscription stream;
StreamSubscription? stream;
@override
void initState() {
@@ -227,7 +227,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
void _handleIncomingLinks() {
if (!kIsWeb) {
stream = getUriLinksStream().listen((Uri uri) {
stream = getUriLinksStream().listen((Uri? uri) {
print('uri: $uri');
if (!mounted) return;
//_fetchEmojiFromUri(uri);
@@ -256,7 +256,8 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return Observer(builder: (BuildContext context) {
final settingsStore = getIt.get<AppStore>().settingsStore;
final appStore = getIt.get<AppStore>();
final settingsStore = appStore.settingsStore;
final statusBarColor = Colors.transparent;
final authenticationStore = getIt.get<AuthenticationStore>();
final initialRoute =
@@ -277,6 +278,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
return Root(
key: rootKey,
appStore: appStore,
authenticationStore: authenticationStore,
navigatorKey: navigatorKey,
child: MaterialApp(
+42 -27
View File
@@ -37,13 +37,13 @@ class CWMoneroAccountList extends MoneroAccountList {
}
@override
Future<void> addAccount(Object wallet, {String label}) async {
Future<void> addAccount(Object wallet, {required String label}) async {
final moneroWallet = wallet as MoneroWallet;
await moneroWallet.walletAddresses.accountList.addAccount(label: label);
}
@override
Future<void> setLabelAccount(Object wallet, {int accountIndex, String label}) async {
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async {
final moneroWallet = wallet as MoneroWallet;
await moneroWallet.walletAddresses.accountList
.setLabelAccount(
@@ -54,7 +54,7 @@ class CWMoneroAccountList extends MoneroAccountList {
class CWMoneroSubaddressList extends MoneroSubaddressList {
CWMoneroSubaddressList(this._wallet);
Object _wallet;
final Object _wallet;
@override
@computed
@@ -71,13 +71,13 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
}
@override
void update(Object wallet, {int accountIndex}) {
void update(Object wallet, {required int accountIndex}) {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
}
@override
void refresh(Object wallet, {int accountIndex}) {
void refresh(Object wallet, {required int accountIndex}) {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
}
@@ -93,7 +93,7 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
}
@override
Future<void> addSubaddress(Object wallet, {int accountIndex, String label}) async {
Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async {
final moneroWallet = wallet as MoneroWallet;
await moneroWallet.walletAddresses.subaddressList
.addSubaddress(
@@ -103,7 +103,7 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
@override
Future<void> setLabelSubaddress(Object wallet,
{int accountIndex, int addressIndex, String label}) async {
{required int accountIndex, required int addressIndex, required String label}) async {
final moneroWallet = wallet as MoneroWallet;
await moneroWallet.walletAddresses.subaddressList
.setLabelSubaddress(
@@ -115,20 +115,23 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
class CWMoneroWalletDetails extends MoneroWalletDetails {
CWMoneroWalletDetails(this._wallet);
Object _wallet;
final Object _wallet;
@computed
@override
Account get account {
final moneroWallet = _wallet as MoneroWallet;
final acc = moneroWallet.walletAddresses.account;
return Account(id: acc.id, label: acc.label);
return Account(id: acc!.id, label: acc.label);
}
@computed
@override
MoneroBalance get balance {
final moneroWallet = _wallet as MoneroWallet;
final balance = moneroWallet.balance;
return MoneroBalance();
throw Exception('Unimplemented');
// return MoneroBalance();
//return MoneroBalance(
// fullBalance: balance.fullBalance,
// unlockedBalance: balance.unlockedBalance);
@@ -136,6 +139,7 @@ class CWMoneroWalletDetails extends MoneroWalletDetails {
}
class CWMonero extends Monero {
@override
MoneroAccountList getAccountList(Object wallet) {
return CWMoneroAccountList(wallet);
}
@@ -157,7 +161,7 @@ class CWMonero extends Monero {
}
@override
int getHeigthByDate({DateTime date}) {
int getHeigthByDate({required DateTime date}) {
return getMoneroHeigthByDate(date: date);
}
@@ -167,7 +171,7 @@ class CWMonero extends Monero {
}
@override
TransactionPriority deserializeMoneroTransactionPriority({int raw}) {
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
return MoneroTransactionPriority.deserialize(raw: raw);
}
@@ -206,13 +210,13 @@ class CWMonero extends Monero {
@override
WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
String name,
String spendKey,
String viewKey,
String address,
String password,
String language,
int height}) {
required String name,
required String spendKey,
required String viewKey,
required String address,
required String password,
required String language,
required int height}) {
return MoneroRestoreWalletFromKeysCredentials(
name: name,
spendKey: spendKey,
@@ -224,7 +228,11 @@ class CWMonero extends Monero {
}
@override
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic}) {
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({
required String name,
required String password,
required int height,
required String mnemonic}) {
return MoneroRestoreWalletFromSeedCredentials(
name: name,
password: password,
@@ -233,7 +241,10 @@ class CWMonero extends Monero {
}
@override
WalletCredentials createMoneroNewWalletCredentials({String name, String password, String language}) {
WalletCredentials createMoneroNewWalletCredentials({
required String name,
required String language,
String? password,}) {
return MoneroNewWalletCredentials(
name: name,
password: password,
@@ -252,7 +263,9 @@ class CWMonero extends Monero {
}
@override
Object createMoneroTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority}) {
Object createMoneroTransactionCreationCredentials({
required List<Output> outputs,
required TransactionPriority priority}) {
return MoneroTransactionCreationCredentials(
outputs: outputs.map((out) => OutputInfo(
fiatAmount: out.fiatAmount,
@@ -268,24 +281,26 @@ class CWMonero extends Monero {
}
@override
Object createMoneroTransactionCreationCredentialsRaw({List<OutputInfo> outputs, TransactionPriority priority}) {
Object createMoneroTransactionCreationCredentialsRaw({
required List<OutputInfo> outputs,
required TransactionPriority priority}) {
return MoneroTransactionCreationCredentials(
outputs: outputs,
priority: priority as MoneroTransactionPriority);
}
@override
String formatterMoneroAmountToString({int amount}) {
String formatterMoneroAmountToString({required int amount}) {
return moneroAmountToString(amount: amount);
}
@override
double formatterMoneroAmountToDouble({int amount}) {
double formatterMoneroAmountToDouble({required int amount}) {
return moneroAmountToDouble(amount: amount);
}
@override
int formatterMoneroParseAmount({String amount}) {
int formatterMoneroParseAmount({required String amount}) {
return moneroParseAmount(amount: amount);
}
@@ -293,7 +308,7 @@ class CWMonero extends Monero {
Account getCurrentAccount(Object wallet) {
final moneroWallet = wallet as MoneroWallet;
final acc = moneroWallet.walletAddresses.account;
return Account(id: acc.id, label: acc.label);
return Account(id: acc!.id, label: acc.label);
}
@override

Some files were not shown because too many files have changed in this diff Show More