Merge remote-tracking branch 'origin/linux/password-direct-input' into linux/password-direct-input

# Conflicts:
#	cw_bitcoin/lib/electrum_transaction_history.dart
#	lib/main.dart
#	lib/src/screens/dashboard/dashboard_page.dart
#	lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
#	lib/src/screens/dashboard/widgets/balance_page.dart
#	lib/src/screens/dashboard/widgets/market_place_page.dart
#	lib/src/screens/dashboard/widgets/transactions_page.dart
#	lib/src/screens/ionia/cards/ionia_manage_cards_page.dart
#	lib/src/screens/receive/anonpay_invoice_page.dart
#	lib/src/screens/wallet_list/wallet_list_page.dart
#	lib/utils/responsive_layout_util.dart
#	res/values/strings_ar.arb
#	res/values/strings_bg.arb
#	res/values/strings_cs.arb
#	res/values/strings_de.arb
#	res/values/strings_en.arb
#	res/values/strings_es.arb
#	res/values/strings_fr.arb
#	res/values/strings_ha.arb
#	res/values/strings_hi.arb
#	res/values/strings_hr.arb
#	res/values/strings_id.arb
#	res/values/strings_it.arb
#	res/values/strings_ja.arb
#	res/values/strings_ko.arb
#	res/values/strings_my.arb
#	res/values/strings_nl.arb
#	res/values/strings_pl.arb
#	res/values/strings_pt.arb
#	res/values/strings_ru.arb
#	res/values/strings_th.arb
#	res/values/strings_tr.arb
#	res/values/strings_uk.arb
#	res/values/strings_ur.arb
#	res/values/strings_yo.arb
#	res/values/strings_zh.arb
This commit is contained in:
OmarHatem 2023-07-13 18:59:49 +03:00
commit 459a40bcd9
68 changed files with 803 additions and 852 deletions

View file

@ -106,6 +106,7 @@ jobs:
echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart
echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart

View file

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 193 B

View file

@ -1,3 +1,6 @@
Enable iPad/Tablet separate layout from mobile UI Opt-in to Cake 2FA for security. More info: https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa
SideShift update and fixes Auto generate restore height for Monero restore QR codes
Bug Fixes Hausa and Yoruba languages
Additional privacy settings
Update Monero to 0.18.2.2
Refactoring and bug fixes

View file

@ -1,4 +1,6 @@
Enable iPad/Tablet separate layout from mobile UI Opt-in to Cake 2FA for security. More info: https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa
SideShift update and fixes Auto generate restore height for Monero restore QR codes
Add MoonPay sell Hausa and Yoruba languages
Bug Fixes Additional privacy settings
Update Monero to 0.18.2.2
Refactoring and bug fixes

View file

@ -37,6 +37,9 @@ CakeWallet requires some packages to be install on your build system. You may ea
Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux). Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux).
### 3. Verify Installations ### 3. Verify Installations
Verify that the Flutter have been correctly installed on your system with the following command: Verify that the Flutter have been correctly installed on your system with the following command:
@ -46,7 +49,7 @@ Verify that the Flutter have been correctly installed on your system with the fo
The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding.
``` ```
Doctor summary (to see all details, run flutter doctor -v): Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.x.x, on Linux, locale en_US.UTF-8) [✓] Flutter (Channel stable, 3.7.x, on Linux, locale en_US.UTF-8)
``` ```
### 4. Acquiring the CakeWallet Source Code ### 4. Acquiring the CakeWallet Source Code
@ -100,6 +103,38 @@ Install Flutter package dependencies with this command:
> `$ flutter pub get` > `$ flutter pub get`
> ### If you get the error like:
> ```
> The lower bound of "sdk: '>=2.0.0-dev.68.0 <3.0.0'" must be 2.12.0 or higher to enable null safety.
> ```
>
> #### Downgrade Flutter to version 3.7.x
> Make sure that Flutter is reverted back to version 3.7.x (which would automatically revert Dart to 2.18 or 2.19)
>
> In your Linux terminal, find where your Flutter SDK is installed with:
>
> ```
> $ which flutter
> ```
>
> Proceed to the Flutter SDK path:
>
> ```
> $ cd user/snap/flutter/common/flutter
> ```
>
> In the Flutter SDK directory, revert to a 3.7.x version (I used 3.7.12):
>
>
> ```
> $ git checkout 3.7.12
> ```
> Then re-configure Cake Wallet's Linux project again. For this open `scripts/linux` (`$cd scripts/linux`) directory and run:
> `$ ./cakewallet.sh`
> and back to project root directory:
> `$ cd ../..`
> and fetch dependecies again
> `$ flutter pub get`
Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command: Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command:

View file

@ -16,6 +16,7 @@ import 'package:cw_core/pathForWallet.dart';
import 'package:cw_bitcoin/address_to_output_script.dart'; import 'package:cw_bitcoin/address_to_output_script.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/electrum_balance.dart'; import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart'; import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
import 'package:cw_bitcoin/electrum_transaction_history.dart'; import 'package:cw_bitcoin/electrum_transaction_history.dart';
import 'package:cw_bitcoin/bitcoin_transaction_no_inputs_exception.dart'; import 'package:cw_bitcoin/bitcoin_transaction_no_inputs_exception.dart';
@ -128,8 +129,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
Map<String, BehaviorSubject<Object>?> _scripthashesUpdateSubject; Map<String, BehaviorSubject<Object>?> _scripthashesUpdateSubject;
bool _isTransactionUpdating; bool _isTransactionUpdating;
void Function(FlutterErrorDetails)? _onError;
Future<void> init() async { Future<void> init() async {
await walletAddresses.init(); await walletAddresses.init();
await transactionHistory.init(); await transactionHistory.init();
@ -332,7 +331,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
} else { } else {
feeAmount = feeRate(transactionCredentials.priority!) * estimatedSize; feeAmount = feeRate(transactionCredentials.priority!) * estimatedSize;
} }
final changeValue = totalInputAmount - amount - feeAmount; final changeValue = totalInputAmount - amount - feeAmount;
if (changeValue > minAmount) { if (changeValue > minAmount) {
@ -673,13 +672,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
await updateUnspent(); await updateUnspent();
await updateBalance(); await updateBalance();
await updateTransactions(); await updateTransactions();
} catch (e, s) { } catch (e) {
print(e.toString()); print(e.toString());
_onError?.call(FlutterErrorDetails(
exception: e,
stack: s,
library: this.runtimeType.toString(),
));
} }
}); });
}); });
@ -745,7 +739,4 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
return addresses[random.nextInt(addresses.length)].address; return addresses[random.nextInt(addresses.length)].address;
} }
@override
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
} }

View file

@ -75,6 +75,4 @@ abstract class WalletBase<
String get password; String get password;
Future<void>? updateBalance(); Future<void>? updateBalance();
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => null;
} }

View file

@ -44,7 +44,6 @@ post_install do |installer|
flutter_additional_ios_build_settings(target) flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config| target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)', '$(inherited)',

View file

@ -4,10 +4,10 @@ PODS:
- MTBBarcodeScanner - MTBBarcodeScanner
- SwiftProtobuf - SwiftProtobuf
- BigInt (5.2.0) - BigInt (5.2.0)
- connectivity_plus (0.0.1): - connectivity (0.0.1):
- Flutter - Flutter
- ReachabilitySwift - Reachability
- CryptoSwift (1.7.1) - CryptoSwift (1.6.0)
- cw_haven (0.0.1): - cw_haven (0.0.1):
- cw_haven/Boost (= 0.0.1) - cw_haven/Boost (= 0.0.1)
- cw_haven/Haven (= 0.0.1) - cw_haven/Haven (= 0.0.1)
@ -126,20 +126,20 @@ PODS:
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- permission_handler_apple (9.1.0): - permission_handler_apple (9.0.4):
- Flutter - Flutter
- platform_device_id (0.0.1): - platform_device_id (0.0.1):
- Flutter - Flutter
- ReachabilitySwift (5.0.0) - Reachability (3.2)
- SDWebImage (5.16.0): - SDWebImage (5.15.5):
- SDWebImage/Core (= 5.16.0) - SDWebImage/Core (= 5.15.5)
- SDWebImage/Core (5.16.0) - SDWebImage/Core (5.15.5)
- share_plus (0.0.1): - share_plus (0.0.1):
- Flutter - Flutter
- shared_preferences_foundation (0.0.1): - shared_preferences_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- SwiftProtobuf (1.22.0) - SwiftProtobuf (1.21.0)
- SwiftyGif (5.4.4) - SwiftyGif (5.4.4)
- uni_links (0.0.1): - uni_links (0.0.1):
- Flutter - Flutter
@ -153,7 +153,7 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - connectivity (from `.symlinks/plugins/connectivity/ios`)
- CryptoSwift - CryptoSwift
- cw_haven (from `.symlinks/plugins/cw_haven/ios`) - cw_haven (from `.symlinks/plugins/cw_haven/ios`)
- cw_monero (from `.symlinks/plugins/cw_monero/ios`) - cw_monero (from `.symlinks/plugins/cw_monero/ios`)
@ -188,7 +188,7 @@ SPEC REPOS:
- DKPhotoGallery - DKPhotoGallery
- MTBBarcodeScanner - MTBBarcodeScanner
- OrderedSet - OrderedSet
- ReachabilitySwift - Reachability
- SDWebImage - SDWebImage
- SwiftProtobuf - SwiftProtobuf
- SwiftyGif - SwiftyGif
@ -197,8 +197,8 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
barcode_scan2: barcode_scan2:
:path: ".symlinks/plugins/barcode_scan2/ios" :path: ".symlinks/plugins/barcode_scan2/ios"
connectivity_plus: connectivity:
:path: ".symlinks/plugins/connectivity_plus/ios" :path: ".symlinks/plugins/connectivity/ios"
cw_haven: cw_haven:
:path: ".symlinks/plugins/cw_haven/ios" :path: ".symlinks/plugins/cw_haven/ios"
cw_monero: cw_monero:
@ -249,8 +249,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
BigInt: f668a80089607f521586bbe29513d708491ef2f7 BigInt: f668a80089607f521586bbe29513d708491ef2f7
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
CryptoSwift: d3d18dc357932f7e6d580689e065cf1f176007c1 CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6
cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d
cw_shared_external: 2972d872b8917603478117c9957dfca611845a92 cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
@ -271,19 +271,19 @@ SPEC CHECKSUMS:
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
permission_handler_apple: 8f116445eff3c0e7c65ad60f5fef5490aa94b4e4 permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5 platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SDWebImage: 2aea163b50bfcb569a2726b6a754c54a4506fcf6 SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989 SwiftProtobuf: afced68785854575756db965e9da52bbf3dc45e7
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841 UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
PODFILE CHECKSUM: 09df1114e7c360f55770d35a79356bf5446e0100 PODFILE CHECKSUM: ae71bdf0eb731a1ffc399c122f6aa4dea0cb5f6f
COCOAPODS: 1.11.3 COCOAPODS: 1.11.3

View file

