v4.10.0 & v1.7.0 (#1113)

* New versions * update the new version text after macos [skip ci] * add cake-wallet headers * add nano/banano to getAddressFromStringPattern * Revert "Exolix integration (#1080)" This reverts commit 9eb6867ab98dbb3a5fec64e0c940c716cf1fd43c. * fix: Bug in conditions check and clean up of repeated code in switch cases (#1117) * update build numbers [skip ci] --------- Co-authored-by: fosse <matt.cfosse@gmail.com> Co-authored-by: Adegoke David <64401859+Blazebrain@users.noreply.github.com>

Omar Hatem committed Oct 9, 2023 at 18:18 UTC e5408a388e31b6fa3c669c9516034d4ef2d2e38f
32 files changed +146 -554
.github/workflows/pr_test_build.yml
-1
@@ -128,7 +128,6 @@ jobs:
128 echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
129 echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_ethereum/lib/.secrets.g.dart
130 echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
131 - echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
131 echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
132 echo "const robinhoodCIdApiSecret = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
133 echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
assets/images/exolix.png
Binary files a/assets/images/exolix.png and /dev/null differ
assets/text/Monerocom_Release_Notes.txt
+1 -1
@@ -1,3 +1,3 @@
1 -Fix 2FA code issue
1 +Support getting Addresses from ENS and Mastodon
2 Bug fixes
3 Minor enhancements
\ No newline at end of file
assets/text/Release_Notes.txt
+3 -2
@@ -1,4 +1,5 @@
1 -Ethereum enhancements and bug fixes
2 -Fix 2FA code issue
1 +Add Nano wallet
2 +Add WalletConnect to connect your ETH wallet with your favorite dApp
3 +Support getting Addresses from ENS and Mastodon
4 Bug fixes
5 Minor enhancements
\ No newline at end of file
cw_nano/lib/nano_client.dart
+12 -12
@@ -13,6 +13,11 @@ class NanoClient {
13 static const String DEFAULT_REPRESENTATIVE =
14 "nano_38713x95zyjsqzx6nm1dsom1jmm668owkeb9913ax6nfgj15az3nu8xkx579";
15
16 + static const Map<String, String> CAKE_HEADERS = {
17 + "Content-Type": "application/json",
18 + "nano-app": "cake-wallet"
19 + };
20 +
21 Node? _node;
22 Node? _powNode;
23
@@ -37,7 +42,7 @@ class NanoClient {
42 Future<NanoBalance> getBalance(String address) async {
43 final response = await http.post(
44 _node!.uri,
40 - headers: {"Content-Type": "application/json"},
45 + headers: CAKE_HEADERS,
46 body: jsonEncode(
47 {
48 "action": "account_balance",
@@ -57,7 +62,7 @@ class NanoClient {
62 try {
63 final response = await http.post(
64 _node!.uri,
60 - headers: {"Content-Type": "application/json"},
65 + headers: CAKE_HEADERS,
66 body: jsonEncode(
67 {
68 "action": "account_info",
@@ -123,7 +128,7 @@ class NanoClient {
128 Future<String> requestWork(String hash) async {
129 final response = await http.post(
130 _powNode!.uri,
126 - headers: {'Content-type': 'application/json'},
131 + headers: CAKE_HEADERS,
132 body: json.encode(
133 {
134 "action": "work_generate",
@@ -157,7 +162,6 @@ class NanoClient {
162 }
163
164 Future<String> processBlock(Map<String, String> block, String subtype) async {
160 - final headers = {"Content-Type": "application/json"};
165 final processBody = jsonEncode({
166 "action": "process",
167 "json_block": "true",
@@ -167,7 +171,7 @@ class NanoClient {
171
172 final processResponse = await http.post(
173 _node!.uri,
170 - headers: headers,
174 + headers: CAKE_HEADERS,
175 body: processBody,
176 );
177
@@ -260,10 +264,6 @@ class NanoClient {
264 }) async {
265 bool openBlock = false;
266
263 - final headers = {
264 - "Content-Type": "application/json",
265 - };
266 -
267 // first check if the account is open:
268 // get the account info (we need the frontier and representative):
269 AccountInfoResponse? infoData = await getAccountInfo(destinationAddress);
@@ -335,7 +335,7 @@ class NanoClient {
335 });
336 final processResponse = await http.post(
337 _node!.uri,
338 - headers: headers,
338 + headers: CAKE_HEADERS,
339 body: processBody,
340 );
341
@@ -351,7 +351,7 @@ class NanoClient {
351 required String privateKey,
352 }) async {
353 final receivableResponse = await http.post(_node!.uri,
354 - headers: {"Content-Type": "application/json"},
354 + headers: CAKE_HEADERS,
355 body: jsonEncode({
356 "action": "receivable",
357 "account": destinationAddress,
@@ -401,7 +401,7 @@ class NanoClient {
401 Future<List<NanoTransactionModel>> fetchTransactions(String address) async {
402 try {
403 final response = await http.post(_node!.uri,
404 - headers: {"Content-Type": "application/json"},
404 + headers: CAKE_HEADERS,
405 body: jsonEncode({
406 "action": "account_history",
407 "account": address,
lib/core/address_validator.dart
+4
@@ -267,6 +267,10 @@ class AddressValidator extends TextValidator {
267 '|([^0-9a-zA-Z]|^)ltc[a-zA-Z0-9]{26,45}([^0-9a-zA-Z]|\$)';
268 case CryptoCurrency.eth:
269 return '0x[0-9a-zA-Z]{42}';
270 + case CryptoCurrency.nano:
271 + return 'nano_[0-9a-zA-Z]{60}';
272 + case CryptoCurrency.banano:
273 + return 'ban_[0-9a-zA-Z]{60}';
274 default:
275 return null;
276 }
lib/core/backup_service.dart
+2 -1
@@ -1,6 +1,7 @@
1 import 'dart:convert';
2 import 'dart:io';
3 import 'dart:typed_data';
4 +import 'package:cake_wallet/utils/device_info.dart';
5 import 'package:cw_core/wallet_type.dart';
6 import 'package:flutter/foundation.dart';
7 import 'package:hive/hive.dart';
@@ -308,7 +309,7 @@ class BackupService {
309 if (currentPinLength != null)
310 await _sharedPreferences.setInt(PreferencesKey.currentPinLength, currentPinLength);
311
311 - if (currentTheme != null)
312 + if (currentTheme != null && DeviceInfo.instance.isMobile)
313 await _sharedPreferences.setInt(PreferencesKey.currentTheme, currentTheme);
314
315 if (exchangeStatus != null)
lib/di.dart
-8
@@ -417,10 +417,6 @@ Future<void> setup({
417 }
418 if (appStore.wallet != null) {
419 authStore.allowed();
420 -
421 - if (appStore.wallet!.type == WalletType.ethereum) {
422 - getIt.get<Web3WalletService>().init();
423 - }
420 return;
421 }
422
@@ -441,10 +437,6 @@ Future<void> setup({
437 } else {
438 if (appStore.wallet != null) {
439 authStore.allowed();
444 -
445 - if (appStore.wallet!.type == WalletType.ethereum) {
446 - getIt.get<Web3WalletService>().init();
447 - }
440 return;
441 }
442
lib/entities/cake_2fa_preset_options.dart
+3
@@ -6,6 +6,7 @@ class Cake2FAPresetsOptions extends EnumerableItem<int> with Serializable<int> {
6 static const narrow = Cake2FAPresetsOptions(title: 'Narrow', raw: 0);
7 static const normal = Cake2FAPresetsOptions(title: 'Normal', raw: 1);
8 static const aggressive = Cake2FAPresetsOptions(title: 'Aggressive', raw: 2);
9 + static const none = Cake2FAPresetsOptions(title: 'None', raw: 3);
10
11 static Cake2FAPresetsOptions deserialize({required int raw}) {
12 switch (raw) {
@@ -15,6 +16,8 @@ class Cake2FAPresetsOptions extends EnumerableItem<int> with Serializable<int> {
16 return Cake2FAPresetsOptions.normal;
17 case 2:
18 return Cake2FAPresetsOptions.aggressive;
19 + case 3:
20 + return Cake2FAPresetsOptions.none;
21 default:
22 throw Exception(
23 'Incorrect Cake 2FA Preset $raw for Cake2FAPresetOptions deserialize',
lib/exchange/exchange_provider_description.dart
+1 -6
@@ -24,10 +24,7 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
24 static const trocador =
25 ExchangeProviderDescription(title: 'Trocador', raw: 5, image: 'assets/images/trocador.png');
26
27 - static const exolix =
28 - ExchangeProviderDescription(title: 'Exolix', raw: 6, image: 'assets/images/exolix.png');
29 -
30 - static const all = ExchangeProviderDescription(title: 'All trades', raw: 7, image: '');
27 + static const all = ExchangeProviderDescription(title: 'All trades', raw: 6, image: '');
28
29 static ExchangeProviderDescription deserialize({required int raw}) {
30 switch (raw) {
@@ -44,8 +41,6 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
41 case 5:
42 return trocador;
43 case 6:
47 - return exolix;
48 - case 7:
44 return all;
45 default:
46 throw Exception('Unexpected token: $raw for ExchangeProviderDescription deserialize');
lib/exchange/exolix/exolix_exchange_provider.dart deleted
-294
@@ -1,294 +0,0 @@
1 -import 'dart:convert';
2 -import 'package:cake_wallet/exchange/trade_not_found_exeption.dart';
3 -import 'package:http/http.dart';
4 -import 'package:cake_wallet/.secrets.g.dart' as secrets;
5 -import 'package:cw_core/crypto_currency.dart';
6 -import 'package:cake_wallet/exchange/exchange_pair.dart';
7 -import 'package:cake_wallet/exchange/exchange_provider.dart';
8 -import 'package:cake_wallet/exchange/limits.dart';
9 -import 'package:cake_wallet/exchange/trade.dart';
10 -import 'package:cake_wallet/exchange/trade_request.dart';
11 -import 'package:cake_wallet/exchange/trade_state.dart';
12 -import 'package:cake_wallet/exchange/exolix/exolix_request.dart';
13 -import 'package:cake_wallet/exchange/exchange_provider_description.dart';
14 -
15 -class ExolixExchangeProvider extends ExchangeProvider {
16 - ExolixExchangeProvider() : super(pairList: _supportedPairs());
17 -
18 - static final apiKey = secrets.exolixApiKey;
19 - static const apiBaseUrl = 'exolix.com';
20 - static const transactionsPath = '/api/v2/transactions';
21 - static const ratePath = '/api/v2/rate';
22 -
23 - static const List<CryptoCurrency> _notSupported = [
24 - CryptoCurrency.usdt,
25 - CryptoCurrency.xhv,
26 - CryptoCurrency.btt,
27 - CryptoCurrency.firo,
28 - CryptoCurrency.zaddr,
29 - CryptoCurrency.xvg,
30 - CryptoCurrency.kmd,
31 - CryptoCurrency.paxg,
32 - CryptoCurrency.rune,
33 - CryptoCurrency.scrt,
34 - CryptoCurrency.btcln,
35 - CryptoCurrency.cro,
36 - CryptoCurrency.ftm,
37 - CryptoCurrency.frax,
38 - CryptoCurrency.gusd,
39 - CryptoCurrency.gtc,
40 - CryptoCurrency.weth,
41 - ];
42 -
43 - static List<ExchangePair> _supportedPairs() {
44 - final supportedCurrencies =
45 - CryptoCurrency.all.where((element) => !_notSupported.contains(element)).toList();
46 -
47 - return supportedCurrencies
48 - .map((i) => supportedCurrencies.map((k) => ExchangePair(from: i, to: k, reverse: true)))
49 - .expand((i) => i)
50 - .toList();
51 - }
52 -
53 - @override
54 - String get title => 'Exolix';
55 -
56 - @override
57 - bool get isAvailable => true;
58 -
59 - @override
60 - bool get isEnabled => true;
61 -
62 - @override
63 - bool get supportsFixedRate => true;
64 -
65 - @override
66 - ExchangeProviderDescription get description => ExchangeProviderDescription.exolix;
67 -
68 - @override
69 - Future<bool> checkIsAvailable() async => true;
70 -
71 - static String getRateType(bool isFixedRate) => isFixedRate ? 'fixed' : 'float';
72 -
73 - @override
74 - Future<Limits> fetchLimits(
75 - {required CryptoCurrency from,
76 - required CryptoCurrency to,
77 - required bool isFixedRateMode}) async {
78 - final params = <String, String>{
79 - 'rateType': getRateType(isFixedRateMode),
80 - 'amount': '1',
81 - };
82 - if (isFixedRateMode) {
83 - params['coinFrom'] = _normalizeCurrency(to);
84 - params['coinTo'] = _normalizeCurrency(from);
85 - params['networkFrom'] = _networkFor(to);
86 - params['networkTo'] = _networkFor(from);
87 - } else {
88 - params['coinFrom'] = _normalizeCurrency(from);
89 - params['coinTo'] = _normalizeCurrency(to);
90 - params['networkFrom'] = _networkFor(from);
91 - params['networkTo'] = _networkFor(to);
92 - }
93 - final uri = Uri.https(apiBaseUrl, ratePath, params);
94 - final response = await get(uri);
95 -
96 - if (response.statusCode != 200) {
97 - throw Exception('Unexpected http status: ${response.statusCode}');
98 - }
99 -
100 - final responseJSON = json.decode(response.body) as Map<String, dynamic>;
101 - return Limits(min: responseJSON['minAmount'] as double?);
102 - }
103 -
104 - @override
105 - Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
106 - final _request = request as ExolixRequest;
107 -
108 - final headers = {'Content-Type': 'application/json'};
109 - final body = <String, dynamic>{
110 - 'coinFrom': _normalizeCurrency(_request.from),
111 - 'coinTo': _normalizeCurrency(_request.to),
112 - 'networkFrom': _networkFor(_request.from),
113 - 'networkTo': _networkFor(_request.to),
114 - 'withdrawalAddress': _request.address,
115 - 'refundAddress': _request.refundAddress,
116 - 'rateType': getRateType(isFixedRateMode),
117 - 'apiToken': apiKey,
118 - };
119 -
120 - if (isFixedRateMode) {
121 - body['withdrawalAmount'] = _request.toAmount;
122 - } else {
123 - body['amount'] = _request.fromAmount;
124 - }
125 -
126 - final uri = Uri.https(apiBaseUrl, transactionsPath);
127 - final response = await post(uri, headers: headers, body: json.encode(body));
128 -
129 - if (response.statusCode == 400) {
130 - final responseJSON = json.decode(response.body) as Map<String, dynamic>;
131 - final errors = responseJSON['errors'] as Map<String, String>;
132 - final errorMessage = errors.values.join(', ');
133 - throw Exception(errorMessage);
134 - }
135 -
136 - if (response.statusCode != 200 && response.statusCode != 201) {
137 - throw Exception('Unexpected http status: ${response.statusCode}');
138 - }
139 -
140 - final responseJSON = json.decode(response.body) as Map<String, dynamic>;
141 - final id = responseJSON['id'] as String;
142 - final inputAddress = responseJSON['depositAddress'] as String;
143 - final refundAddress = responseJSON['refundAddress'] as String?;
144 - final extraId = responseJSON['depositExtraId'] as String?;
145 - final payoutAddress = responseJSON['withdrawalAddress'] as String;
146 - final amount = responseJSON['amount'].toString();
147 -
148 - return Trade(
149 - id: id,
150 - from: _request.from,
151 - to: _request.to,
152 - provider: description,
153 - inputAddress: inputAddress,
154 - refundAddress: refundAddress,
155 - extraId: extraId,
156 - createdAt: DateTime.now(),
157 - amount: amount,
158 - state: TradeState.created,
159 - payoutAddress: payoutAddress);
160 - }
161 -
162 - @override
163 - Future<Trade> findTradeById({required String id}) async {
164 - final findTradeByIdPath = transactionsPath + '/$id';
165 - final uri = Uri.https(apiBaseUrl, findTradeByIdPath);
166 - final response = await get(uri);
167 -
168 - if (response.statusCode == 404) {
169 - throw TradeNotFoundException(id, provider: description);
170 - }
171 -
172 - if (response.statusCode == 400) {
173 - final responseJSON = json.decode(response.body) as Map<String, dynamic>;
174 - final errors = responseJSON['errors'] as Map<String, String>;
175 - final errorMessage = errors.values.join(', ');
176 -
177 - throw TradeNotFoundException(id, provider: description, description: errorMessage);
178 - }
179 -
180 - if (response.statusCode != 200) {
181 - throw Exception('Unexpected http status: ${response.statusCode}');
182 - }
183 -
184 - final responseJSON = json.decode(response.body) as Map<String, dynamic>;
185 - final coinFrom = responseJSON['coinFrom']['coinCode'] as String;
186 - final from = CryptoCurrency.fromString(coinFrom);
187 - final coinTo = responseJSON['coinTo']['coinCode'] as String;
188 - final to = CryptoCurrency.fromString(coinTo);
189 - final inputAddress = responseJSON['depositAddress'] as String;
190 - final amount = responseJSON['amount'].toString();
191 - final status = responseJSON['status'] as String;
192 - final state = TradeState.deserialize(raw: _prepareStatus(status));
193 - final extraId = responseJSON['depositExtraId'] as String?;
194 - final outputTransaction = responseJSON['hashOut']['hash'] as String?;
195 - final payoutAddress = responseJSON['withdrawalAddress'] as String;
196 -
197 - return Trade(
198 - id: id,
199 - from: from,
200 - to: to,
201 - provider: description,
202 - inputAddress: inputAddress,
203 - amount: amount,
204 - state: state,
205 - extraId: extraId,
206 - outputTransaction: outputTransaction,
207 - payoutAddress: payoutAddress);
208 - }
209 -
210 - @override
211 - Future<double> fetchRate(
212 - {required CryptoCurrency from,
213 - required CryptoCurrency to,
214 - required double amount,
215 - required bool isFixedRateMode,
216 - required bool isReceiveAmount}) async {
217 - try {
218 - if (amount == 0) {
219 - return 0.0;
220 - }
221 -
222 - final params = <String, String>{
223 - 'coinFrom': _normalizeCurrency(from),
224 - 'coinTo': _normalizeCurrency(to),
225 - 'networkFrom': _networkFor(from),
226 - 'networkTo': _networkFor(to),
227 - 'rateType': getRateType(isFixedRateMode),
228 - };
229 -
230 - if (isReceiveAmount) {
231 - params['withdrawalAmount'] = amount.toString();
232 - } else {
233 - params['amount'] = amount.toString();
234 - }
235 -
236 - final uri = Uri.https(apiBaseUrl, ratePath, params);
237 - final response = await get(uri);
238 - final responseJSON = json.decode(response.body) as Map<String, dynamic>;
239 -
240 - if (response.statusCode != 200) {
241 - final message = responseJSON['message'] as String?;
242 - throw Exception(message);
243 - }
244 -
245 - final rate = responseJSON['rate'] as double;
246 -
247 - return rate;
248 - } catch (e) {
249 - print(e.toString());
250 - return 0.0;
251 - }
252 - }
253 -
254 - String _prepareStatus(String status) {
255 - switch (status) {
256 - case 'deleted':
257 - case 'error':
258 - return 'overdue';
259 - default:
260 - return status;
261 - }
262 - }
263 -
264 - String _networkFor(CryptoCurrency currency) {
265 - switch (currency) {
266 - case CryptoCurrency.arb:
267 - return 'ARBITRUM';
268 - default:
269 - return currency.tag != null ? _normalizeTag(currency.tag!) : currency.title;
270 - }
271 - }
272 -
273 - String _normalizeCurrency(CryptoCurrency currency) {
274 - switch (currency) {
275 - case CryptoCurrency.nano:
276 - return 'XNO';
277 - case CryptoCurrency.bttc:
278 - return 'BTT';
279 - case CryptoCurrency.zec:
280 - return 'ZEC';
281 - default:
282 - return currency.title;
283 - }
284 - }
285 -
286 - String _normalizeTag(String tag) {
287 - switch (tag) {
288 - case 'POLY':
289 - return 'Polygon';
290 - default:
291 - return tag;
292 - }
293 - }
294 -}
lib/exchange/exolix/exolix_request.dart deleted
-20
@@ -1,20 +0,0 @@
1 -import 'package:flutter/foundation.dart';
2 -import 'package:cw_core/crypto_currency.dart';
3 -import 'package:cake_wallet/exchange/trade_request.dart';
4 -
5 -class ExolixRequest extends TradeRequest {
6 - ExolixRequest(
7 - {required this.from,
8 - required this.to,
9 - required this.address,
10 - required this.fromAmount,
11 - required this.toAmount,
12 - required this.refundAddress});
13 -
14 - CryptoCurrency from;
15 - CryptoCurrency to;
16 - String address;
17 - String fromAmount;
18 - String toAmount;
19 - String refundAddress;
20 -}
lib/exchange/trade_state.dart
-27
@@ -35,15 +35,6 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
35 static const completed = TradeState(raw: 'completed', title: 'Completed');
36 static const settling = TradeState(raw: 'settling', title: 'Settlement in progress');
37 static const settled = TradeState(raw: 'settled', title: 'Settlement completed');
38 - static const wait = TradeState(raw: 'wait', title: 'Waiting');
39 - static const overdue = TradeState(raw: 'overdue', title: 'Overdue');
40 - static const refund = TradeState(raw: 'refund', title: 'Refund');
41 - static const refunded = TradeState(raw: 'refunded', title: 'Refunded');
42 - static const confirmation = TradeState(raw: 'confirmation', title: 'Confirmation');
43 - static const confirmed = TradeState(raw: 'confirmed', title: 'Confirmed');
44 - static const exchanging = TradeState(raw: 'exchanging', title: 'Exchanging');
45 - static const sending = TradeState(raw: 'sending', title: 'Sending');
46 - static const success = TradeState(raw: 'success', title: 'Success');
38 static TradeState deserialize({required String raw}) {
39 switch (raw) {
40 case 'pending':
@@ -86,24 +77,6 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
77 return failed;
78 case 'completed':
79 return completed;
89 - case 'wait':
90 - return wait;
91 - case 'overdue':
92 - return overdue;
93 - case 'refund':
94 - return refund;
95 - case 'refunded':
96 - return refunded;
97 - case 'confirmation':
98 - return confirmation;
99 - case 'confirmed':
100 - return confirmed;
101 - case 'exchanging':
102 - return exchanging;
103 - case 'sending':
104 - return sending;
105 - case 'success':
106 - return success;
80 default:
81 throw Exception('Unexpected token: $raw in TradeState deserialize');
82 }
lib/nano/cw_nano.dart
+14 -4
@@ -178,6 +178,11 @@ class CWNano extends Nano {
178 BigInt getTransactionAmountRaw(TransactionInfo transactionInfo) {
179 return (transactionInfo as NanoTransactionInfo).amountRaw;
180 }
181 +
182 + @override
183 + String getRepresentative(Object wallet) {
184 + return (wallet as NanoWallet).representative;
185 + }
186 }
187
188 class CWNanoUtil extends NanoUtil {
@@ -308,14 +313,19 @@ class CWNanoUtil extends NanoUtil {
313 /// @param raw 100000000000000000000000000000
314 /// @return Decimal value 1.000000000000000000000000000000
315 ///
311 - @override
312 - Decimal getRawAsDecimal(String? raw, BigInt? rawPerCur) {
316 + Decimal _getRawAsDecimal(String? raw, BigInt? rawPerCur) {
317 rawPerCur ??= rawPerNano;
318 final Decimal amount = Decimal.parse(raw.toString());
319 final Decimal result = (amount / Decimal.parse(rawPerCur.toString())).toDecimal();
320 return result;
321 }
322
323 + @override
324 + String getRawAsDecimalString(String? raw, BigInt? rawPerCur) {
325 + final Decimal result = _getRawAsDecimal(raw, rawPerCur);
326 + return result.toString();
327 + }
328 +
329 @override
330 String truncateDecimal(Decimal input, {int digits = maxDecimalDigits}) {
331 Decimal bigger = input.shift(digits);
@@ -332,7 +342,7 @@ class CWNanoUtil extends NanoUtil {
342 @override
343 String getRawAsUsableString(String? raw, BigInt rawPerCur) {
344 final String res =
335 - truncateDecimal(getRawAsDecimal(raw, rawPerCur), digits: maxDecimalDigits + 9);
345 + truncateDecimal(_getRawAsDecimal(raw, rawPerCur), digits: maxDecimalDigits + 9);
346
347 if (raw == null || raw == "0" || raw == "00000000000000000000000000000000") {
348 return "0";
@@ -361,7 +371,7 @@ class CWNanoUtil extends NanoUtil {
371 @override
372 String getRawAccuracy(String? raw, BigInt rawPerCur) {
373 final String rawString = getRawAsUsableString(raw, rawPerCur);
364 - final String rawDecimalString = getRawAsDecimal(raw, rawPerCur).toString();
374 + final String rawDecimalString = _getRawAsDecimal(raw, rawPerCur).toString();
375
376 if (raw == null || raw.isEmpty || raw == "0") {
377 return "";
lib/src/screens/dashboard/widgets/trade_row.dart
-3
@@ -94,9 +94,6 @@ class TradeRow extends StatelessWidget {
94 borderRadius: BorderRadius.circular(50),
95 child: Image.asset('assets/images/trocador.png', width: 36, height: 36));
96 break;
97 - case ExchangeProviderDescription.exolix:
98 - image = Image.asset('assets/images/exolix.png', width: 36, height: 36);
99 - break;
97 default:
98 image = null;
99 }
lib/src/screens/nano/nano_change_rep_page.dart
+1 -2
@@ -6,7 +6,6 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
6 import 'package:cake_wallet/utils/show_pop_up.dart';
7 import 'package:cw_core/crypto_currency.dart';
8 import 'package:cw_core/wallet_base.dart';
9 -import 'package:cw_nano/nano_wallet.dart';
9 import 'package:flutter/material.dart';
10 import 'package:flutter_mobx/flutter_mobx.dart';
11 import 'package:cake_wallet/generated/i18n.dart';
@@ -18,7 +17,7 @@ class NanoChangeRepPage extends BasePage {
17 NanoChangeRepPage(WalletBase wallet)
18 : _wallet = wallet,
19 _addressController = TextEditingController() {
21 - _addressController.text = (wallet as NanoWallet).representative;
20 + _addressController.text = nano!.getRepresentative(wallet);
21 }
22
23 final TextEditingController _addressController;
lib/src/screens/settings/connection_sync_page.dart
+1 -1
@@ -85,7 +85,7 @@ class ConnectionSyncPage extends BasePage {
85 );
86 },
87 ),
88 - if (dashboardViewModel.wallet.type == WalletType.ethereum) ...[
88 + if (dashboardViewModel.wallet.type == WalletType.ethereum && DeviceInfo.instance.isMobile) ...[
89 WalletConnectTile(
90 onTap: () async {
91 Navigator.of(context).push(
lib/store/app_store.dart
+7
@@ -1,5 +1,8 @@
1 +import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart';
2 +import 'package:cake_wallet/di.dart';
3 import 'package:cake_wallet/utils/exception_handler.dart';
4 import 'package:cw_core/transaction_info.dart';
5 +import 'package:cw_core/wallet_type.dart';
6 import 'package:mobx/mobx.dart';
7 import 'package:cw_core/balance.dart';
8 import 'package:cw_core/wallet_base.dart';
@@ -40,5 +43,9 @@ abstract class AppStoreBase with Store {
43 this.wallet?.close();
44 this.wallet = wallet;
45 this.wallet!.setExceptionHandler(ExceptionHandler.onError);
46 +
47 + if (wallet.type == WalletType.ethereum) {
48 + getIt.get<Web3WalletService>().init();
49 + }
50 }
51 }
lib/store/dashboard/trade_filter_store.dart
+4 -14
@@ -13,8 +13,7 @@ abstract class TradeFilterStoreBase with Store {
13 displaySideShift = true,
14 displayMorphToken = true,
15 displaySimpleSwap = true,
16 - displayTrocador = true,
17 - displayExolix = true;
16 + displayTrocador = true;
17
18 @observable
19 bool displayXMRTO;
@@ -34,11 +33,8 @@ abstract class TradeFilterStoreBase with Store {
33 @observable
34 bool displayTrocador;
35
37 - @observable
38 - bool displayExolix;
39 -
36 @computed
41 - bool get displayAllTrades => displayChangeNow && displaySideShift && displaySimpleSwap && displayTrocador && displayExolix;
37 + bool get displayAllTrades => displayChangeNow && displaySideShift && displaySimpleSwap && displayTrocador;
38
39 @action
40 void toggleDisplayExchange(ExchangeProviderDescription provider) {
@@ -60,10 +56,7 @@ abstract class TradeFilterStoreBase with Store {
56 break;
57 case ExchangeProviderDescription.trocador:
58 displayTrocador = !displayTrocador;
63 - break;
64 - case ExchangeProviderDescription.exolix:
65 - displayExolix = !displayExolix;
66 - break;
59 + break;
60 case ExchangeProviderDescription.all:
61 if (displayAllTrades) {
62 displayChangeNow = false;
@@ -72,7 +65,6 @@ abstract class TradeFilterStoreBase with Store {
65 displayMorphToken = false;
66 displaySimpleSwap = false;
67 displayTrocador = false;
75 - displayExolix = false;
68 } else {
69 displayChangeNow = true;
70 displaySideShift = true;
@@ -80,7 +72,6 @@ abstract class TradeFilterStoreBase with Store {
72 displayMorphToken = true;
73 displaySimpleSwap = true;
74 displayTrocador = true;
83 - displayExolix = true;
75 }
76 break;
77 }
@@ -107,8 +98,7 @@ abstract class TradeFilterStoreBase with Store {
98 ||(displaySimpleSwap &&
99 item.trade.provider ==
100 ExchangeProviderDescription.simpleSwap)
110 - ||(displayTrocador && item.trade.provider == ExchangeProviderDescription.trocador)
111 - ||(displayExolix && item.trade.provider == ExchangeProviderDescription.exolix))
101 + ||(displayTrocador && item.trade.provider == ExchangeProviderDescription.trocador))
102 .toList()
103 : _trades;
104 }
lib/view_model/dashboard/dashboard_view_model.dart
-5
@@ -98,11 +98,6 @@ abstract class DashboardViewModelBase with Store {
98 caption: ExchangeProviderDescription.trocador.title,
99 onChanged: () => tradeFilterStore
100 .toggleDisplayExchange(ExchangeProviderDescription.trocador)),
101 - FilterItem(
102 - value: () => tradeFilterStore.displayExolix,
103 - caption: ExchangeProviderDescription.exolix.title,
104 - onChanged: () => tradeFilterStore
105 - .toggleDisplayExchange(ExchangeProviderDescription.exolix)),
101 ]
102 },
103 subname = '',
lib/view_model/dashboard/transaction_list_item.dart
+2 -3
@@ -92,9 +92,8 @@ class TransactionListItem extends ActionListItem with Keyable {
92 break;
93 case WalletType.nano:
94 amount = calculateFiatAmountRaw(
95 - cryptoAmount: nanoUtil!
96 - .getRawAsDecimal(nano!.getTransactionAmountRaw(transaction).toString(), nanoUtil!.rawPerNano)
97 - .toDouble(),
95 + cryptoAmount: double.parse(nanoUtil!.getRawAsDecimalString(
96 + nano!.getTransactionAmountRaw(transaction).toString(), nanoUtil!.rawPerNano)),
97 price: price);
98 break;
99 case WalletType.ethereum:
lib/view_model/exchange/exchange_trade_view_model.dart
-4
@@ -1,5 +1,4 @@
1 import 'dart:async';
2 -import 'package:cake_wallet/exchange/exolix/exolix_exchange_provider.dart';
2 import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart';
3 import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart';
4 import 'package:cake_wallet/exchange/trocador/trocador_exchange_provider.dart';
@@ -54,9 +53,6 @@ abstract class ExchangeTradeViewModelBase with Store {
53 case ExchangeProviderDescription.trocador:
54 _provider = TrocadorExchangeProvider();
55 break;
57 - case ExchangeProviderDescription.exolix:
58 - _provider = ExolixExchangeProvider();
59 - break;
56 }
57
58 _updateItems();
lib/view_model/exchange/exchange_view_model.dart
-14
@@ -6,8 +6,6 @@ import 'package:cake_wallet/core/wallet_change_listener_view_model.dart';
6 import 'package:cake_wallet/entities/exchange_api_mode.dart';
7 import 'package:cake_wallet/entities/preferences_key.dart';
8 import 'package:cake_wallet/entities/wallet_contact.dart';
9 -import 'package:cake_wallet/exchange/exolix/exolix_exchange_provider.dart';
10 -import 'package:cake_wallet/exchange/exolix/exolix_request.dart';
9 import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart';
10 import 'package:cake_wallet/exchange/sideshift/sideshift_request.dart';
11 import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart';
@@ -152,7 +150,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
150 SideShiftExchangeProvider(),
151 SimpleSwapExchangeProvider(),
152 TrocadorExchangeProvider(useTorOnly: _useTorOnly),
155 - ExolixExchangeProvider(),
153 ];
154
155 @observable
@@ -549,17 +546,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
546 amount = isFixedRateMode ? receiveAmount : depositAmount;
547 }
548
552 - if (provider is ExolixExchangeProvider) {
553 - request = ExolixRequest(
554 - from: depositCurrency,
555 - to: receiveCurrency,
556 - fromAmount: depositAmount.replaceAll(',', '.'),
557 - toAmount: receiveAmount.replaceAll(',', '.'),
558 - refundAddress: depositAddress,
559 - address: receiveAddress);
560 - amount = isFixedRateMode ? receiveAmount : depositAmount;
561 - }
562 -
549 amount = amount.replaceAll(',', '.');
550
551 if (limitsState is LimitsLoadedSuccessfully) {
lib/view_model/send/send_view_model.dart
+9 -3
@@ -278,7 +278,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
278 List<bool> conditionsList = [];
279
280 for (var output in outputs) {
281 - final show = checkThroughChecksToDisplayTOTP(output.address);
281 +
282 + final show = checkThroughChecksToDisplayTOTP(output.extractedAddress);
283 conditionsList.add(show);
284 }
285
@@ -427,9 +428,14 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
428 }
429 }
430
430 - String translateErrorMessage(String error, WalletType walletType, CryptoCurrency currency,) {
431 + String translateErrorMessage(
432 + String error,
433 + WalletType walletType,
434 + CryptoCurrency currency,
435 + ) {
436 if (walletType == WalletType.ethereum || walletType == WalletType.haven) {
432 - if (error.contains('gas required exceeds allowance') || error.contains('insufficient funds for')) {
437 + if (error.contains('gas required exceeds allowance') ||
438 + error.contains('insufficient funds for')) {
439 return S.current.do_not_have_enough_gas_asset(currency.toString());
440 }
441 }
lib/view_model/set_up_2fa_viewmodel.dart
+69 -100
@@ -201,38 +201,15 @@ abstract class Setup2FAViewModelBase with Store {
201 @observable
202 ObservableList<VerboseControlSettings> selected2FASettings;
203
204 - //! The code here works, but can be improved
205 - //! Still trying out various ways to improve it
206 - @action
207 - void selectCakePreset(Cake2FAPresetsOptions cake2FAPreset) {
208 - // The tabs are ordered in the format [Narrow || Normal || Verbose]
209 - // Where Narrow = 0, Normal = 1 and Verbose = 2
210 - switch (cake2FAPreset) {
211 - case Cake2FAPresetsOptions.narrow:
212 - activateCake2FANarrowPreset();
213 - break;
214 - case Cake2FAPresetsOptions.normal:
215 - activateCake2FANormalPreset();
216 - break;
217 - case Cake2FAPresetsOptions.aggressive:
218 - activateCake2FAAggressivePreset();
219 - break;
220 - default:
221 - activateCake2FANormalPreset();
222 - }
223 - }
224 -
204 @action
205 void checkIfTheCurrentSettingMatchesAnyOfThePresets() {
206 final hasNormalPreset = checkIfTheNormalPresetIsPresent();
207 final hasNarrowPreset = checkIfTheNarrowPresetIsPresent();
208 final hasVerbosePreset = checkIfTheVerbosePresetIsPresent();
209
231 - if (hasNormalPreset || hasNarrowPreset || hasVerbosePreset) {
232 - unhighlightTabs = false;
233 - } else {
234 - unhighlightTabs = true;
235 - }
210 + if (hasNormalPreset || hasNarrowPreset || hasVerbosePreset) return;
211 +
212 + noCake2FAPresetSelected();
213 }
214
215 @action
@@ -288,32 +265,8 @@ abstract class Setup2FAViewModelBase with Store {
265 }
266
267 @action
291 - void activateCake2FANormalPreset() {
292 - _settingsStore.selectedCake2FAPreset = Cake2FAPresetsOptions.normal;
293 - setAllControlsToFalse();
294 - switchShouldRequireTOTP2FAForSendsToNonContact(true);
295 - switchShouldRequireTOTP2FAForSendsToContact(true);
296 - switchShouldRequireTOTP2FAForSendsToInternalWallets(true);
297 - switchShouldRequireTOTP2FAForExchangesToInternalWallets(true);
298 - switchShouldRequireTOTP2FAForAllSecurityAndBackupSettings(true);
299 - }
300 -
301 - @action
302 - void activateCake2FANarrowPreset() {
303 - _settingsStore.selectedCake2FAPreset = Cake2FAPresetsOptions.narrow;
304 - setAllControlsToFalse();
305 - switchShouldRequireTOTP2FAForSendsToNonContact(true);
306 - switchShouldRequireTOTP2FAForAddingContacts(true);
307 - switchShouldRequireTOTP2FAForCreatingNewWallet(true);
308 - switchShouldRequireTOTP2FAForAllSecurityAndBackupSettings(true);
309 - }
310 -
311 - @action
312 - void activateCake2FAAggressivePreset() {
313 - _settingsStore.selectedCake2FAPreset = Cake2FAPresetsOptions.aggressive;
314 - setAllControlsToFalse();
315 - switchShouldRequireTOTP2FAForAccessingWallet(true);
316 - switchShouldRequireTOTP2FAForAllSecurityAndBackupSettings(true);
268 + void noCake2FAPresetSelected() {
269 + _settingsStore.selectedCake2FAPreset = Cake2FAPresetsOptions.none;
270 }
271
272 @action
@@ -330,90 +283,106 @@ abstract class Setup2FAViewModelBase with Store {
283 unhighlightTabs = false;
284 }
285
286 + final Map<Cake2FAPresetsOptions, List<VerboseControlSettings>> presetsMap = {
287 + Cake2FAPresetsOptions.normal: [
288 + VerboseControlSettings.sendsToContacts,
289 + VerboseControlSettings.sendsToNonContacts,
290 + VerboseControlSettings.sendsToInternalWallets,
291 + VerboseControlSettings.securityAndBackupSettings,
292 + VerboseControlSettings.exchangesToInternalWallets
293 + ],
294 + Cake2FAPresetsOptions.narrow: [
295 + VerboseControlSettings.addingContacts,
296 + VerboseControlSettings.sendsToNonContacts,
297 + VerboseControlSettings.creatingNewWallets,
298 + VerboseControlSettings.securityAndBackupSettings,
299 + ],
300 + Cake2FAPresetsOptions.aggressive: [
301 + VerboseControlSettings.accessWallet,
302 + VerboseControlSettings.securityAndBackupSettings,
303 + ],
304 + Cake2FAPresetsOptions.none: [],
305 + };
306 +
307 + @action
308 + void selectCakePreset(Cake2FAPresetsOptions preset) {
309 + presetsMap[preset]?.forEach(toggleControl);
310 + _settingsStore.selectedCake2FAPreset = preset;
311 + }
312 +
313 @action
334 - void switchShouldRequireTOTP2FAForAccessingWallet(bool value) {
335 - _settingsStore.shouldRequireTOTP2FAForAccessingWallet = value;
336 - if (value) {
337 - selected2FASettings.add(VerboseControlSettings.accessWallet);
338 - } else {
339 - selected2FASettings.remove(VerboseControlSettings.accessWallet);
340 - }
341 - checkIfTheCurrentSettingMatchesAnyOfThePresets();
314 + void toggleControl(VerboseControlSettings control, [bool value = true]) {
315 + final methodsMap = {
316 + VerboseControlSettings.sendsToContacts: switchShouldRequireTOTP2FAForSendsToContact,
317 + VerboseControlSettings.accessWallet: switchShouldRequireTOTP2FAForAccessingWallet,
318 + VerboseControlSettings.addingContacts: switchShouldRequireTOTP2FAForAddingContacts,
319 + VerboseControlSettings.creatingNewWallets: switchShouldRequireTOTP2FAForCreatingNewWallet,
320 + VerboseControlSettings.sendsToNonContacts: switchShouldRequireTOTP2FAForSendsToNonContact,
321 + VerboseControlSettings.sendsToInternalWallets:
322 + switchShouldRequireTOTP2FAForSendsToInternalWallets,
323 + VerboseControlSettings.securityAndBackupSettings:
324 + switchShouldRequireTOTP2FAForAllSecurityAndBackupSettings,
325 + VerboseControlSettings.exchangesToInternalWallets:
326 + switchShouldRequireTOTP2FAForExchangesToInternalWallets,
327 + };
328 +
329 + methodsMap[control]?.call(value);
330 }
331
332 @action
333 void switchShouldRequireTOTP2FAForSendsToContact(bool value) {
334 _settingsStore.shouldRequireTOTP2FAForSendsToContact = value;
347 - if (value) {
348 - selected2FASettings.add(VerboseControlSettings.sendsToContacts);
349 - } else {
350 - selected2FASettings.remove(VerboseControlSettings.sendsToContacts);
351 - }
352 - checkIfTheCurrentSettingMatchesAnyOfThePresets();
335 + updateSelectedSettings(VerboseControlSettings.sendsToContacts, value);
336 + }
337 +
338 + @action
339 + void switchShouldRequireTOTP2FAForAccessingWallet(bool value) {
340 + _settingsStore.shouldRequireTOTP2FAForAccessingWallet = value;
341 + updateSelectedSettings(VerboseControlSettings.accessWallet, value);
342 }
343
344 @action
345 void switchShouldRequireTOTP2FAForSendsToNonContact(bool value) {
346 _settingsStore.shouldRequireTOTP2FAForSendsToNonContact = value;
358 - if (value) {
359 - selected2FASettings.add(VerboseControlSettings.sendsToNonContacts);
360 - } else {
361 - selected2FASettings.remove(VerboseControlSettings.sendsToNonContacts);
362 - }
363 - checkIfTheCurrentSettingMatchesAnyOfThePresets();
347 + updateSelectedSettings(VerboseControlSettings.sendsToNonContacts, value);
348 }
349
350 @action
351 void switchShouldRequireTOTP2FAForSendsToInternalWallets(bool value) {
352 _settingsStore.shouldRequireTOTP2FAForSendsToInternalWallets = value;
369 - if (value) {
370 - selected2FASettings.add(VerboseControlSettings.sendsToInternalWallets);
371 - } else {
372 - selected2FASettings.remove(VerboseControlSettings.sendsToInternalWallets);
373 - }
374 - checkIfTheCurrentSettingMatchesAnyOfThePresets();
353 + updateSelectedSettings(VerboseControlSettings.sendsToInternalWallets, value);
354 }
355
356 @action
357 void switchShouldRequireTOTP2FAForExchangesToInternalWallets(bool value) {
358 _settingsStore.shouldRequireTOTP2FAForExchangesToInternalWallets = value;
380 - if (value) {
381 - selected2FASettings.add(VerboseControlSettings.exchangesToInternalWallets);
382 - } else {
383 - selected2FASettings.remove(VerboseControlSettings.exchangesToInternalWallets);
384 - }
385 - checkIfTheCurrentSettingMatchesAnyOfThePresets();
359 + updateSelectedSettings(VerboseControlSettings.exchangesToInternalWallets, value);
360 }
361
362 @action
363 void switchShouldRequireTOTP2FAForAddingContacts(bool value) {
364 _settingsStore.shouldRequireTOTP2FAForAddingContacts = value;
391 - if (value)
392 - selected2FASettings.add(VerboseControlSettings.addingContacts);
393 - else {
394 - selected2FASettings.remove(VerboseControlSettings.addingContacts);
395 - }
396 - checkIfTheCurrentSettingMatchesAnyOfThePresets();
365 + updateSelectedSettings(VerboseControlSettings.addingContacts, value);
366 }
367
368 @action
369 void switchShouldRequireTOTP2FAForCreatingNewWallet(bool value) {
370 _settingsStore.shouldRequireTOTP2FAForCreatingNewWallets = value;
402 - if (value) {
403 - selected2FASettings.add(VerboseControlSettings.creatingNewWallets);
404 - } else {
405 - selected2FASettings.remove(VerboseControlSettings.creatingNewWallets);
406 - }
407 - checkIfTheCurrentSettingMatchesAnyOfThePresets();
371 + updateSelectedSettings(VerboseControlSettings.creatingNewWallets, value);
372 }
373
374 @action
375 void switchShouldRequireTOTP2FAForAllSecurityAndBackupSettings(bool value) {
376 _settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings = value;
413 - if (value)
414 - selected2FASettings.add(VerboseControlSettings.securityAndBackupSettings);
415 - else {
416 - selected2FASettings.remove(VerboseControlSettings.securityAndBackupSettings);
377 + updateSelectedSettings(VerboseControlSettings.securityAndBackupSettings, value);
378 + }
379 +
380 + @action
381 + void updateSelectedSettings(VerboseControlSettings control, bool value) {
382 + if (value) {
383 + selected2FASettings.add(control);
384 + } else {
385 + selected2FASettings.remove(control);
386 }
387 checkIfTheCurrentSettingMatchesAnyOfThePresets();
388 }
lib/view_model/support_view_model.dart
-5
@@ -53,11 +53,6 @@ abstract class SupportViewModelBase with Store {
53 icon: 'assets/images/simpleSwap.png',
54 linkTitle: 'support@simpleswap.io',
55 link: 'mailto:support@simpleswap.io'),
56 - LinkListItem(
57 - title: 'Exolix',
58 - icon: 'assets/images/exolix.png',
59 - linkTitle: 'support@exolix.com',
60 - link: 'mailto:support@exolix.com'),
56 if (!isMoneroOnly) ... [
57 LinkListItem(
58 title: 'Wyre',
lib/view_model/trade_details_view_model.dart
-10
@@ -2,7 +2,6 @@ import 'dart:async';
2 import 'package:cake_wallet/exchange/changenow/changenow_exchange_provider.dart';
3 import 'package:cake_wallet/exchange/exchange_provider.dart';
4 import 'package:cake_wallet/exchange/exchange_provider_description.dart';
5 -import 'package:cake_wallet/exchange/exolix/exolix_exchange_provider.dart';
5 import 'package:cake_wallet/exchange/morphtoken/morphtoken_exchange_provider.dart';
6 import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart';
7 import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart';
@@ -55,9 +54,6 @@ abstract class TradeDetailsViewModelBase with Store {
54 case ExchangeProviderDescription.trocador:
55 _provider = TrocadorExchangeProvider();
56 break;
58 - case ExchangeProviderDescription.exolix:
59 - _provider = ExolixExchangeProvider();
60 - break;
57 }
58
59 _updateItems();
@@ -161,12 +157,6 @@ abstract class TradeDetailsViewModelBase with Store {
157 items.add(StandartListItem(
158 title: '${trade.providerName} ${S.current.password}', value: trade.password ?? ''));
159 }
164 -
165 - if (trade.provider == ExchangeProviderDescription.exolix) {
166 - final buildURL = 'https://exolix.com/transaction/${trade.id.toString()}';
167 - items.add(
168 - TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => _launchUrl(buildURL)));
169 - }
160 }
161
162 void _launchUrl(String url) {
scripts/android/app_env.sh
+4 -4
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
15 APP_ANDROID_TYPE=$1
16
17 MONERO_COM_NAME="Monero.com"
18 -MONERO_COM_VERSION="1.6.2"
19 -MONERO_COM_BUILD_NUMBER=58
18 +MONERO_COM_VERSION="1.7.0"
19 +MONERO_COM_BUILD_NUMBER=61
20 MONERO_COM_BUNDLE_ID="com.monero.app"
21 MONERO_COM_PACKAGE="com.monero.app"
22 MONERO_COM_SCHEME="monero.com"
23
24 CAKEWALLET_NAME="Cake Wallet"
25 -CAKEWALLET_VERSION="4.9.2"
26 -CAKEWALLET_BUILD_NUMBER=171
25 +CAKEWALLET_VERSION="4.10.0"
26 +CAKEWALLET_BUILD_NUMBER=175
27 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
28 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
29 CAKEWALLET_SCHEME="cakewallet"
scripts/ios/app_env.sh
+4 -4
@@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
13 APP_IOS_TYPE=$1
14
15 MONERO_COM_NAME="Monero.com"
16 -MONERO_COM_VERSION="1.6.2"
17 -MONERO_COM_BUILD_NUMBER=56
16 +MONERO_COM_VERSION="1.7.0"
17 +MONERO_COM_BUILD_NUMBER=59
18 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
19
20 CAKEWALLET_NAME="Cake Wallet"
21 -CAKEWALLET_VERSION="4.9.2"
22 -CAKEWALLET_BUILD_NUMBER=185
21 +CAKEWALLET_VERSION="4.10.0"
22 +CAKEWALLET_BUILD_NUMBER=189
23 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
24
25 HAVEN_NAME="Haven"
scripts/macos/app_env.sh
+2 -2
@@ -15,8 +15,8 @@ if [ -n "$1" ]; then
15 fi
16
17 CAKEWALLET_NAME="Cake Wallet"
18 -CAKEWALLET_VERSION="1.2.2"
19 -CAKEWALLET_BUILD_NUMBER=33
18 +CAKEWALLET_VERSION="1.3.0"
19 +CAKEWALLET_BUILD_NUMBER=36
20 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
21
22 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
tool/configure.dart
+3 -3
@@ -639,6 +639,7 @@ abstract class Nano {
639 Future<void> changeRep(Object wallet, String address);
640 Future<void> updateTransactions(Object wallet);
641 BigInt getTransactionAmountRaw(TransactionInfo transactionInfo);
642 + String getRepresentative(Object wallet);
643 }
644
645 abstract class NanoAccountList {
@@ -672,8 +673,7 @@ abstract class NanoUtil {
673 BigInt rawPerBanano = BigInt.parse("100000000000000000000000000000");
674 BigInt rawPerXMR = BigInt.parse("1000000000000");
675 BigInt convertXMRtoNano = BigInt.parse("1000000000000000000");
675 - Decimal getRawAsDecimal(String? raw, BigInt? rawPerCur);
676 - String truncateDecimal(Decimal input, {int digits = maxDecimalDigits});
676 + String getRawAsDecimalString(String? raw, BigInt? rawPerCur);
677 String getRawAsUsableString(String? raw, BigInt rawPerCur);
678 String getRawAccuracy(String? raw, BigInt rawPerCur);
679 String getAmountAsRaw(String amount, BigInt rawPerCur);
@@ -693,7 +693,7 @@ abstract class NanoUtil {
693 }
694 """;
695
696 - const nanoEmptyDefinition = 'Nano? nano;\nNanoUtil? nanoUtil = CWNanoUtil();\n';
696 + const nanoEmptyDefinition = 'Nano? nano;\nNanoUtil? nanoUtil;\n';
697 const nanoCWDefinition = 'Nano? nano = CWNano();\nNanoUtil? nanoUtil = CWNanoUtil();\n';
698
699 final output = '$nanoCommonHeaders\n' +
tool/utils/secret_key.dart
-1
@@ -32,7 +32,6 @@ class SecretKey {
32 SecretKey('fiatApiKey', () => ''),
33 SecretKey('payfuraApiKey', () => ''),
34 SecretKey('chatwootWebsiteToken', () => ''),
35 - SecretKey('exolixApiKey', () => ''),
35 SecretKey('robinhoodApplicationId', () => ''),
36 SecretKey('robinhoodCIdApiSecret', () => ''),
37 SecretKey('walletConnectProjectId', () => ''),