@ -10,8 +10,8 @@
0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44A7192518EF8000B570ED /* decrypt.swift */; }; 0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44A7192518EF8000B570ED /* decrypt.swift */; };
0C9D68C9264854B60011B691 /* secRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9D68C8264854B60011B691 /* secRandom.swift */; }; 0C9D68C9264854B60011B691 /* secRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9D68C8264854B60011B691 /* secRandom.swift */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
20ED0868E1BD7E12278C0CB3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C663361C56EBB242598F609 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
@ -23,13 +23,13 @@
0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = "<group>"; }; 0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = "<group>"; };
0C9986A3251A932F00D566FD /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0C9986A3251A932F00D566FD /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0C9D68C8264854B60011B691 /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secRandom.swift; sourceTree = "<group>"; }; 0C9D68C8264854B60011B691 /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secRandom.swift; sourceTree = "<group>"; };
11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 20F67A1B2C2FCB2A3BB048C1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3C663361C56EBB242598F609 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 501EA9286675DC8636978EA4 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
5AFFEBFC279AD49C00F906A4 /* wakeLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = wakeLock.swift; sourceTree = "<group>"; }; 5AFFEBFC279AD49C00F906A4 /* wakeLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = wakeLock.swift; sourceTree = "<group>"; };
61CAA8652B54F23356F7592A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@ -40,7 +40,7 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -48,7 +48,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */, 20ED0868E1BD7E12278C0CB3 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -59,7 +59,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0C9986A3251A932F00D566FD /* CryptoSwift.framework */, 0C9986A3251A932F00D566FD /* CryptoSwift.framework */,
3C663361C56EBB242598F609 /* Pods_Runner.framework */, B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -77,9 +77,9 @@
84389F1A05D5860790D82820 /* Pods */ = { 84389F1A05D5860790D82820 /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */, 20F67A1B2C2FCB2A3BB048C1 /* Pods-Runner.debug.xcconfig */,
1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */, 501EA9286675DC8636978EA4 /* Pods-Runner.release.xcconfig */,
AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */, 61CAA8652B54F23356F7592A /* Pods-Runner.profile.xcconfig */,
); );
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
@ -138,13 +138,13 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */, 0843B0813AFBAF53935AD24E /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */, DD8DB3179CA4E511F9954A6F /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -203,21 +203,26 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */ = { 0843B0813AFBAF53935AD24E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
); );
name = "[CP] Embed Pods Frameworks"; inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", );
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
@ -250,26 +255,21 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
}; };
B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */ = { DD8DB3179CA4E511F9954A6F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
); );
inputPaths = ( name = "[CP] Embed Pods Frameworks";
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = ( outputFileListPaths = (
); "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
@ -390,7 +390,7 @@
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64; VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
@ -537,7 +537,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64; VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
@ -574,7 +574,7 @@
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64; VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };

View file

@ -1,25 +1,21 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "Icon-App-40x40@1x.png",
"idiom" : "iphone", "idiom" : "iphone",
"scale" : "2x", "scale" : "2x",
"size" : "20x20" "size" : "20x20"
}, },
{ {
"filename" : "Icon-App-20x20@3x.png",
"idiom" : "iphone", "idiom" : "iphone",
"scale" : "3x", "scale" : "3x",
"size" : "20x20" "size" : "20x20"
}, },
{ {
"filename" : "Icon-App-29x29@2x 1.png",
"idiom" : "iphone", "idiom" : "iphone",
"scale" : "2x", "scale" : "2x",
"size" : "29x29" "size" : "29x29"
}, },
{ {
"filename" : "Icon-App-29x29@3x.png",
"idiom" : "iphone", "idiom" : "iphone",
"scale" : "3x", "scale" : "3x",
"size" : "29x29" "size" : "29x29"
@ -30,7 +26,6 @@
"size" : "40x40" "size" : "40x40"
}, },
{ {
"filename" : "Icon-App-40x40@3x.png",
"idiom" : "iphone", "idiom" : "iphone",
"scale" : "3x", "scale" : "3x",
"size" : "40x40" "size" : "40x40"
@ -48,31 +43,26 @@
"size" : "60x60" "size" : "60x60"
}, },
{ {
"filename" : "Icon-App-20x20@1x.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "1x", "scale" : "1x",
"size" : "20x20" "size" : "20x20"
}, },
{ {
"filename" : "Icon-App-20x20@2x.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "2x", "scale" : "2x",
"size" : "20x20" "size" : "20x20"
}, },
{ {
"filename" : "Icon-App-29x29@1x.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "1x", "scale" : "1x",
"size" : "29x29" "size" : "29x29"
}, },
{ {
"filename" : "Icon-App-29x29@2x.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "2x", "scale" : "2x",
"size" : "29x29" "size" : "29x29"
}, },
{ {
"filename" : "Icon-App-40x40@1x 1.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "1x", "scale" : "1x",
"size" : "40x40" "size" : "40x40"
@ -83,19 +73,16 @@
"size" : "40x40" "size" : "40x40"
}, },
{ {
"filename" : "Icon-App-76x76@1x.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "1x", "scale" : "1x",
"size" : "76x76" "size" : "76x76"
}, },
{ {
"filename" : "Icon-App-76x76@2x.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "2x", "scale" : "2x",
"size" : "76x76" "size" : "76x76"
}, },
{ {
"filename" : "Icon-App-83.5x83.5@2x.png",
"idiom" : "ipad", "idiom" : "ipad",
"scale" : "2x", "scale" : "2x",
"size" : "83.5x83.5" "size" : "83.5x83.5"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View file

@ -1,7 +1,4 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:cake_wallet/buy/buy_exception.dart'; import 'package:cake_wallet/buy/buy_exception.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
@ -19,42 +16,20 @@ class MoonPaySellProvider {
MoonPaySellProvider({this.isTest = false}) MoonPaySellProvider({this.isTest = false})
: baseUrl = isTest ? _baseTestUrl : _baseProductUrl; : baseUrl = isTest ? _baseTestUrl : _baseProductUrl;
static const _baseTestUrl = 'sell-sandbox.moonpay.com'; static const _baseTestUrl = 'sell-staging.moonpay.com';
static const _baseProductUrl = 'sell.moonpay.com'; static const _baseProductUrl = 'sell.moonpay.com';
static String themeToMoonPayTheme(ThemeBase theme) {
switch (theme.type) {
case ThemeType.bright:
return 'light';
case ThemeType.light:
return 'light';
case ThemeType.dark:
return 'dark';
}
}
static String get _apiKey => secrets.moonPayApiKey; static String get _apiKey => secrets.moonPayApiKey;
static String get _secretKey => secrets.moonPaySecretKey; static String get _secretKey => secrets.moonPaySecretKey;
final bool isTest; final bool isTest;
final String baseUrl; final String baseUrl;
Future<Uri> requestUrl( Future<Uri> requestUrl({required CryptoCurrency currency, required String refundWalletAddress}) async {
{required CryptoCurrency currency,
required String refundWalletAddress,
required SettingsStore settingsStore}) async {
final customParams = {
'theme': themeToMoonPayTheme(settingsStore.currentTheme),
'language': settingsStore.languageCode,
'colorCode': settingsStore.currentTheme.type == ThemeType.dark
? '#${Palette.blueCraiola.value.toRadixString(16).substring(2, 8)}'
: '#${Palette.moderateSlateBlue.value.toRadixString(16).substring(2, 8)}',
};
final originalUri = Uri.https( final originalUri = Uri.https(
baseUrl, '', <String, dynamic>{ baseUrl, '', <String, dynamic>{
'apiKey': _apiKey, 'apiKey': _apiKey,
'defaultBaseCurrencyCode': currency.toString().toLowerCase(), 'defaultBaseCurrencyCode': currency.toString().toLowerCase(),
'refundWalletAddress': refundWalletAddress 'refundWalletAddress': refundWalletAddress
}..addAll(customParams)); });
final messageBytes = utf8.encode('?${originalUri.query}'); final messageBytes = utf8.encode('?${originalUri.query}');
final key = utf8.encode(_secretKey); final key = utf8.encode(_secretKey);
final hmac = Hmac(sha256, key); final hmac = Hmac(sha256, key);

View file

@ -18,9 +18,10 @@ import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_tip.dart'; import 'package:cake_wallet/ionia/ionia_tip.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart'; import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
import 'package:cake_wallet/src/screens/buy/payfura_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
@ -48,11 +49,9 @@ import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart'; import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart'; import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart'; import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
@ -264,7 +263,7 @@ Future setup({
nodeSource: _nodeSource, nodeSource: _nodeSource,
isBitcoinBuyEnabled: isBitcoinBuyEnabled, isBitcoinBuyEnabled: isBitcoinBuyEnabled,
// Enforce darkTheme on platforms other than mobile till the design for other themes is completed // Enforce darkTheme on platforms other than mobile till the design for other themes is completed
initialTheme: ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme, initialTheme: DeviceInfo.instance.isMobile ? null : ThemeList.darkTheme,
); );
if (_isSetupFinished) { if (_isSetupFinished) {
@ -710,13 +709,15 @@ Future setup({
wallet: getIt.get<AppStore>().wallet!, wallet: getIt.get<AppStore>().wallet!,
)); ));
getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri)); getIt.registerFactory(() => OnRamperPage(getIt.get<OnRamperBuyProvider>()));
getIt.registerFactory<PayfuraBuyProvider>(() => PayfuraBuyProvider( getIt.registerFactory<PayfuraBuyProvider>(() => PayfuraBuyProvider(
settingsStore: getIt.get<AppStore>().settingsStore, settingsStore: getIt.get<AppStore>().settingsStore,
wallet: getIt.get<AppStore>().wallet!, wallet: getIt.get<AppStore>().wallet!,
)); ));
getIt.registerFactory(() => PayFuraPage(getIt.get<PayfuraBuyProvider>()));
getIt.registerFactory(() => ExchangeViewModel( getIt.registerFactory(() => ExchangeViewModel(
getIt.get<AppStore>().wallet!, getIt.get<AppStore>().wallet!,
_tradesSource, _tradesSource,
@ -913,8 +914,6 @@ Future setup({
getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get<IoniaService>())); getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get<IoniaService>()));
getIt.registerFactory(()=> MarketPlaceViewModel(getIt.get<IoniaService>()));
getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get<IoniaService>())); getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get<IoniaService>()));
getIt.registerFactoryParam<IoniaMerchPurchaseViewModel, double, IoniaMerchant>( getIt.registerFactoryParam<IoniaMerchPurchaseViewModel, double, IoniaMerchant>(
@ -944,7 +943,7 @@ Future setup({
return IoniaVerifyIoniaOtp(getIt.get<IoniaAuthViewModel>(), email, isSignIn); return IoniaVerifyIoniaOtp(getIt.get<IoniaAuthViewModel>(), email, isSignIn);
}); });
getIt.registerFactory(() => IoniaWelcomePage()); getIt.registerFactory(() => IoniaWelcomePage(getIt.get<IoniaGiftCardsListViewModel>()));
getIt.registerFactoryParam<IoniaBuyGiftCardPage, List, void>((List args, _) { getIt.registerFactoryParam<IoniaBuyGiftCardPage, List, void>((List args, _) {
final merchant = args.first as IoniaMerchant; final merchant = args.first as IoniaMerchant;

View file

@ -55,11 +55,11 @@ class LanguageService {
'cs': 'czk', 'cs': 'czk',
'ur': 'pak', 'ur': 'pak',
'id': 'idn', 'id': 'idn',
'yo': 'nga', 'yo': 'yor',
'ha': 'hau' 'ha': 'hau'
}; };
static final list = <String, String>{}; static final list = <String, String> {};
static void loadLocaleList() { static void loadLocaleList() {
supportedLocales.forEach((key, value) { supportedLocales.forEach((key, value) {

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -47,20 +48,22 @@ class MainActions {
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
if (viewModel.isEnabledBuyAction) { if (viewModel.isEnabledBuyAction) {
final uri = getIt.get<OnRamperBuyProvider>().requestUrl();
if (DeviceInfo.instance.isMobile) { if (DeviceInfo.instance.isMobile) {
Navigator.of(context) Navigator.of(context).pushNamed(Routes.onramperPage);
.pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]);
} else { } else {
final uri = getIt.get<OnRamperBuyProvider>().requestUrl();
await launchUrl(uri); await launchUrl(uri);
} }
} }
break; break;
case WalletType.monero: case WalletType.monero:
if (viewModel.isEnabledBuyAction) { if (viewModel.isEnabledBuyAction) {
// final uri = getIt.get<PayfuraBuyProvider>().requestUrl(); if (DeviceInfo.instance.isMobile) {
final uri = Uri.parse("https://monero.com/trade"); Navigator.of(context).pushNamed(Routes.payfuraPage);
await launchUrl(uri); } else {
final uri = getIt.get<PayfuraBuyProvider>().requestUrl();
await launchUrl(uri);
}
} }
break; break;
default: default:
@ -115,22 +118,14 @@ class MainActions {
switch (walletType) { switch (walletType) {
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin:
if (viewModel.isEnabledSellAction) { if (viewModel.isEnabledSellAction) {
final moonPaySellProvider = MoonPaySellProvider(); final moonPaySellProvider = MoonPaySellProvider();
final uri = await moonPaySellProvider.requestUrl( final uri = await moonPaySellProvider.requestUrl(
currency: viewModel.wallet.currency, currency: viewModel.wallet.currency,
refundWalletAddress: viewModel.wallet.walletAddresses.address, refundWalletAddress: viewModel.wallet.walletAddresses.address,
settingsStore: viewModel.settingsStore,
); );
if (DeviceInfo.instance.isMobile) { await launchUrl(uri);
Navigator.of(context).pushNamed(Routes.webViewPage,
arguments: [S.of(context).sell, uri]);
} else {
await launchUrl(uri);
}
} }
break; break;
default: default:
await showPopUp<void>( await showPopUp<void>(

View file

@ -204,11 +204,11 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final expectedSendAmount = responseJSON['expectedAmountFrom'].toString(); final expectedSendAmount = responseJSON['expectedAmountFrom'].toString();
final status = responseJSON['status'] as String; final status = responseJSON['status'] as String;
final state = TradeState.deserialize(raw: status); final state = TradeState.deserialize(raw: status);
final extraId = responseJSON['payinExtraId'] as String?; final extraId = responseJSON['payinExtraId'] as String;
final outputTransaction = responseJSON['payoutHash'] as String?; final outputTransaction = responseJSON['payoutHash'] as String;
final expiredAtRaw = responseJSON['validUntil'] as String?; final expiredAtRaw = responseJSON['validUntil'] as String;
final payoutAddress = responseJSON['payoutAddress'] as String; final payoutAddress = responseJSON['payoutAddress'] as String;
final expiredAt = DateTime.tryParse(expiredAtRaw ?? '')?.toLocal(); final expiredAt = DateTime.tryParse(expiredAtRaw)?.toLocal();
return Trade( return Trade(
id: id, id: id,

View file

@ -19,10 +19,10 @@ class SideShiftExchangeProvider extends ExchangeProvider {
static const affiliateId = secrets.sideShiftAffiliateId; static const affiliateId = secrets.sideShiftAffiliateId;
static const apiBaseUrl = 'https://sideshift.ai/api'; static const apiBaseUrl = 'https://sideshift.ai/api';
static const rangePath = '/v2/pair'; static const rangePath = '/v1/pairs';
static const orderPath = '/v2/shifts'; static const orderPath = '/v1/orders';
static const quotePath = '/v2/quotes'; static const quotePath = '/v1/quotes';
static const permissionPath = '/v2/permissions'; static const permissionPath = '/v1/permissions';
static const List<CryptoCurrency> _notSupported = [ static const List<CryptoCurrency> _notSupported = [
CryptoCurrency.xhv, CryptoCurrency.xhv,
@ -36,22 +36,23 @@ class SideShiftExchangeProvider extends ExchangeProvider {
CryptoCurrency.scrt, CryptoCurrency.scrt,
CryptoCurrency.stx, CryptoCurrency.stx,
CryptoCurrency.bttc, CryptoCurrency.bttc,
CryptoCurrency.usdt,
CryptoCurrency.eos,
]; ];
static List<ExchangePair> _supportedPairs() { static List<ExchangePair> _supportedPairs() {
final supportedCurrencies = final supportedCurrencies = CryptoCurrency.all
CryptoCurrency.all.where((element) => !_notSupported.contains(element)).toList(); .where((element) => !_notSupported.contains(element))
.toList();
return supportedCurrencies return supportedCurrencies
.map((i) => supportedCurrencies.map((k) => ExchangePair(from: i, to: k, reverse: true))) .map((i) => supportedCurrencies
.map((k) => ExchangePair(from: i, to: k, reverse: true)))
.expand((i) => i) .expand((i) => i)
.toList(); .toList();
} }
@override @override
ExchangeProviderDescription get description => ExchangeProviderDescription.sideShift; ExchangeProviderDescription get description =>
ExchangeProviderDescription.sideShift;
@override @override
Future<double> fetchRate( Future<double> fetchRate(
@ -64,18 +65,17 @@ class SideShiftExchangeProvider extends ExchangeProvider {
if (amount == 0) { if (amount == 0) {
return 0.0; return 0.0;
} }
final fromCurrency = _normalizeCryptoCurrency(from);
final fromCurrency = from.title.toLowerCase(); final toCurrency = _normalizeCryptoCurrency(to);
final toCurrency = to.title.toLowerCase(); final url =
final depositNetwork = _networkFor(from); apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
final settleNetwork = _networkFor(to);
final url = "$apiBaseUrl$rangePath/$fromCurrency-$depositNetwork/$toCurrency-$settleNetwork";
final uri = Uri.parse(url); final uri = Uri.parse(url);
final response = await get(uri); final response = await get(uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final rate = double.parse(responseJSON['rate'] as String); final rate = double.parse(responseJSON['rate'] as String);
final max = double.parse(responseJSON['max'] as String);
if (amount > max) return 0.00;
return rate; return rate;
} catch (_) { } catch (_) {
@ -101,38 +101,25 @@ class SideShiftExchangeProvider extends ExchangeProvider {
} }
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final cancreateShift = responseJSON['createShift'] as bool; final canCreateOrder = responseJSON['createOrder'] as bool;
return cancreateShift; final canCreateQuote = responseJSON['createQuote'] as bool;
return canCreateOrder && canCreateQuote;
} }
@override @override
Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async { Future<Trade> createTrade(
{required TradeRequest request, required bool isFixedRateMode}) async {
final _request = request as SideShiftRequest; final _request = request as SideShiftRequest;
String url = ''; final quoteId = await _createQuote(_request);
final depositCoin = request.depositMethod.title.toLowerCase(); final url = apiBaseUrl + orderPath;
final settleCoin = request.settleMethod.title.toLowerCase(); final headers = {'Content-Type': 'application/json'};
final body = { final body = {
'type': 'fixed',
'quoteId': quoteId,
'affiliateId': affiliateId, 'affiliateId': affiliateId,
'settleAddress': _request.settleAddress, 'settleAddress': _request.settleAddress,
'refundAddress': _request.refundAddress, 'refundAddress': _request.refundAddress
}; };
if (isFixedRateMode) {
final quoteId = await _createQuote(_request);
body['quoteId'] = quoteId;
url = apiBaseUrl + orderPath + '/fixed';
} else {
url = apiBaseUrl + orderPath + '/variable';
final depositNetwork = _networkFor(request.depositMethod);
final settleNetwork = _networkFor(request.settleMethod);
body["depositCoin"] = depositCoin;
body["settleCoin"] = settleCoin;
body["settleNetwork"] = settleNetwork;
body["depositNetwork"] = depositNetwork;
}
final headers = {'Content-Type': 'application/json'};
final uri = Uri.parse(url); final uri = Uri.parse(url);
final response = await post(uri, headers: headers, body: json.encode(body)); final response = await post(uri, headers: headers, body: json.encode(body));
@ -149,9 +136,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final id = responseJSON['id'] as String; final id = responseJSON['id'] as String;
final inputAddress = responseJSON['depositAddress'] as String; final inputAddress = responseJSON['depositAddress']['address'] as String;
final settleAddress = responseJSON['settleAddress'] as String; final settleAddress = responseJSON['settleAddress']['address'] as String;
final depositAmount = responseJSON['depositAmount'] as String?;
return Trade( return Trade(
id: id, id: id,
@ -161,7 +147,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
inputAddress: inputAddress, inputAddress: inputAddress,
refundAddress: settleAddress, refundAddress: settleAddress,
state: TradeState.created, state: TradeState.created,
amount: depositAmount ?? _request.depositAmount, amount: _request.depositAmount,
payoutAddress: settleAddress, payoutAddress: settleAddress,
createdAt: DateTime.now(), createdAt: DateTime.now(),
); );
@ -170,17 +156,13 @@ class SideShiftExchangeProvider extends ExchangeProvider {
Future<String> _createQuote(SideShiftRequest request) async { Future<String> _createQuote(SideShiftRequest request) async {
final url = apiBaseUrl + quotePath; final url = apiBaseUrl + quotePath;
final headers = {'Content-Type': 'application/json'}; final headers = {'Content-Type': 'application/json'};
final depositMethod = request.depositMethod.title.toLowerCase(); final depositMethod = _normalizeCryptoCurrency(request.depositMethod);
final settleMethod = request.settleMethod.title.toLowerCase(); final settleMethod = _normalizeCryptoCurrency(request.settleMethod);
final depositNetwork = _networkFor(request.depositMethod);
final settleNetwork = _networkFor(request.settleMethod);
final body = { final body = {
'depositCoin': depositMethod, 'depositMethod': depositMethod,
'settleCoin': settleMethod, 'settleMethod': settleMethod,
'affiliateId': affiliateId, 'affiliateId': affiliateId,
'settleAmount': request.depositAmount, 'depositAmount': request.depositAmount,
'settleNetwork': settleNetwork,
'depositNetwork': depositNetwork,
}; };
final uri = Uri.parse(url); final uri = Uri.parse(url);
final response = await post(uri, headers: headers, body: json.encode(body)); final response = await post(uri, headers: headers, body: json.encode(body));
@ -207,15 +189,9 @@ class SideShiftExchangeProvider extends ExchangeProvider {
{required CryptoCurrency from, {required CryptoCurrency from,
required CryptoCurrency to, required CryptoCurrency to,
required bool isFixedRateMode}) async { required bool isFixedRateMode}) async {
final fromCurrency = isFixedRateMode ? to : from; final fromCurrency = _normalizeCryptoCurrency(from);
final toCurrency = isFixedRateMode ? from : to; final toCurrency = _normalizeCryptoCurrency(to);
final url = apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
final fromNetwork = _networkFor(fromCurrency);
final toNetwork = _networkFor(toCurrency);
final url =
"$apiBaseUrl$rangePath/${fromCurrency.title.toLowerCase()}-$fromNetwork/${toCurrency.title.toLowerCase()}-$toNetwork";
final uri = Uri.parse(url); final uri = Uri.parse(url);
final response = await get(uri); final response = await get(uri);
@ -234,14 +210,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final min = double.tryParse(responseJSON['min'] as String? ?? ''); final min = double.tryParse(responseJSON['min'] as String? ?? '');
final max = double.tryParse(responseJSON['max'] as String? ?? ''); final max = double.tryParse(responseJSON['max'] as String? ?? '');
if (isFixedRateMode) {
final currentRate = double.parse(responseJSON['rate'] as String);
return Limits(
min: min != null ? (min * currentRate) : null,
max: max != null ? (max * currentRate) : null,
);
}
return Limits(min: min, max: max); return Limits(min: min, max: max);
} }
@ -259,7 +227,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final error = responseJSON['error']['message'] as String; final error = responseJSON['error']['message'] as String;
throw TradeNotFoundException(id, provider: description, description: error); throw TradeNotFoundException(id,
provider: description, description: error);
} }
if (response.statusCode != 200) { if (response.statusCode != 200) {
@ -267,32 +236,36 @@ class SideShiftExchangeProvider extends ExchangeProvider {
} }
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final fromCurrency = responseJSON['depositCoin'] as String; final fromCurrency = responseJSON['depositMethodId'] as String;
final from = CryptoCurrency.fromString(fromCurrency); final from = CryptoCurrency.fromString(fromCurrency);
final toCurrency = responseJSON['settleCoin'] as String; final toCurrency = responseJSON['settleMethodId'] as String;
final to = CryptoCurrency.fromString(toCurrency); final to = CryptoCurrency.fromString(toCurrency);
final inputAddress = responseJSON['depositAddress'] as String; final inputAddress = responseJSON['depositAddress']['address'] as String;
final expectedSendAmount = responseJSON['depositAmount'] as String?; final expectedSendAmount = responseJSON['depositAmount'].toString();
final status = responseJSON['status'] as String?; final deposits = responseJSON['deposits'] as List?;
final settleAddress = responseJSON['settleAddress'] as String; final settleAddress = responseJSON['settleAddress']['address'] as String;
TradeState? state; TradeState? state;
String? status;
if (deposits?.isNotEmpty ?? false) {
status = deposits![0]['status'] as String?;
}
state = TradeState.deserialize(raw: status ?? 'created'); state = TradeState.deserialize(raw: status ?? 'created');
final isVariable = (responseJSON['type'] as String) == 'variable';
final expiredAtRaw = responseJSON['expiresAt'] as String; final expiredAtRaw = responseJSON['expiresAtISO'] as String;
final expiredAt = isVariable ? null : DateTime.tryParse(expiredAtRaw)?.toLocal(); final expiredAt = DateTime.tryParse(expiredAtRaw)?.toLocal();
return Trade( return Trade(
id: id, id: id,
from: from, from: from,
to: to, to: to,
provider: description, provider: description,
inputAddress: inputAddress, inputAddress: inputAddress,
amount: expectedSendAmount ?? '', amount: expectedSendAmount,
state: state, state: state,
expiredAt: expiredAt, expiredAt: expiredAt,
payoutAddress: settleAddress); payoutAddress: settleAddress
);
} }
@override @override
@ -307,25 +280,28 @@ class SideShiftExchangeProvider extends ExchangeProvider {
@override @override
String get title => 'SideShift'; String get title => 'SideShift';
String _networkFor(CryptoCurrency currency) => static String _normalizeCryptoCurrency(CryptoCurrency currency) {
currency.tag != null ? _normalizeTag(currency.tag!) : 'mainnet'; switch (currency) {
case CryptoCurrency.zaddr:
String _normalizeTag(String tag) { return 'zaddr';
switch (tag) { case CryptoCurrency.zec:
case 'ETH': return 'zec';
return 'ethereum'; case CryptoCurrency.bnb:
case 'TRX': return currency.tag!.toLowerCase();
return 'tron'; case CryptoCurrency.usdterc20:
case 'LN': return 'usdtErc20';
return 'lightning'; case CryptoCurrency.usdttrc20:
case 'POLY': return 'usdtTrc20';
case CryptoCurrency.usdcpoly:
return 'usdcpolygon';
case CryptoCurrency.usdcsol:
return 'usdcsol';
case CryptoCurrency.maticpoly:
return 'polygon'; return 'polygon';
case 'ZEC': case CryptoCurrency.btcln:
return 'zcash'; return 'ln';
case 'AVAXC':
return 'avax';
default: default:
return tag.toLowerCase(); return currency.title.toLowerCase();
} }
} }
} }

View file

@ -1,9 +1,10 @@
import 'dart:async'; import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/sync_status.dart'; import 'package:cw_core/sync_status.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:connectivity/connectivity.dart';
Timer? _checkConnectionTimer; Timer? _checkConnectionTimer;
void startCheckConnectionReaction( void startCheckConnectionReaction(

View file

@ -8,7 +8,8 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar
import 'package:cake_wallet/src/screens/backup/backup_page.dart'; import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart'; import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
import 'package:cake_wallet/src/screens/buy/payfura_page.dart';
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart'; import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart'; import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart'; import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
@ -191,6 +192,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
fullscreenDialog: true); fullscreenDialog: true);
} else if (isSingleCoin) { } else if (isSingleCoin) {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<WalletRestorePage>( builder: (_) => getIt.get<WalletRestorePage>(
param1: availableWalletTypes.first param1: availableWalletTypes.first
)); ));
@ -211,6 +213,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.restoreWallet: case Routes.restoreWallet:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<WalletRestorePage>( builder: (_) => getIt.get<WalletRestorePage>(
param1: settings.arguments as WalletType)); param1: settings.arguments as WalletType));
@ -220,7 +223,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.dashboard: case Routes.dashboard:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
settings: settings,
builder: (_) => getIt.get<DashboardPage>()); builder: (_) => getIt.get<DashboardPage>());
case Routes.send: case Routes.send:
@ -512,8 +514,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaCreateAccountPage>()); return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaCreateAccountPage>());
case Routes.ioniaManageCardsPage: case Routes.ioniaManageCardsPage:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaManageCardsPage>());
builder: (_) => getIt.get<IoniaManageCardsPage>());
case Routes.ioniaBuyGiftCardPage: case Routes.ioniaBuyGiftCardPage:
final args = settings.arguments as List; final args = settings.arguments as List;
@ -563,13 +564,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: paymentInfo, param1: paymentInfo,
param2: commitedInfo)); param2: commitedInfo));
case Routes.webViewPage: case Routes.onramperPage:
final args = settings.arguments as List; return CupertinoPageRoute<void>(builder: (_) => getIt.get<OnRamperPage>());
final title = args.first as String;
final url = args[1] as Uri; case Routes.payfuraPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<WebViewPage>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<PayFuraPage>());
param1: title,
param2: url));
case Routes.advancedPrivacySettings: case Routes.advancedPrivacySettings:
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;
@ -583,6 +582,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.anonPayInvoicePage: case Routes.anonPayInvoicePage:
final args = settings.arguments as List; final args = settings.arguments as List;
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<AnonPayInvoicePage>(param1: args)); builder: (_) => getIt.get<AnonPayInvoicePage>(param1: args));
case Routes.anonPayReceivePage: case Routes.anonPayReceivePage:

View file

@ -71,7 +71,7 @@ class Routes {
static const ioniaPaymentStatusPage = '/ionia_payment_status_page'; static const ioniaPaymentStatusPage = '/ionia_payment_status_page';
static const ioniaMoreOptionsPage = '/ionia_more_options_page'; static const ioniaMoreOptionsPage = '/ionia_more_options_page';
static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page'; static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page';
static const webViewPage = '/web_view_page'; static const onramperPage = '/onramper';
static const connectionSync = '/connection_sync_page'; static const connectionSync = '/connection_sync_page';
static const securityBackupPage = '/security_and_backup_page'; static const securityBackupPage = '/security_and_backup_page';
static const privacyPage = '/privacy_page'; static const privacyPage = '/privacy_page';
@ -84,6 +84,7 @@ class Routes {
static const anonPayInvoicePage = '/anon_pay_invoice_page'; static const anonPayInvoicePage = '/anon_pay_invoice_page';
static const anonPayReceivePage = '/anon_pay_receive_page'; static const anonPayReceivePage = '/anon_pay_receive_page';
static const anonPayDetailsPage = '/anon_pay_details_page'; static const anonPayDetailsPage = '/anon_pay_details_page';
static const payfuraPage = '/pay_fura_page';
static const desktop_actions = '/desktop_actions'; static const desktop_actions = '/desktop_actions';
static const transactionsPage = '/transactions_page'; static const transactionsPage = '/transactions_page';
static const setup_2faPage = '/setup_2fa_page'; static const setup_2faPage = '/setup_2fa_page';

View file

@ -5,32 +5,33 @@ import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
class WebViewPage extends BasePage { class OnRamperPage extends BasePage {
WebViewPage(this._title, this._url); OnRamperPage(this._onRamperBuyProvider);
final String _title; final OnRamperBuyProvider _onRamperBuyProvider;
final Uri _url;
@override @override
String get title => _title; String get title => S.current.buy;
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
return WebViewPageBody(_url); return OnRamperPageBody(_onRamperBuyProvider);
} }
} }
class WebViewPageBody extends StatefulWidget { class OnRamperPageBody extends StatefulWidget {
WebViewPageBody(this.uri); OnRamperPageBody(this.onRamperBuyProvider);
final Uri uri; final OnRamperBuyProvider onRamperBuyProvider;
Uri get uri => onRamperBuyProvider.requestUrl();
@override @override
WebViewPageBodyState createState() => WebViewPageBodyState(); OnRamperPageBodyState createState() => OnRamperPageBodyState();
} }
class WebViewPageBodyState extends State<WebViewPageBody> { class OnRamperPageBodyState extends State<OnRamperPageBody> {
WebViewPageBodyState(); OnRamperPageBodyState();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -0,0 +1,58 @@
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';
class PayFuraPage extends BasePage {
PayFuraPage(this._PayfuraBuyProvider);
final PayfuraBuyProvider _PayfuraBuyProvider;
@override
String get title => S.current.buy;
@override
Widget body(BuildContext context) {
return PayFuraPageBody(_PayfuraBuyProvider);
}
}
class PayFuraPageBody extends StatefulWidget {
PayFuraPageBody(this._PayfuraBuyProvider);
final PayfuraBuyProvider _PayfuraBuyProvider;
Uri get uri => _PayfuraBuyProvider.requestUrl();
@override
PayFuraPageBodyState createState() => PayFuraPageBodyState();
}
class PayFuraPageBodyState extends State<PayFuraPageBody> {
PayFuraPageBodyState();
@override
Widget build(BuildContext context) {
return InAppWebView(
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(transparentBackground: true),
),
initialUrlRequest: URLRequest(url: widget.uri),
androidOnPermissionRequest: (_, __, resources) async {
bool permissionGranted = await Permission.camera.status == PermissionStatus.granted;
if (!permissionGranted) {
permissionGranted = await Permission.camera.request().isGranted;
}
return PermissionRequestResponse(
resources: resources,
action: permissionGranted
? PermissionRequestResponseAction.GRANT
: PermissionRequestResponseAction.DENY,
);
},
);
}
}

View file

@ -21,54 +21,57 @@ class DesktopActionButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return MouseRegion(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), cursor: SystemMouseCursors.click,
child: GestureDetector( child: Padding(
onTap: onTap, padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
child: Container( child: GestureDetector(
padding: EdgeInsets.symmetric(vertical: 25), onTap: onTap,
width: double.infinity, child: Container(
decoration: BoxDecoration( padding: EdgeInsets.symmetric(vertical: 25),
borderRadius: BorderRadius.circular(15.0), width: double.infinity,
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!, decoration: BoxDecoration(
), borderRadius: BorderRadius.circular(15.0),
child: Center( color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!,
child: Row( ),
mainAxisSize: MainAxisSize.min, child: Center(
children: [ child: Row(
Image.asset( mainAxisSize: MainAxisSize.min,
image, children: [
height: 30, Image.asset(
width: 30, image,
color: isEnabled height: 30,
? Theme.of(context) width: 30,
.accentTextTheme!
.displayMedium!
.backgroundColor!
: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!,
),
const SizedBox(width: 10),
AutoSizeText(
title,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
color: isEnabled color: isEnabled
? Theme.of(context) ? Theme.of(context)
.accentTextTheme! .accentTextTheme!
.displayMedium! .displayMedium!
.backgroundColor! .backgroundColor!
: null, : Theme.of(context)
height: 1, .accentTextTheme!
.displaySmall!
.backgroundColor!,
), ),
maxLines: 1, const SizedBox(width: 10),
textAlign: TextAlign.center, AutoSizeText(
) title,
], style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
color: isEnabled
? Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!
: null,
height: 1,
),
maxLines: 1,
textAlign: TextAlign.center,
)
],
),
), ),
), ),
), ),

View file

@ -73,7 +73,7 @@ class AddressPage extends BasePage {
? closeButtonImageDarkTheme ? closeButtonImageDarkTheme
: closeButtonImage; : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile; bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics( return MergeSemantics(
child: SizedBox( child: SizedBox(
@ -275,7 +275,7 @@ class AddressPage extends BasePage {
reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) { reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) {
switch (option) { switch (option) {
case ReceivePageOption.anonPayInvoice: case ReceivePageOption.anonPayInvoice:
Navigator.pushNamed( Navigator.pushReplacementNamed(
context, context,
Routes.anonPayInvoicePage, Routes.anonPayInvoicePage,
arguments: [addressListViewModel.address.address, option], arguments: [addressListViewModel.address.address, option],
@ -287,7 +287,7 @@ class AddressPage extends BasePage {
final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink); final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink);
if (clearnetUrl != null && onionUrl != null) { if (clearnetUrl != null && onionUrl != null) {
Navigator.pushNamed( Navigator.pushReplacementNamed(
context, context,
Routes.anonPayReceivePage, Routes.anonPayReceivePage,
arguments: AnonpayDonationLinkInfo( arguments: AnonpayDonationLinkInfo(
@ -297,7 +297,7 @@ class AddressPage extends BasePage {
), ),
); );
} else { } else {
Navigator.pushNamed( Navigator.pushReplacementNamed(
context, context,
Routes.anonPayInvoicePage, Routes.anonPayInvoicePage,
arguments: [addressListViewModel.address.address, option], arguments: [addressListViewModel.address.address, option],

View file

@ -60,110 +60,96 @@ class TransactionsPage extends StatelessWidget {
Expanded(child: Observer(builder: (_) { Expanded(child: Observer(builder: (_) {
final items = dashboardViewModel.items; final items = dashboardViewModel.items;
return items.isNotEmpty return items.isNotEmpty
? ListView.builder( ? ListView.builder(
itemCount: items.length, itemCount: items.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = items[index]; final item = items[index];
if (item is DateSectionItem) { if (item is DateSectionItem) {
return DateSectionRaw(date: item.date); return DateSectionRaw(date: item.date);
} }
if (item is TransactionListItem) { if (item is TransactionListItem) {
final transaction = item.transaction; final transaction = item.transaction;
return Observer( return Observer(
builder: (_) => TransactionRow( builder: (_) => TransactionRow(
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context)
Routes.transactionDetails, .pushNamed(Routes.transactionDetails, arguments: transaction),
arguments: transaction), direction: transaction.direction,
direction: transaction.direction, formattedDate: DateFormat('HH:mm').format(transaction.date),
formattedDate: DateFormat('HH:mm') formattedAmount: item.formattedCryptoAmount,
.format(transaction.date), formattedFiatAmount:
formattedAmount: item.formattedCryptoAmount, dashboardViewModel.balanceViewModel.isFiatDisabled
formattedFiatAmount: dashboardViewModel ? ''
.balanceViewModel.isFiatDisabled : item.formattedFiatAmount,
? '' isPending: transaction.isPending,
: item.formattedFiatAmount, title: item.formattedTitle + item.formattedStatus));
isPending: transaction.isPending, }
title: item.formattedTitle +
item.formattedStatus));
}
if (item is AnonpayTransactionListItem) { if (item is AnonpayTransactionListItem) {
final transactionInfo = item.transaction; final transactionInfo = item.transaction;
return AnonpayTransactionRow( return AnonpayTransactionRow(
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context)
Routes.anonPayDetailsPage, .pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
arguments: transactionInfo), currency: transactionInfo.fiatAmount != null
currency: transactionInfo.fiatAmount != null ? transactionInfo.fiatEquiv ?? ''
? transactionInfo.fiatEquiv ?? '' : CryptoCurrency.fromFullName(transactionInfo.coinTo)
: CryptoCurrency.fromFullName( .name
transactionInfo.coinTo) .toUpperCase(),
.name provider: transactionInfo.provider,
.toUpperCase(), amount: transactionInfo.fiatAmount?.toString() ??
provider: transactionInfo.provider, (transactionInfo.amountTo?.toString() ?? ''),
amount: transactionInfo.fiatAmount?.toString() ?? createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
(transactionInfo.amountTo?.toString() ?? ''), );
createdAt: DateFormat('HH:mm') }
.format(transactionInfo.createdAt),
);
}
if (item is TradeListItem) { if (item is TradeListItem) {
final trade = item.trade; final trade = item.trade;
return Observer( return Observer(
builder: (_) => TradeRow( builder: (_) => TradeRow(
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context)
Routes.tradeDetails, .pushNamed(Routes.tradeDetails, arguments: trade),
arguments: trade), provider: trade.provider,
provider: trade.provider, from: trade.from,
from: trade.from, to: trade.to,
to: trade.to, createdAtFormattedDate: trade.createdAt != null
? DateFormat('HH:mm').format(trade.createdAt!)
: null,
formattedAmount: item.tradeFormattedAmount));
}
if (item is OrderListItem) {
final order = item.order;
return Observer(
builder: (_) => OrderRow(
onTap: () => Navigator.of(context)
.pushNamed(Routes.orderDetails, arguments: order),
provider: order.provider,
from: order.from!,
to: order.to!,
createdAtFormattedDate: createdAtFormattedDate:
trade.createdAt != null DateFormat('HH:mm').format(order.createdAt),
? DateFormat('HH:mm') formattedAmount: item.orderFormattedAmount,
.format(trade.createdAt!) ));
: null, }
formattedAmount: item.tradeFormattedAmount));
}
if (item is OrderListItem) { return Container(color: Colors.transparent, height: 1);
final order = item.order; })
: Center(
return Observer( child: Text(
builder: (_) => OrderRow( S.of(context).placeholder_transactions,
onTap: () => Navigator.of(context) style: TextStyle(
.pushNamed(Routes.orderDetails, fontSize: 14,
arguments: order), color: Theme.of(context).primaryTextTheme!.labelSmall!.decorationColor!),
provider: order.provider, ),
from: order.from!, );
to: order.to!, }))
createdAtFormattedDate: DateFormat('HH:mm') ],
.format(order.createdAt),
formattedAmount: item.orderFormattedAmount,
));
}
return Container(color: Colors.transparent, height: 1);
})
: Center(
child: Text(
S.of(context).placeholder_transactions,
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.primaryTextTheme
.labelSmall!
.decorationColor!),
),
);
}))
],
),
), ),
); );
} }

View file

@ -117,7 +117,7 @@ class ExchangePage extends BasePage {
final _closeButton = currentTheme.type == ThemeType.dark final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme : closeButtonImage; ? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile; bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics( return MergeSemantics(
child: SizedBox( child: SizedBox(
@ -601,8 +601,8 @@ class ExchangePage extends BasePage {
alertContent: S.of(context).low_fee_alert, alertContent: S.of(context).low_fee_alert,
leftButtonText: S.of(context).ignor, leftButtonText: S.of(context).ignor,
rightButtonText: S.of(context).use_suggested, rightButtonText: S.of(context).use_suggested,
actionLeftButton: () => Navigator.of(dialogContext).pop(false), actionLeftButton: () => Navigator.of(context).pop(false),
actionRightButton: () => Navigator.of(dialogContext).pop(true)); actionRightButton: () => Navigator.of(context).pop(true));
}) ?? false; }) ?? false;
if (confirmed) { if (confirmed) {
exchangeViewModel.setDefaultTransactionPriority(); exchangeViewModel.setDefaultTransactionPriority();
@ -733,7 +733,7 @@ class ExchangePage extends BasePage {
}, },
)); ));
if (ResponsiveLayoutUtil.instance.isMobile) { if (ResponsiveLayoutUtil.instance.isMobile(context)) {
return MobileExchangeCardsSection( return MobileExchangeCardsSection(
firstExchangeCard: firstExchangeCard, firstExchangeCard: firstExchangeCard,
secondExchangeCard: secondExchangeCard, secondExchangeCard: secondExchangeCard,

View file

@ -3,11 +3,14 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:mobx/mobx.dart';
class IoniaWelcomePage extends BasePage { class IoniaWelcomePage extends BasePage {
IoniaWelcomePage(); IoniaWelcomePage(this._cardsListViewModel);
@override @override
Widget middle(BuildContext context) { Widget middle(BuildContext context) {
@ -22,8 +25,15 @@ class IoniaWelcomePage extends BasePage {
); );
} }
final IoniaGiftCardsListViewModel _cardsListViewModel;
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
reaction((_) => _cardsListViewModel.isLoggedIn, (bool state) {
if (state) {
Navigator.pushReplacementNamed(context, Routes.ioniaManageCardsPage);
}
});
return Padding( return Padding(
padding: const EdgeInsets.all(24.0), padding: const EdgeInsets.all(24.0),
child: Column( child: Column(
@ -31,7 +41,7 @@ class IoniaWelcomePage extends BasePage {
children: [ children: [
Column( Column(
children: [ children: [
SizedBox(height: 90), SizedBox(height: 100),
Text( Text(
S.of(context).about_cake_pay, S.of(context).about_cake_pay,
style: TextStyle( style: TextStyle(

View file

@ -1,5 +1,4 @@
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/currency.dart'; import 'package:cw_core/currency.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -10,8 +9,7 @@ class CurrencyInputField extends StatelessWidget {
required this.onTapPicker, required this.onTapPicker,
required this.selectedCurrency, required this.selectedCurrency,
this.focusNode, this.focusNode,
required this.controller, required this.controller, required this.isLight,
required this.isLight,
}); });
final Function() onTapPicker; final Function() onTapPicker;
@ -24,12 +22,13 @@ class CurrencyInputField extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final arrowBottomPurple = Image.asset( final arrowBottomPurple = Image.asset(
'assets/images/arrow_bottom_purple_icon.png', 'assets/images/arrow_bottom_purple_icon.png',
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!, color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 8, height: 8,
); );
// This magic number for wider screen sets the text input focus at center of the inputfield final _width = MediaQuery.of(context).size.width;
final _width =
ResponsiveLayoutUtil.instance.isMobile ? MediaQuery.of(context).size.width : 500;
return Column( return Column(
children: [ children: [
@ -43,12 +42,10 @@ class CurrencyInputField extends StatelessWidget {
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true), keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))], inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))],
hintText: '0.000', hintText: '0.000',
placeholderTextStyle: isLight placeholderTextStyle: isLight ? null : TextStyle(
? null color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!,
: TextStyle( fontWeight: FontWeight.w600,
color: Theme.of(context).primaryTextTheme!.headlineSmall!.color!, ),
fontWeight: FontWeight.w600,
),
borderColor: Theme.of(context).accentTextTheme!.titleLarge!.backgroundColor!, borderColor: Theme.of(context).accentTextTheme!.titleLarge!.backgroundColor!,
textColor: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!, textColor: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
textStyle: TextStyle( textStyle: TextStyle(
@ -75,10 +72,7 @@ class CurrencyInputField extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 16, fontSize: 16,
color: Theme.of(context) color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
.accentTextTheme!
.displayMedium!
.backgroundColor!,
), ),
), ),
if (selectedCurrency.tag != null) if (selectedCurrency.tag != null)
@ -113,10 +107,8 @@ class CurrencyInputField extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 20, fontSize: 20,
color: Theme.of(context) color:
.accentTextTheme! Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
.displayMedium!
.backgroundColor!,
), ),
), ),
), ),

View file

@ -274,8 +274,6 @@ class WalletRestorePage extends BasePage {
} }
void _confirmForm() { void _confirmForm() {
// Dismissing all visible keyboard to provide context for navigation
FocusManager.instance.primaryFocus?.unfocus();
final formContext = walletRestoreViewModel.mode == WalletRestoreMode.seed final formContext = walletRestoreViewModel.mode == WalletRestoreMode.seed
? walletRestoreFromSeedFormKey.currentContext ? walletRestoreFromSeedFormKey.currentContext
: walletRestoreFromKeysFormKey.currentContext; : walletRestoreFromKeysFormKey.currentContext;

View file

@ -62,7 +62,7 @@ class SendPage extends BasePage {
final _closeButton = currentTheme.type == ThemeType.dark final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme : closeButtonImage; ? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile; bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics( return MergeSemantics(
child: SizedBox( child: SizedBox(
@ -94,7 +94,7 @@ class SendPage extends BasePage {
double _sendCardHeight(BuildContext context) { double _sendCardHeight(BuildContext context) {
final double initialHeight = sendViewModel.isElectrumWallet ? 490 : 465; final double initialHeight = sendViewModel.isElectrumWallet ? 490 : 465;
if (!ResponsiveLayoutUtil.instance.isMobile) { if (!ResponsiveLayoutUtil.instance.isMobile(context)) {
return initialHeight - 66; return initialHeight - 66;
} }
return initialHeight; return initialHeight;
@ -147,247 +147,216 @@ class SendPage extends BasePage {
Widget body(BuildContext context) { Widget body(BuildContext context) {
_setEffects(context); _setEffects(context);
return GestureDetector( return Form(
onLongPress: () => sendViewModel.balanceViewModel.isReversing = key: _formKey,
!sendViewModel.balanceViewModel.isReversing, child: ScrollableWithBottomSection(
onLongPressUp: () => sendViewModel.balanceViewModel.isReversing = contentPadding: EdgeInsets.only(bottom: 24),
!sendViewModel.balanceViewModel.isReversing, content: FocusTraversalGroup(
child: Form( policy: OrderedTraversalPolicy(),
key: _formKey, child: Column(
child: ScrollableWithBottomSection( children: <Widget>[
contentPadding: EdgeInsets.only(bottom: 24), Container(
content: FocusTraversalGroup( height: _sendCardHeight(context),
policy: OrderedTraversalPolicy(), child: Observer(
child: Column( builder: (_) {
children: <Widget>[ return PageView.builder(
Container( scrollDirection: Axis.horizontal,
height: _sendCardHeight(context), controller: controller,
child: Observer( itemCount: sendViewModel.outputs.length,
builder: (_) { itemBuilder: (context, index) {
return PageView.builder( final output = sendViewModel.outputs[index];
scrollDirection: Axis.horizontal,
controller: controller, return SendCard(
itemCount: sendViewModel.outputs.length, key: output.key,
itemBuilder: (context, index) { output: output,
final output = sendViewModel.outputs[index]; sendViewModel: sendViewModel,
initialPaymentRequest: initialPaymentRequest,
return SendCard( );
key: output.key, });
output: output, },
sendViewModel: sendViewModel, )),
initialPaymentRequest: initialPaymentRequest, Padding(
); padding:
}); EdgeInsets.only(top: 10, left: 24, right: 24, bottom: 10),
}, child: Container(
)), height: 10,
Padding( child: Observer(
padding: EdgeInsets.only( builder: (_) {
top: 10, left: 24, right: 24, bottom: 10), final count = sendViewModel.outputs.length;
child: Container(
height: 10, return count > 1
child: Observer( ? SmoothPageIndicator(
builder: (_) { controller: controller,
final count = sendViewModel.outputs.length; count: count,
effect: ScrollingDotsEffect(
return count > 1 spacing: 6.0,
? SmoothPageIndicator( radius: 6.0,
controller: controller, dotWidth: 6.0,
count: count, dotHeight: 6.0,
effect: ScrollingDotsEffect( dotColor: Theme.of(context)
spacing: 6.0, .primaryTextTheme!.displaySmall!
radius: 6.0, .backgroundColor!,
dotWidth: 6.0, activeDotColor: Theme.of(context)
dotHeight: 6.0, .primaryTextTheme!.displayMedium!
dotColor: Theme.of(context) .backgroundColor!),
.primaryTextTheme )
!.displaySmall! : Offstage();
.backgroundColor!, },
activeDotColor: Theme.of(context)
.primaryTextTheme
!.displayMedium!
.backgroundColor!),
)
: Offstage();
},
),
), ),
), ),
if (sendViewModel.hasMultiRecipient) ),
Container( if (sendViewModel.hasMultiRecipient)
height: 40, Container(
width: double.infinity, height: 40,
padding: EdgeInsets.only(left: 24), width: double.infinity,
child: SingleChildScrollView( padding: EdgeInsets.only(left: 24),
scrollDirection: Axis.horizontal, child: SingleChildScrollView(
child: Observer( scrollDirection: Axis.horizontal,
builder: (_) { child: Observer(
final templates = sendViewModel.templates; builder: (_) {
final itemCount = templates.length; final templates = sendViewModel.templates;
final itemCount = templates.length;
return Row(
children: <Widget>[ return Row(
AddTemplateButton( children: <Widget>[
onTap: () => Navigator.of(context) AddTemplateButton(
.pushNamed(Routes.sendTemplate), onTap: () => Navigator.of(context).pushNamed(Routes.sendTemplate),
currentTemplatesLength: templates.length, currentTemplatesLength: templates.length,
), ),
ListView.builder( ListView.builder(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
itemCount: itemCount, itemCount: itemCount,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final template = templates[index]; final template = templates[index];
return TemplateTile( return TemplateTile(
key: UniqueKey(), key: UniqueKey(),
to: template.name, to: template.name,
amount: template.isCurrencySelected amount: template.isCurrencySelected ? template.amount : template.amountFiat,
? template.amount from: template.isCurrencySelected ? template.cryptoCurrency : template.fiatCurrency,
: template.amountFiat, onTap: () async {
from: template.isCurrencySelected final fiatFromTemplate = FiatCurrency.all.singleWhere((element) => element.title == template.fiatCurrency);
? template.cryptoCurrency final output = _defineCurrentOutput();
: template.fiatCurrency, output.address = template.address;
onTap: () async { if(template.isCurrencySelected){
final fiatFromTemplate = FiatCurrency output.setCryptoAmount(template.amount);
.all }else{
.singleWhere((element) => sendViewModel.setFiatCurrency(fiatFromTemplate);
element.title == output.setFiatAmount(template.amountFiat);
template.fiatCurrency); }
final output = _defineCurrentOutput(); output.resetParsedAddress();
output.address = template.address; await output.fetchParsedAddress(context);
if (template.isCurrencySelected) { },
output onRemove: () {
.setCryptoAmount(template.amount); showPopUp<void>(
} else { context: context,
sendViewModel.setFiatCurrency( builder: (dialogContext) {
fiatFromTemplate); return AlertWithTwoActions(
output.setFiatAmount( alertTitle: S.of(context).template,
template.amountFiat); alertContent: S
} .of(context)
output.resetParsedAddress(); .confirm_delete_template,
await output rightButtonText: S.of(context).delete,
.fetchParsedAddress(context); leftButtonText: S.of(context).cancel,
}, actionRightButton: () {
onRemove: () { Navigator.of(dialogContext).pop();
showPopUp<void>( sendViewModel.sendTemplateViewModel
context: context, .removeTemplate(
builder: (dialogContext) { template: template);
return AlertWithTwoActions( },
alertTitle: actionLeftButton: () =>
S.of(context).template, Navigator.of(dialogContext)
alertContent: S .pop());
.of(context)
.confirm_delete_template,
rightButtonText:
S.of(context).delete,
leftButtonText:
S.of(context).cancel,
actionRightButton: () {
Navigator.of(dialogContext)
.pop();
sendViewModel
.sendTemplateViewModel
.removeTemplate(
template: template);
},
actionLeftButton: () =>
Navigator.of(dialogContext)
.pop());
},
);
}, },
); );
}, },
), );
], },
); ),
}, ],
), );
),
)
],
),
),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Column(
children: [
if (sendViewModel.hasCurrecyChanger)
Observer(
builder: (_) => Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () => presentCurrencyPicker(context),
text:
'Change your asset (${sendViewModel.selectedCryptoCurrency})',
color: Colors.transparent,
textColor: Theme.of(context)
.accentTextTheme
!.displaySmall!
.decorationColor!,
))),
if (sendViewModel.hasMultiRecipient)
Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () {
sendViewModel.addOutput();
Future.delayed(const Duration(milliseconds: 250), () {
controller
.jumpToPage(sendViewModel.outputs.length - 1);
});
},
text: S.of(context).add_receiver,
color: Colors.transparent,
textColor: Theme.of(context)
.accentTextTheme
!.displaySmall!
.decorationColor!,
isDottedBorder: true,
borderColor: Theme.of(context)
.primaryTextTheme
!.displaySmall!
.decorationColor!,
)),
Observer(
builder: (_) {
return LoadingPrimaryButton(
onPressed: () async {
if (_formKey.currentState != null &&
!_formKey.currentState!.validate()) {
if (sendViewModel.outputs.length > 1) {
showErrorValidationAlert(context);
}
return;
}
final notValidItems = sendViewModel.outputs
.where((item) =>
item.address.isEmpty ||
item.cryptoAmount.isEmpty)
.toList();
if (notValidItems.isNotEmpty ?? false) {
showErrorValidationAlert(context);
return;
}
await sendViewModel.createTransaction();
}, },
text: S.of(context).send, ),
color: ),
Theme.of(context).accentTextTheme!.bodyLarge!.color!,
textColor: Colors.white,
isLoading: sendViewModel.state is IsExecutingState ||
sendViewModel.state is TransactionCommitting,
isDisabled: !sendViewModel.isReadyForSend,
);
},
) )
], ],
)), ),
), ),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Column(
children: [
if (sendViewModel.hasCurrecyChanger)
Observer(builder: (_) =>
Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () => presentCurrencyPicker(context),
text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
color: Colors.transparent,
textColor: Theme.of(context)
.accentTextTheme!.displaySmall!
.decorationColor!,
)
)
),
if (sendViewModel.hasMultiRecipient)
Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () {
sendViewModel.addOutput();
Future.delayed(const Duration(milliseconds: 250), () {
controller.jumpToPage(sendViewModel.outputs.length - 1);
});
},
text: S.of(context).add_receiver,
color: Colors.transparent,
textColor: Theme.of(context)
.accentTextTheme!.displaySmall!
.decorationColor!,
isDottedBorder: true,
borderColor: Theme.of(context)
.primaryTextTheme!.displaySmall!
.decorationColor!,
)),
Observer(
builder: (_) {
return LoadingPrimaryButton(
onPressed: () async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
if (sendViewModel.outputs.length > 1) {
showErrorValidationAlert(context);
}
return;
}
final notValidItems = sendViewModel.outputs
.where((item) =>
item.address.isEmpty || item.cryptoAmount.isEmpty)
.toList();
if (notValidItems.isNotEmpty ?? false) {
showErrorValidationAlert(context);
return;
}
await sendViewModel.createTransaction();
},
text: S.of(context).send,
color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
textColor: Colors.white,
isLoading: sendViewModel.state is IsExecutingState ||
sendViewModel.state is TransactionCommitting,
isDisabled: !sendViewModel.isReadyForSend,
);
},
)
],
)),
); );
} }
@ -415,54 +384,51 @@ class SendPage extends BasePage {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (context.mounted) { if (context.mounted) {
showPopUp<void>( showPopUp<void>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return ConfirmSendingAlert( return ConfirmSendingAlert(
alertTitle: S.of(context).confirm_sending, alertTitle: S.of(context).confirm_sending,
amount: S.of(context).send_amount, amount: S.of(context).send_amount,
amountValue: amountValue:
sendViewModel.pendingTransaction!.amountFormatted, sendViewModel.pendingTransaction!.amountFormatted,
fiatAmountValue: fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted,
sendViewModel.pendingTransactionFiatAmountFormatted, fee: S.of(context).send_fee,
fee: S.of(context).send_fee, feeValue: sendViewModel.pendingTransaction!.feeFormatted,
feeValue: sendViewModel.pendingTransaction!.feeFormatted, feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
feeFiatAmount: sendViewModel outputs: sendViewModel.outputs,
.pendingTransactionFeeFiatAmountFormatted, rightButtonText: S.of(context).ok,
outputs: sendViewModel.outputs, leftButtonText: S.of(context).cancel,
rightButtonText: S.of(context).ok, actionRightButton: () {
leftButtonText: S.of(context).cancel, Navigator.of(context).pop();
actionRightButton: () { sendViewModel.commitTransaction();
Navigator.of(context).pop(); showPopUp<void>(
sendViewModel.commitTransaction(); context: context,
showPopUp<void>( builder: (BuildContext context) {
context: context, return Observer(builder: (_) {
builder: (BuildContext context) { final state = sendViewModel.state;
return Observer(builder: (_) {
final state = sendViewModel.state;
if (state is FailureState) { if (state is FailureState) {
Navigator.of(context).pop(); Navigator.of(context).pop();
}
if (state is TransactionCommitted) {
return AlertWithOneAction(
alertTitle: '',
alertContent: S.of(context).send_success(
sendViewModel.selectedCryptoCurrency.toString()),
buttonText: S.of(context).ok,
buttonAction: () {
Navigator.of(context).pop();
RequestReviewHandler.requestReview();
});
} }
if (state is TransactionCommitted) { return Offstage();
return AlertWithOneAction(
alertTitle: '',
alertContent: S.of(context).send_success(
sendViewModel.selectedCryptoCurrency
.toString()),
buttonText: S.of(context).ok,
buttonAction: () {
Navigator.of(context).pop();
RequestReviewHandler.requestReview();
});
}
return Offstage();
});
}); });
}, });
actionLeftButton: () => Navigator.of(context).pop()); },
}); actionLeftButton: () => Navigator.of(context).pop());
});
} }
}); });
} }
@ -497,18 +463,16 @@ class SendPage extends BasePage {
}); });
} }
void presentCurrencyPicker(BuildContext context) async { void presentCurrencyPicker(BuildContext context) async {
await showPopUp<CryptoCurrency>( await showPopUp<CryptoCurrency>(
builder: (_) => Picker( builder: (_) => Picker(
items: sendViewModel.currencies, items: sendViewModel.currencies,
displayItem: (Object item) => item.toString(), displayItem: (Object item) => item.toString(),
selectedAtIndex: sendViewModel.currencies selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
.indexOf(sendViewModel.selectedCryptoCurrency), title: S.of(context).please_select,
title: S.of(context).please_select, mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, onItemSelected: (CryptoCurrency cur) => sendViewModel.selectedCryptoCurrency = cur,
onItemSelected: (CryptoCurrency cur) => ),
sendViewModel.selectedCryptoCurrency = cur,
),
context: context); context: context);
} }
} }

View file

@ -122,7 +122,7 @@ class SendCardState extends State<SendCard>
color: Colors.transparent, color: Colors.transparent,
)), )),
Container( Container(
decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration( decoration: ResponsiveLayoutUtil.instance.isMobile(context) ? BoxDecoration(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24), bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24)), bottomRight: Radius.circular(24)),
@ -137,9 +137,9 @@ class SendCardState extends State<SendCard>
child: Padding( child: Padding(
padding: EdgeInsets.fromLTRB( padding: EdgeInsets.fromLTRB(
24, 24,
ResponsiveLayoutUtil.instance.isMobile ? 100 : 55, ResponsiveLayoutUtil.instance.isMobile(context) ? 100 : 55,
24, 24,
ResponsiveLayoutUtil.instance.isMobile ? 32 : 0, ResponsiveLayoutUtil.instance.isMobile(context) ? 32 : 0,
), ),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Observer(builder: (_) => Column( child: Observer(builder: (_) => Column(

View file

@ -8,7 +8,6 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/theme_list.dart'; import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/settings/choices_list_item.dart'; import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart'; import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -30,11 +29,11 @@ class DisplaySettingsPage extends BasePage {
child: Column( child: Column(
children: [ children: [
SettingsSwitcherCell( SettingsSwitcherCell(
title: S.current.settings_display_balance, title: S.current.settings_display_balance,
value: _displaySettingsViewModel.shouldDisplayBalance, value: _displaySettingsViewModel.shouldDisplayBalance,
onValueChange: (_, bool value) { onValueChange: (_, bool value) {
_displaySettingsViewModel.setShouldDisplayBalance(value); _displaySettingsViewModel.setShouldDisplayBalance(value);
}), }),
SettingsSwitcherCell( SettingsSwitcherCell(
title: S.current.show_market_place, title: S.current.show_market_place,
value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard, value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
@ -43,17 +42,14 @@ class DisplaySettingsPage extends BasePage {
}, },
), ),
//if (!isHaven) it does not work correctly //if (!isHaven) it does not work correctly
if (!_displaySettingsViewModel.disabledFiatApiMode) if(!_displaySettingsViewModel.disabledFiatApiMode)
SettingsPickerCell<FiatCurrency>( SettingsPickerCell<FiatCurrency>(
title: S.current.settings_currency, title: S.current.settings_currency,
searchHintText: S.current.search_currency, searchHintText: S.current.search_currency,
items: FiatCurrency.all, items: FiatCurrency.all,
selectedItem: _displaySettingsViewModel.fiatCurrency, selectedItem: _displaySettingsViewModel.fiatCurrency,
onItemSelected: (FiatCurrency currency) => onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency),
_displaySettingsViewModel.setFiatCurrency(currency), images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
images: FiatCurrency.all
.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
.toList(),
isGridView: true, isGridView: true,
matchingCriteria: (FiatCurrency currency, String searchText) { matchingCriteria: (FiatCurrency currency, String searchText) {
return currency.title.toLowerCase().contains(searchText) || return currency.title.toLowerCase().contains(searchText) ||
@ -70,14 +66,13 @@ class DisplaySettingsPage extends BasePage {
selectedItem: _displaySettingsViewModel.languageCode, selectedItem: _displaySettingsViewModel.languageCode,
onItemSelected: _displaySettingsViewModel.onLanguageSelected, onItemSelected: _displaySettingsViewModel.onLanguageSelected,
images: LanguageService.list.keys images: LanguageService.list.keys
.map((e) => Image.asset( .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
"assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
.toList(), .toList(),
matchingCriteria: (String code, String searchText) { matchingCriteria: (String code, String searchText) {
return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false; return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
}, },
), ),
if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile) if (DeviceInfo.instance.isMobile)
SettingsChoicesCell( SettingsChoicesCell(
ChoicesListItem<ThemeBase>( ChoicesListItem<ThemeBase>(
title: S.current.color_theme, title: S.current.color_theme,

View file

@ -43,24 +43,26 @@ class TotpAuthCodePageState extends State<TotpAuthCodePage> {
@override @override
void initState() { void initState() {
if(widget.totpArguments.onTotpAuthenticationFinished != null) { _reaction ??= reaction((_) => widget.setup2FAViewModel.state, (ExecutionState state) {
_reaction ??= reaction((_) => widget.setup2FAViewModel.state, (ExecutionState state) { if (state is ExecutedSuccessfullyState) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (state is ExecutedSuccessfullyState) { widget.totpArguments.onTotpAuthenticationFinished!(true, this);
widget.totpArguments.onTotpAuthenticationFinished!(true, this); });
} }
if (state is FailureState) { if (state is FailureState) {
print(state.error); print(state.error);
widget.totpArguments.onTotpAuthenticationFinished!(false, this); WidgetsBinding.instance.addPostFrameCallback((_) {
} widget.totpArguments.onTotpAuthenticationFinished!(false, this);
});
}
if (state is AuthenticationBanned) { if (state is AuthenticationBanned) {
widget.totpArguments.onTotpAuthenticationFinished!(false, this); WidgetsBinding.instance.addPostFrameCallback((_) {
} widget.totpArguments.onTotpAuthenticationFinished!(false, this);
}); });
}
}); });
}
super.initState(); super.initState();
} }

View file

@ -26,7 +26,7 @@ class AddTemplateButton extends StatelessWidget {
child: Container( child: Container(
height: 34, height: 34,
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: ResponsiveLayoutUtil.instance.isMobile ? 10 : 30), horizontal: ResponsiveLayoutUtil.instance.isMobile(context) ? 10 : 30),
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)), borderRadius: BorderRadius.all(Radius.circular(20)),

View file

@ -1,6 +1,6 @@
import 'dart:io';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -105,7 +105,7 @@ class AddressTextField extends StatelessWidget {
width: prefixIconWidth * options.length + width: prefixIconWidth * options.length +
(spaceBetweenPrefixIcons * options.length), (spaceBetweenPrefixIcons * options.length),
child: Row( child: Row(
mainAxisAlignment: ResponsiveLayoutUtil.instance.isMobile mainAxisAlignment: DeviceInfo.instance.isMobile
? MainAxisAlignment.spaceBetween : MainAxisAlignment.end, ? MainAxisAlignment.spaceBetween : MainAxisAlignment.end,
children: [ children: [
SizedBox(width: 5), SizedBox(width: 5),

View file

@ -1,4 +1,3 @@
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cw_core/balance.dart'; import 'package:cw_core/balance.dart';
@ -39,6 +38,5 @@ abstract class AppStoreBase with Store {
wallet) { wallet) {
this.wallet?.close(); this.wallet?.close();
this.wallet = wallet; this.wallet = wallet;
this.wallet!.setExceptionHandler(ExceptionHandler.onError);
} }
} }

View file

@ -580,6 +580,7 @@ abstract class SettingsStoreBase with Store {
if (Platform.isAndroid) { if (Platform.isAndroid) {
final androidInfo = await deviceInfoPlugin.androidInfo; final androidInfo = await deviceInfoPlugin.androidInfo;
deviceName = '${androidInfo.brand}%20${androidInfo.manufacturer}%20${androidInfo.model}'; deviceName = '${androidInfo.brand}%20${androidInfo.manufacturer}%20${androidInfo.model}';
print(deviceName);
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
final iosInfo = await deviceInfoPlugin.iosInfo; final iosInfo = await deviceInfoPlugin.iosInfo;
deviceName = iosInfo.model; deviceName = iosInfo.model;

View file

@ -131,16 +131,17 @@ class ExceptionHandler {
_ignoredErrors.any((element) => error.contains(element)); _ignoredErrors.any((element) => error.contains(element));
static const List<String> _ignoredErrors = const [ static const List<String> _ignoredErrors = const [
"Bad file descriptor", "errno = 9", // SocketException: Bad file descriptor
"No space left on device", "errno = 28", // OS Error: No space left on device
"Write failed (OS Error: Broken pipe)", "errno = 32", // SocketException: Write failed (OS Error: Broken pipe)
"Can't assign requested address", "errno = 49", // SocketException: Can't assign requested address
"Read failed (OS Error: Socket is not connected)", "errno = 54", // SocketException: Connection reset by peer
"Operation timed out", "errno = 57", // SocketException: Read failed (OS Error: Socket is not connected)
"No route to host", "errno = 60", // SocketException: Operation timed out
"Software caused connection abort", "errno = 65", // SocketException: No route to host
"Connection reset by peer", "errno = 103", // SocketException: Software caused connection abort
"Connection timed out", "errno = 104", // SocketException: Connection reset by peer
"errno = 110", // SocketException: Connection timed out
"Connection reset by peer", "Connection reset by peer",
"Connection closed before full header was received", "Connection closed before full header was received",
"Connection terminated during handshake", "Connection terminated during handshake",

View file

@ -296,7 +296,8 @@ abstract class DashboardViewModelBase with Store {
bool get isEnabledSellAction => bool get isEnabledSellAction =>
!settingsStore.disableSell && !settingsStore.disableSell &&
wallet.type != WalletType.haven && wallet.type != WalletType.haven &&
wallet.type != WalletType.monero; wallet.type != WalletType.monero &&
wallet.type != WalletType.litecoin;
@observable @observable
bool hasSellAction; bool hasSellAction;

View file

@ -1,17 +0,0 @@
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:mobx/mobx.dart';
part 'market_place_view_model.g.dart';
class MarketPlaceViewModel = MarketPlaceViewModelBase with _$MarketPlaceViewModel;
abstract class MarketPlaceViewModelBase with Store {
final IoniaService _ioniaService;
MarketPlaceViewModelBase(this._ioniaService);
Future<bool> isIoniaUserAuthenticated() async {
return await _ioniaService.isLogined();
}
}

View file

@ -13,6 +13,7 @@ import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:cw_core/keyable.dart'; import 'package:cw_core/keyable.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
class TransactionListItem extends ActionListItem with Keyable { class TransactionListItem extends ActionListItem with Keyable {
TransactionListItem( TransactionListItem(
{required this.transaction, {required this.transaction,
@ -27,7 +28,7 @@ class TransactionListItem extends ActionListItem with Keyable {
FiatCurrency get fiatCurrency => settingsStore.fiatCurrency; FiatCurrency get fiatCurrency => settingsStore.fiatCurrency;
BalanceDisplayMode get displayMode => balanceViewModel.displayMode; BalanceDisplayMode get displayMode => settingsStore.balanceDisplayMode;
@override @override
dynamic get keyIndex => transaction.id; dynamic get keyIndex => transaction.id;

View file

@ -48,7 +48,7 @@ abstract class ExchangeTradeViewModelBase with Store {
case ExchangeProviderDescription.simpleSwap: case ExchangeProviderDescription.simpleSwap:
_provider = SimpleSwapExchangeProvider(); _provider = SimpleSwapExchangeProvider();
break; break;
case ExchangeProviderDescription.trocador: case ExchangeProviderDescription.trocador:
_provider = TrocadorExchangeProvider(); _provider = TrocadorExchangeProvider();
break; break;
} }
@ -115,10 +115,6 @@ abstract class ExchangeTradeViewModelBase with Store {
updatedTrade.createdAt = trade.createdAt; updatedTrade.createdAt = trade.createdAt;
} }
if (updatedTrade.amount.isEmpty) {
updatedTrade.amount = trade.amount;
}
trade = updatedTrade; trade = updatedTrade;
_updateItems(); _updateItems();
@ -128,8 +124,7 @@ abstract class ExchangeTradeViewModelBase with Store {
} }
void _updateItems() { void _updateItems() {
final tagFrom = final tagFrom = tradesStore.trade!.from.tag != null ? '${tradesStore.trade!.from.tag}' + ' ' : '';
tradesStore.trade!.from.tag != null ? '${tradesStore.trade!.from.tag}' + ' ' : '';
final tagTo = tradesStore.trade!.to.tag != null ? '${tradesStore.trade!.to.tag}' + ' ' : ''; final tagTo = tradesStore.trade!.to.tag != null ? '${tradesStore.trade!.to.tag}' + ' ' : '';
items.clear(); items.clear();
items.add(ExchangeTradeItem( items.add(ExchangeTradeItem(

View file

@ -443,9 +443,7 @@ abstract class ExchangeViewModelBase with Store {
request = SideShiftRequest( request = SideShiftRequest(
depositMethod: depositCurrency, depositMethod: depositCurrency,
settleMethod: receiveCurrency, settleMethod: receiveCurrency,
depositAmount: isFixedRateMode depositAmount: depositAmount.replaceAll(',', '.'),
? receiveAmount.replaceAll(',', '.')
: depositAmount.replaceAll(',', '.'),
settleAddress: receiveAddress, settleAddress: receiveAddress,
refundAddress: depositAddress, refundAddress: depositAddress,
); );

View file

@ -16,10 +16,12 @@ abstract class IoniaGiftCardsListViewModelBase with Store {
ioniaCategories = IoniaCategory.allCategories, ioniaCategories = IoniaCategory.allCategories,
selectedIndices = ObservableList<IoniaCategory>.of([IoniaCategory.all]), selectedIndices = ObservableList<IoniaCategory>.of([IoniaCategory.all]),
scrollOffsetFromTop = 0.0, scrollOffsetFromTop = 0.0,
isLoggedIn = false,
merchantState = InitialIoniaMerchantLoadingState(), merchantState = InitialIoniaMerchantLoadingState(),
createCardState = IoniaCreateCardState(), createCardState = IoniaCreateCardState(),
searchString = '', searchString = '',
ioniaMerchantList = <IoniaMerchant>[] { ioniaMerchantList = <IoniaMerchant>[] {
_getAuthStatus().then((value) => isLoggedIn = value);
} }
final IoniaService ioniaService; final IoniaService ioniaService;
@ -43,17 +45,24 @@ abstract class IoniaGiftCardsListViewModelBase with Store {
@observable @observable
List<IoniaMerchant> ioniaMerchants; List<IoniaMerchant> ioniaMerchants;
@observable
bool isLoggedIn;
@observable @observable
List<IoniaCategory> ioniaCategories; List<IoniaCategory> ioniaCategories;
@observable @observable
ObservableList<IoniaCategory> selectedIndices; ObservableList<IoniaCategory> selectedIndices;
Future<bool> _getAuthStatus() async {
return await ioniaService.isLogined();
}
@action @action
Future<void> createCard() async { Future<void> createCard() async {
try { try {
createCardState = IoniaCreateCardLoading(); createCardState = IoniaCreateCardLoading();
await ioniaService.createCard(); final card = await ioniaService.createCard();
createCardState = IoniaCreateCardSuccess(); createCardState = IoniaCreateCardSuccess();
} catch (e) { } catch (e) {
createCardState = IoniaCreateCardFailure(error: e.toString()); createCardState = IoniaCreateCardFailure(error: e.toString());

View file

@ -21,7 +21,6 @@ import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart
import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart'; import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart';
import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart'; import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:collection/collection.dart';
part 'trade_details_view_model.g.dart'; part 'trade_details_view_model.g.dart';
@ -33,8 +32,7 @@ abstract class TradeDetailsViewModelBase with Store {
required this.trades, required this.trades,
required this.settingsStore, required this.settingsStore,
}) : items = ObservableList<StandartListItem>(), }) : items = ObservableList<StandartListItem>(),
trade = trades.values.firstWhereOrNull((element) => element.id == tradeForDetails.id) ?? trade = tradeForDetails {
tradeForDetails {
switch (trade.provider) { switch (trade.provider) {
case ExchangeProviderDescription.xmrto: case ExchangeProviderDescription.xmrto:
_provider = XMRTOExchangeProvider(); _provider = XMRTOExchangeProvider();
@ -56,6 +54,8 @@ abstract class TradeDetailsViewModelBase with Store {
break; break;
} }
items = ObservableList<StandartListItem>();
_updateItems(); _updateItems();
_updateTrade(); _updateTrade();
@ -85,12 +85,6 @@ abstract class TradeDetailsViewModelBase with Store {
if (updatedTrade.createdAt == null && trade.createdAt != null) { if (updatedTrade.createdAt == null && trade.createdAt != null) {
updatedTrade.createdAt = trade.createdAt; updatedTrade.createdAt = trade.createdAt;
} }
Trade? foundElement = trades.values.firstWhereOrNull((element) => element.id == trade.id);
if (foundElement != null) {
final editedTrade = trades.get(foundElement.key);
editedTrade?.stateRaw = updatedTrade.stateRaw;
editedTrade?.save();
}
trade = updatedTrade; trade = updatedTrade;
@ -160,9 +154,8 @@ abstract class TradeDetailsViewModelBase with Store {
} }
void _launchUrl(String url) { void _launchUrl(String url) {
final uri = Uri.parse(url);
try { try {
launchUrl(uri); launch(url);
} catch (e) {} } catch (e) {}
} }
} }

View file

@ -5,7 +5,7 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import connectivity_plus_macos import connectivity_macos
import cw_monero import cw_monero
import device_info_plus import device_info_plus
import devicelocale import devicelocale

View file

@ -36,9 +36,5 @@ end
post_install do |installer| post_install do |installer|
installer.pods_project.targets.each do |target| installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target) flutter_additional_macos_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = '12.0'
end
end end
end end

View file

@ -1,7 +1,7 @@
PODS: PODS:
- connectivity_plus_macos (0.0.1): - connectivity_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- ReachabilitySwift - Reachability
- cw_monero (0.0.1): - cw_monero (0.0.1):
- cw_monero/Boost (= 0.0.1) - cw_monero/Boost (= 0.0.1)
- cw_monero/Monero (= 0.0.1) - cw_monero/Monero (= 0.0.1)
@ -37,7 +37,7 @@ PODS:
- FlutterMacOS - FlutterMacOS
- platform_device_id_macos (0.0.1): - platform_device_id_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- ReachabilitySwift (5.0.0) - Reachability (3.2)
- share_plus_macos (0.0.1): - share_plus_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- shared_preferences_foundation (0.0.1): - shared_preferences_foundation (0.0.1):
@ -49,7 +49,7 @@ PODS:
- FlutterMacOS - FlutterMacOS
DEPENDENCIES: DEPENDENCIES:
- connectivity_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos`) - connectivity_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_macos/macos`)
- cw_monero (from `Flutter/ephemeral/.symlinks/plugins/cw_monero/macos`) - cw_monero (from `Flutter/ephemeral/.symlinks/plugins/cw_monero/macos`)
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`) - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`)
@ -67,11 +67,11 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- ReachabilitySwift - Reachability
EXTERNAL SOURCES: EXTERNAL SOURCES:
connectivity_plus_macos: connectivity_macos:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/connectivity_macos/macos
cw_monero: cw_monero:
:path: Flutter/ephemeral/.symlinks/plugins/cw_monero/macos :path: Flutter/ephemeral/.symlinks/plugins/cw_monero/macos
device_info_plus: device_info_plus:
@ -102,7 +102,7 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos
SPEC CHECKSUMS: SPEC CHECKSUMS:
connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308 connectivity_macos: 5dae6ee11d320fac7c05f0d08bd08fc32b5514d9
cw_monero: ec03de55a19c4a2b174ea687e0f4202edc716fa4 cw_monero: ec03de55a19c4a2b174ea687e0f4202edc716fa4
device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225
@ -113,12 +113,12 @@ SPEC CHECKSUMS:
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
platform_device_id: 3e414428f45df149bbbfb623e2c0ca27c545b763 platform_device_id: 3e414428f45df149bbbfb623e2c0ca27c545b763
platform_device_id_macos: f763bb55f088be804d61b96eb4710b8ab6598e94 platform_device_id_macos: f763bb55f088be804d61b96eb4710b8ab6598e94
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4 share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451 url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451
wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9
PODFILE CHECKSUM: 5107934592df7813b33d744aebc8ddc6b5a5445f PODFILE CHECKSUM: 505596d150d38022472859d890f709281982e016
COCOAPODS: 1.11.2 COCOAPODS: 1.11.2

View file

@ -75,6 +75,7 @@
9646C67C7114830A5ACFF5DF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; 9646C67C7114830A5ACFF5DF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
9F565D5729954F53009A75FB /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = secRandom.swift; path = CakeWallet/secRandom.swift; sourceTree = "<group>"; }; 9F565D5729954F53009A75FB /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = secRandom.swift; path = CakeWallet/secRandom.swift; sourceTree = "<group>"; };
9F565D5829954F53009A75FB /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = decrypt.swift; path = CakeWallet/decrypt.swift; sourceTree = "<group>"; };
B38D1DBC56DBD386923BC063 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B38D1DBC56DBD386923BC063 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -104,6 +105,7 @@
33CC10E42044A3C60003C045 = { 33CC10E42044A3C60003C045 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9F565D5829954F53009A75FB /* decrypt.swift */,
9F565D5729954F53009A75FB /* secRandom.swift */, 9F565D5729954F53009A75FB /* secRandom.swift */,
33FAB671232836740065AC1E /* Runner */, 33FAB671232836740065AC1E /* Runner */,
33CEB47122A05771004F2AC0 /* Flutter */, 33CEB47122A05771004F2AC0 /* Flutter */,

View file

@ -49,8 +49,8 @@ dependencies:
# password: ^1.0.0 # password: ^1.0.0
basic_utils: ^4.3.0 basic_utils: ^4.3.0
get_it: ^7.2.0 get_it: ^7.2.0
# connectivity: ^3.0.3 connectivity: ^3.0.3
connectivity_plus: ^2.3.5 # connectivity_plus: ^2.3.5
keyboard_actions: ^4.0.1 keyboard_actions: ^4.0.1
another_flushbar: ^1.12.29 another_flushbar: ^1.12.29
archive: ^3.3.0 archive: ^3.3.0

View file

@ -14,14 +14,14 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1 APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.3.8" MONERO_COM_VERSION="1.3.7"
MONERO_COM_BUILD_NUMBER=51 MONERO_COM_BUILD_NUMBER=50
MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app" MONERO_COM_PACKAGE="com.monero.app"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.6.7" CAKEWALLET_VERSION="4.6.6"
CAKEWALLET_BUILD_NUMBER=161 CAKEWALLET_BUILD_NUMBER=160
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"

View file

@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1 APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.3.8" MONERO_COM_VERSION="1.3.7"
MONERO_COM_BUILD_NUMBER=49 MONERO_COM_BUILD_NUMBER=48
MONERO_COM_BUNDLE_ID="com.cakewallet.monero" MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.6.7" CAKEWALLET_VERSION="4.6.6"
CAKEWALLET_BUILD_NUMBER=159 CAKEWALLET_BUILD_NUMBER=155
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven" HAVEN_NAME="Haven"

View file

@ -14,8 +14,8 @@ if [ -n "$1" ]; then
fi fi
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.0.2" CAKEWALLET_VERSION="1.0.1"
CAKEWALLET_BUILD_NUMBER=3 CAKEWALLET_BUILD_NUMBER=2
if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
echo "Wrong app type." echo "Wrong app type."

View file

@ -15,8 +15,8 @@ if [ -n "$1" ]; then
fi fi
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.0.6" CAKEWALLET_VERSION="1.0.5"
CAKEWALLET_BUILD_NUMBER=25 CAKEWALLET_BUILD_NUMBER=24
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

View file

@ -20,6 +20,7 @@ class SecretKey {
SecretKey('moonPayApiKey', () => ''), SecretKey('moonPayApiKey', () => ''),
SecretKey('moonPaySecretKey', () => ''), SecretKey('moonPaySecretKey', () => ''),
SecretKey('sideShiftAffiliateId', () => ''), SecretKey('sideShiftAffiliateId', () => ''),
SecretKey('sideShiftApiKey', () => ''),
SecretKey('simpleSwapApiKey', () => ''), SecretKey('simpleSwapApiKey', () => ''),
SecretKey('simpleSwapApiKeyDesktop', () => ''), SecretKey('simpleSwapApiKeyDesktop', () => ''),
SecretKey('anypayToken', () => ''), SecretKey('anypayToken', () => ''),