diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index 46924cb35..23902f110 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -42,7 +42,7 @@ jobs: - name: Flutter action uses: subosito/flutter-action@v1 with: - flutter-version: "3.10.x" + flutter-version: "3.19.5" channel: stable - name: Install package dependencies diff --git a/assets/tron_node_list.yml b/assets/tron_node_list.yml index e30f79d53..4c67b920e 100644 --- a/assets/tron_node_list.yml +++ b/assets/tron_node_list.yml @@ -1,4 +1,8 @@ - uri: api.trongrid.io is_default: true + useSSL: true +- + uri: tron-rpc.publicnode.com:443 + is_default: false useSSL: true \ No newline at end of file diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart index 739d98062..f27a8bf1a 100644 --- a/cw_bitcoin/lib/bitcoin_wallet.dart +++ b/cw_bitcoin/lib/bitcoin_wallet.dart @@ -28,7 +28,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { required String password, required WalletInfo walletInfo, required Box unspentCoinsInfo, - required Uint8List seedBytes, + Uint8List? seedBytes, String? mnemonic, String? xpub, String? addressPageType, @@ -68,10 +68,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { mainHd: hd, sideHd: accountHD.derive(1), network: networkParam ?? network, - masterHd: bitcoin.HDWallet.fromSeed( - seedBytes, - network: network == BitcoinNetwork.testnet ? bitcoin.testnet : bitcoin.bitcoin, - ), + masterHd: hd, ); autorun((_) { diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index ca9bce13b..65648d2a0 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -226,10 +226,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" convert: dependency: transitive description: @@ -463,6 +463,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" ledger_bitcoin: dependency: "direct main" description: @@ -500,26 +524,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.11.0" mime: dependency: transitive description: @@ -564,10 +588,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: "direct main" description: @@ -761,10 +785,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sp_scanner: dependency: "direct main" description: @@ -778,18 +802,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -818,10 +842,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" timing: dependency: transitive description: @@ -862,8 +886,16 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - watcher: + vm_service: dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" + watcher: + dependency: "direct overridden" description: name: watcher sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" @@ -911,5 +943,5 @@ packages: source: hosted version: "2.2.0" sdks: - dart: ">=3.0.6 <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=3.10.0" diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml index 6ea047f33..014bd5aa5 100644 --- a/cw_bitcoin/pubspec.yaml +++ b/cw_bitcoin/pubspec.yaml @@ -50,11 +50,14 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 build_resolvers: ^2.0.9 mobx_codegen: ^2.0.7 hive_generator: ^1.1.3 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml index 8aa7efd47..a0ce889c1 100644 --- a/cw_bitcoin_cash/pubspec.yaml +++ b/cw_bitcoin_cash/pubspec.yaml @@ -41,10 +41,13 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 mobx_codegen: ^2.0.7 hive_generator: ^1.1.3 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_core/lib/window_size.dart b/cw_core/lib/window_size.dart new file mode 100644 index 000000000..a0f192f66 --- /dev/null +++ b/cw_core/lib/window_size.dart @@ -0,0 +1,22 @@ +import 'dart:io'; + +import 'package:flutter/services.dart'; + +const MethodChannel _channel = MethodChannel('com.cake_wallet/native_utils'); + +Future setDefaultMinimumWindowSize() async { + if (!Platform.isMacOS) return; + + try { + final result = await _channel.invokeMethod( + 'setMinWindowSize', + {'width': 500, 'height': 700}, + ) as bool; + + if (!result) { + print("Failed to set minimum window size."); + } + } on PlatformException catch (e) { + print("Failed to set minimum window size: '${e.message}'."); + } +} diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock index 678e57b54..abfdbfc58 100644 --- a/cw_core/pubspec.lock +++ b/cw_core/pubspec.lock @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" convert: dependency: transitive description: @@ -331,6 +331,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" logging: dependency: transitive description: @@ -343,26 +367,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.11.0" mime: dependency: transitive description: @@ -407,10 +431,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: "direct main" description: @@ -564,26 +588,26 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -612,10 +636,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" timing: dependency: transitive description: @@ -640,8 +664,16 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - watcher: + vm_service: dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" + watcher: + dependency: "direct overridden" description: name: watcher sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" @@ -681,5 +713,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.0.0 <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=3.10.0" diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml index 36fe9967e..51d671dc7 100644 --- a/cw_core/pubspec.yaml +++ b/cw_core/pubspec.yaml @@ -28,11 +28,13 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 build_resolvers: ^2.0.9 mobx_codegen: ^2.0.7 hive_generator: ^2.0.1 +dependency_overrides: + watcher: ^1.1.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_ethereum/pubspec.yaml b/cw_ethereum/pubspec.yaml index 5f78fba3d..462e1d77e 100644 --- a/cw_ethereum/pubspec.yaml +++ b/cw_ethereum/pubspec.yaml @@ -24,11 +24,13 @@ dependency_overrides: git: url: https://github.com/cake-tech/web3dart.git ref: cake + watcher: ^1.1.0 dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 + flutter: # assets: # - images/a_dot_burr.jpeg diff --git a/cw_evm/pubspec.yaml b/cw_evm/pubspec.yaml index fb0384064..e4b29b676 100644 --- a/cw_evm/pubspec.yaml +++ b/cw_evm/pubspec.yaml @@ -36,11 +36,12 @@ dependency_overrides: git: url: https://github.com/cake-tech/ledger-flutter.git ref: cake + watcher: ^1.1.0 dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 mobx_codegen: ^2.0.7 hive_generator: ^1.1.3 flutter_lints: ^2.0.0 diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock index b13487936..8aeb70a97 100644 --- a/cw_haven/pubspec.lock +++ b/cw_haven/pubspec.lock @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" convert: dependency: transitive description: @@ -338,6 +338,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" logging: dependency: transitive description: @@ -350,26 +374,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.11.0" mime: dependency: transitive description: @@ -406,10 +430,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: "direct main" description: @@ -563,26 +587,26 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -611,10 +635,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" timing: dependency: transitive description: @@ -639,8 +663,16 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - watcher: + vm_service: dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" + watcher: + dependency: "direct overridden" description: name: watcher sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" @@ -680,5 +712,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=3.0.0 <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=3.7.0" diff --git a/cw_haven/pubspec.yaml b/cw_haven/pubspec.yaml index c215ab779..d868c986d 100644 --- a/cw_haven/pubspec.yaml +++ b/cw_haven/pubspec.yaml @@ -24,11 +24,14 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 mobx_codegen: ^2.0.7 build_resolvers: ^2.0.9 hive_generator: ^1.1.3 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_monero/example/pubspec.lock b/cw_monero/example/pubspec.lock index c9ca8d92b..7816a7fad 100644 --- a/cw_monero/example/pubspec.lock +++ b/cw_monero/example/pubspec.lock @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" convert: dependency: transitive description: @@ -201,6 +201,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -213,26 +237,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.11.0" mobx: dependency: transitive description: @@ -245,10 +269,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: transitive description: @@ -354,26 +378,26 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -394,10 +418,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" typed_data: dependency: transitive description: @@ -414,6 +438,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" win32: dependency: transitive description: @@ -431,5 +463,5 @@ packages: source: hosted version: "0.2.0+3" sdks: - dart: ">=3.0.6 <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=3.7.0" diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index ed9b12c07..adb50bd02 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" convert: dependency: transitive description: @@ -354,6 +354,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" logging: dependency: transitive description: @@ -366,26 +390,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.11.0" mime: dependency: transitive description: @@ -422,10 +446,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: "direct main" description: @@ -587,26 +611,26 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -635,10 +659,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" timing: dependency: transitive description: @@ -663,8 +687,16 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - watcher: + vm_service: dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" + watcher: + dependency: "direct overridden" description: name: watcher sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" @@ -704,5 +736,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=3.0.6 <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=3.7.0" diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml index a6fe7f967..c49a541ab 100644 --- a/cw_monero/pubspec.yaml +++ b/cw_monero/pubspec.yaml @@ -26,11 +26,14 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 build_resolvers: ^2.0.9 mobx_codegen: ^2.0.7 hive_generator: ^1.1.3 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_nano/pubspec.lock b/cw_nano/pubspec.lock index 2af954b5b..51e43145e 100644 --- a/cw_nano/pubspec.lock +++ b/cw_nano/pubspec.lock @@ -173,10 +173,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" convert: dependency: transitive description: @@ -399,6 +399,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" libcrypto: dependency: "direct main" description: @@ -419,26 +443,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.11.0" mime: dependency: transitive description: @@ -492,10 +516,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: transitive description: @@ -713,26 +737,26 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -761,10 +785,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" timing: dependency: transitive description: @@ -789,8 +813,16 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - watcher: + vm_service: dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" + watcher: + dependency: "direct overridden" description: name: watcher sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" @@ -830,5 +862,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.0.0 <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=3.10.0" diff --git a/cw_nano/pubspec.yaml b/cw_nano/pubspec.yaml index a4b8732fd..768c1bb4e 100644 --- a/cw_nano/pubspec.yaml +++ b/cw_nano/pubspec.yaml @@ -32,10 +32,13 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.1.11 + build_runner: ^2.4.7 mobx_codegen: ^2.0.7 hive_generator: ^1.1.3 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_polygon/pubspec.yaml b/cw_polygon/pubspec.yaml index dbef40b46..8421562b4 100644 --- a/cw_polygon/pubspec.yaml +++ b/cw_polygon/pubspec.yaml @@ -28,12 +28,14 @@ dependency_overrides: git: url: https://github.com/cake-tech/web3dart.git ref: cake + watcher: ^1.1.0 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 - build_runner: ^2.1.11 + build_runner: ^2.4.7 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_solana/pubspec.yaml b/cw_solana/pubspec.yaml index 7e24983bf..6b59282b4 100644 --- a/cw_solana/pubspec.yaml +++ b/cw_solana/pubspec.yaml @@ -26,10 +26,13 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 - build_runner: ^2.1.11 + build_runner: ^2.4.7 mobx_codegen: ^2.0.7 hive_generator: ^1.1.3 +dependency_overrides: + watcher: ^1.1.0 + flutter: # assets: # - images/a_dot_burr.jpeg diff --git a/cw_tron/lib/tron_client.dart b/cw_tron/lib/tron_client.dart index f03a8abce..73812f14c 100644 --- a/cw_tron/lib/tron_client.dart +++ b/cw_tron/lib/tron_client.dart @@ -367,7 +367,7 @@ class TronClient { ) async { // This is introduce to server as a limit in cases where feeLimit is 0 // The transaction signing will fail if the feeLimit is explicitly 0. - int defaultFeeLimit = 100000; + int defaultFeeLimit = 269000; final block = await _provider!.request(TronRequestGetNowBlock()); // Create the transfer contract @@ -401,8 +401,9 @@ class TronClient { final tronBalanceInt = tronBalance.toInt(); if (feeLimit > tronBalanceInt) { + final feeInTrx = TronHelper.fromSun(BigInt.parse(feeLimit.toString())); throw Exception( - 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up.', + 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up.\nTransaction fee: $feeInTrx TRX', ); } @@ -442,6 +443,9 @@ class TronClient { if (!request.isSuccess) { log("Tron TRC20 error: ${request.error} \n ${request.respose}"); + throw Exception( + 'An error occured while creating the transfer request. Please try again.', + ); } final feeLimit = await getFeeLimit( @@ -454,8 +458,9 @@ class TronClient { final tronBalanceInt = tronBalance.toInt(); if (feeLimit > tronBalanceInt) { + final feeInTrx = TronHelper.fromSun(BigInt.parse(feeLimit.toString())); throw Exception( - 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up.', + 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up. Transaction fee: $feeInTrx TRX', ); } diff --git a/lib/core/auth_service.dart b/lib/core/auth_service.dart index 48610784c..66943bb7f 100644 --- a/lib/core/auth_service.dart +++ b/lib/core/auth_service.dart @@ -42,12 +42,7 @@ class AuthService with Store { Future setPassword(String password) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final encodedPassword = encodedPinCode(pin: password); - // secure storage has a weird bug on macOS, where overwriting a key doesn't work, unless - // we delete what's there first: - if (Platform.isMacOS) { - await secureStorage.delete(key: key); - } - await secureStorage.write(key: key, value: encodedPassword); + await writeSecureStorage(secureStorage, key: key, value: encodedPassword); } Future canAuthenticate() async { @@ -74,7 +69,11 @@ class AuthService with Store { void saveLastAuthTime() { int timestamp = DateTime.now().millisecondsSinceEpoch; - secureStorage.write(key: SecureKey.lastAuthTimeMilliseconds, value: timestamp.toString()); + writeSecureStorage( + secureStorage, + key: SecureKey.lastAuthTimeMilliseconds, + value: timestamp.toString(), + ); } Future requireAuth() async { diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart index 2ec5f293d..d1092b024 100644 --- a/lib/core/backup_service.dart +++ b/lib/core/backup_service.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/themes/theme_list.dart'; import 'package:cake_wallet/utils/device_info.dart'; import 'package:cw_core/wallet_type.dart'; @@ -275,7 +276,7 @@ class BackupService { if (currentTransactionPriorityKeyLegacy != null) await _sharedPreferences.setInt( PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy); - + if (currentBitcoinElectrumSererId != null) await _sharedPreferences.setInt( PreferencesKey.currentBitcoinElectrumSererIdKey, currentBitcoinElectrumSererId); @@ -373,16 +374,15 @@ class BackupService { final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final backupPassword = keychainJSON[backupPasswordKey] as String; - await _flutterSecureStorage.delete(key: backupPasswordKey); - await _flutterSecureStorage.write(key: backupPasswordKey, value: backupPassword); + await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword); keychainWalletsInfo.forEach((dynamic rawInfo) async { final info = rawInfo as Map; await importWalletKeychainInfo(info); }); - await _flutterSecureStorage.delete(key: pinCodeKey); - await _flutterSecureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); + await writeSecureStorage(_flutterSecureStorage, + key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); keychainDumpFile.deleteSync(); } @@ -401,16 +401,15 @@ class BackupService { final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final backupPassword = keychainJSON[backupPasswordKey] as String; - await _flutterSecureStorage.delete(key: backupPasswordKey); - await _flutterSecureStorage.write(key: backupPasswordKey, value: backupPassword); + await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword); keychainWalletsInfo.forEach((dynamic rawInfo) async { final info = rawInfo as Map; await importWalletKeychainInfo(info); }); - await _flutterSecureStorage.delete(key: pinCodeKey); - await _flutterSecureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); + await writeSecureStorage(_flutterSecureStorage, + key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); keychainDumpFile.deleteSync(); } diff --git a/lib/core/key_service.dart b/lib/core/key_service.dart index f829c22b5..ba2da4de6 100644 --- a/lib/core/key_service.dart +++ b/lib/core/key_service.dart @@ -20,8 +20,7 @@ class KeyService { key: SecretStoreKey.moneroWalletPassword, walletName: walletName); final encodedPassword = encodeWalletPassword(password: password); - await _secureStorage.delete(key: key); - await _secureStorage.write(key: key, value: encodedPassword); + await writeSecureStorage(_secureStorage, key: key, value: encodedPassword); } Future deleteWalletPassword({required String walletName}) async { diff --git a/lib/core/secure_storage.dart b/lib/core/secure_storage.dart index 4d9334a10..5afb36d29 100644 --- a/lib/core/secure_storage.dart +++ b/lib/core/secure_storage.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // For now, we can create a utility function to handle this. // @@ -25,3 +26,13 @@ Future readSecureStorage(FlutterSecureStorage secureStorage, String key return result; } + +Future writeSecureStorage(FlutterSecureStorage secureStorage, + {required String key, required String value}) async { + // delete the value before writing on macOS because of a weird bug + // https://github.com/mogol/flutter_secure_storage/issues/581 + if (Platform.isMacOS) { + await secureStorage.delete(key: key); + } + await secureStorage.write(key: key, value: value); +} diff --git a/lib/entities/biometric_auth.dart b/lib/entities/biometric_auth.dart index 4b2bfd906..353cd0492 100644 --- a/lib/entities/biometric_auth.dart +++ b/lib/entities/biometric_auth.dart @@ -1,32 +1,29 @@ -import 'package:local_auth/local_auth.dart'; import 'package:flutter/services.dart'; -import 'package:cake_wallet/generated/i18n.dart'; +import 'package:flutter_local_authentication/flutter_local_authentication.dart'; class BiometricAuth { - final _localAuth = LocalAuthentication(); + final _flutterLocalAuthenticationPlugin = FlutterLocalAuthentication(); Future isAuthenticated() async { try { - return await _localAuth.authenticate( - localizedReason: S.current.biometric_auth_reason, - options: AuthenticationOptions( - biometricOnly: true, - useErrorDialogs: true, - stickyAuth: false)); - } on PlatformException catch (e) { + final authenticated = await _flutterLocalAuthenticationPlugin.authenticate(); + return authenticated; + } catch (e) { print(e); } - return false; } Future canCheckBiometrics() async { + bool canAuthenticate; try { - return await _localAuth.canCheckBiometrics; - } on PlatformException catch (e) { - print(e); + canAuthenticate = await _flutterLocalAuthenticationPlugin.canAuthenticate(); + await _flutterLocalAuthenticationPlugin.setTouchIDAuthenticationAllowableReuseDuration(0); + } catch (error) { + print("Exception checking support. $error"); + canAuthenticate = false; } - return false; + return canAuthenticate; } } \ No newline at end of file diff --git a/lib/entities/fs_migration.dart b/lib/entities/fs_migration.dart index 4280949cd..869ed66ff 100644 --- a/lib/entities/fs_migration.dart +++ b/lib/entities/fs_migration.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'dart:convert'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:collection/collection.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -147,8 +148,8 @@ Future ios_migrate_pin() async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final encodedPassword = encodedPinCode(pin: pinPassword); - await flutterSecureStorage.delete(key: key); - await flutterSecureStorage.write(key: key, value: encodedPassword); + await writeSecureStorage(flutterSecureStorage, key: key, value: encodedPassword); + await prefs.setBool('ios_migration_pin_completed', true); } diff --git a/lib/entities/get_encryption_key.dart b/lib/entities/get_encryption_key.dart index a32d4e311..04c3a65f7 100644 --- a/lib/entities/get_encryption_key.dart +++ b/lib/entities/get_encryption_key.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cw_core/cake_hive.dart'; @@ -10,8 +11,7 @@ Future> getEncryptionKey( key = CakeHive.generateSecureKey(); final keyStringified = key.join(','); String storageKey = 'transactionDescriptionsBoxKey'; - await secureStorage.delete(key: storageKey); - await secureStorage.write(key: storageKey, value: keyStringified); + await writeSecureStorage(secureStorage, key: storageKey, value: keyStringified); } else { key = stringifiedKey.split(',').map((i) => int.parse(i)).toList(); } diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index f729e6392..409724c6e 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -5,6 +5,7 @@ import 'package:cake_wallet/entities/openalias_record.dart'; import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/entities/emoji_string_extension.dart'; +import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart'; import 'package:cake_wallet/mastodon/mastodon_api.dart'; import 'package:cake_wallet/nostr/nostr_api.dart'; import 'package:cake_wallet/store/settings_store.dart'; @@ -71,8 +72,8 @@ class AddressResolver { return emailRegex.hasMatch(address); } - // TODO: refactor this to take Crypto currency instead of ticker, or at least pass in the tag as well - Future resolve(BuildContext context, String text, String ticker) async { + Future resolve(BuildContext context, String text, CryptoCurrency currency) async { + final ticker = currency.title; try { if (text.startsWith('@') && !text.substring(1).contains('@')) { if (settingsStore.lookupsTwitter) { @@ -116,8 +117,7 @@ class AddressResolver { await MastodonAPI.lookupUserByUserName(userName: userName, apiHost: hostName); if (mastodonUser != null) { - String? addressFromBio = extractAddressByType( - raw: mastodonUser.note, type: CryptoCurrency.fromString(ticker)); + String? addressFromBio = extractAddressByType(raw: mastodonUser.note, type: currency); if (addressFromBio != null) { return ParsedAddress.fetchMastodonAddress( @@ -131,8 +131,8 @@ class AddressResolver { if (pinnedPosts.isNotEmpty) { final userPinnedPostsText = pinnedPosts.map((item) => item.content).join('\n'); - String? addressFromPinnedPost = extractAddressByType( - raw: userPinnedPostsText, type: CryptoCurrency.fromString(ticker)); + String? addressFromPinnedPost = + extractAddressByType(raw: userPinnedPostsText, type: currency); if (addressFromPinnedPost != null) { return ParsedAddress.fetchMastodonAddress( @@ -162,6 +162,16 @@ class AddressResolver { } } } + + final thorChainAddress = await ThorChainExchangeProvider.lookupAddressByName(text); + if (thorChainAddress != null) { + String? address = + thorChainAddress[ticker] ?? (ticker == 'RUNE' ? thorChainAddress['THOR'] : null); + if (address != null) { + return ParsedAddress.thorChainAddress(address: address, name: text); + } + } + final formattedName = OpenaliasRecord.formatDomainName(text); final domainParts = formattedName.split('.'); final name = domainParts.last; @@ -204,7 +214,7 @@ class AddressResolver { if (nostrUserData != null) { String? addressFromBio = extractAddressByType( - raw: nostrUserData.about, type: CryptoCurrency.fromString(ticker)); + raw: nostrUserData.about, type: currency); if (addressFromBio != null) { return ParsedAddress.nostrAddress( address: addressFromBio, diff --git a/lib/entities/parsed_address.dart b/lib/entities/parsed_address.dart index fc8ab2440..cfd69acbe 100644 --- a/lib/entities/parsed_address.dart +++ b/lib/entities/parsed_address.dart @@ -11,7 +11,8 @@ enum ParseFrom { ens, contact, mastodon, - nostr + nostr, + thorChain } class ParsedAddress { @@ -133,6 +134,14 @@ class ParsedAddress { ); } + factory ParsedAddress.thorChainAddress({required String address, required String name}) { + return ParsedAddress( + addresses: [address], + name: name, + parseFrom: ParseFrom.thorChain, + ); + } + final List addresses; final String name; final String description; diff --git a/lib/exchange/provider/thorchain_exchange.provider.dart b/lib/exchange/provider/thorchain_exchange.provider.dart index 32dce7db8..826e203f3 100644 --- a/lib/exchange/provider/thorchain_exchange.provider.dart +++ b/lib/exchange/provider/thorchain_exchange.provider.dart @@ -34,11 +34,13 @@ class ThorChainExchangeProvider extends ExchangeProvider { static final isRefundAddressSupported = [CryptoCurrency.eth]; - static const _baseURL = 'thornode.ninerealms.com'; + static const _baseNodeURL = 'thornode.ninerealms.com'; + static const _baseURL = 'midgard.ninerealms.com'; static const _quotePath = '/thorchain/quote/swap'; static const _txInfoPath = '/thorchain/tx/status/'; static const _affiliateName = 'cakewallet'; static const _affiliateBps = '175'; + static const _nameLookUpPath= 'v2/thorname/lookup/'; final Box tradesStore; @@ -154,7 +156,7 @@ class ThorChainExchangeProvider extends ExchangeProvider { Future findTradeById({required String id}) async { if (id.isEmpty) throw Exception('Trade id is empty'); final formattedId = id.startsWith('0x') ? id.substring(2) : id; - final uri = Uri.https(_baseURL, '$_txInfoPath$formattedId'); + final uri = Uri.https(_baseNodeURL, '$_txInfoPath$formattedId'); final response = await http.get(uri); if (response.statusCode == 404) { @@ -206,8 +208,35 @@ class ThorChainExchangeProvider extends ExchangeProvider { ); } + static Future?>? lookupAddressByName(String name) async { + final uri = Uri.https(_baseURL, '$_nameLookUpPath$name'); + final response = await http.get(uri); + + if (response.statusCode != 200) { + return null; + } + + final body = json.decode(response.body) as Map; + final entries = body['entries'] as List?; + + if (entries == null || entries.isEmpty) { + return null; + } + + Map chainToAddressMap = {}; + + for (final entry in entries) { + final chain = entry['chain'] as String; + final address = entry['address'] as String; + chainToAddressMap[chain] = address; + } + + return chainToAddressMap; + } + + Future> _getSwapQuote(Map params) async { - Uri uri = Uri.https(_baseURL, _quotePath, params); + Uri uri = Uri.https(_baseNodeURL, _quotePath, params); final response = await http.get(uri); diff --git a/lib/locales/hausa_intl.dart b/lib/locales/hausa_intl.dart index 749d39a4d..6cf757b60 100644 --- a/lib/locales/hausa_intl.dart +++ b/lib/locales/hausa_intl.dart @@ -751,6 +751,50 @@ class HaMaterialLocalizations extends GlobalMaterialLocalizations { @override String get scrimOnTapHintRaw => "Scrip on Tap"; + + @override + // TODO: implement collapsedHint + String get collapsedHint => "collapsedHint"; + + @override + // TODO: implement expandedHint + String get expandedHint => "expandedHint"; + + @override + // TODO: implement expansionTileCollapsedHint + String get expansionTileCollapsedHint => "expansionTileCollapsedHint"; + + @override + // TODO: implement expansionTileCollapsedTapHint + String get expansionTileCollapsedTapHint => "expansionTileCollapsedTapHint"; + + @override + // TODO: implement expansionTileExpandedHint + String get expansionTileExpandedHint => "expansionTileExpandedHint"; + + @override + // TODO: implement expansionTileExpandedTapHint + String get expansionTileExpandedTapHint => "expansionTileExpandedTapHint"; + + @override + // TODO: implement scanTextButtonLabel + String get scanTextButtonLabel => "scanTextButtonLabel"; + + @override + // TODO: implement lookUpButtonLabel + String get lookUpButtonLabel => "lookUpButtonLabel"; + + @override + // TODO: implement menuDismissLabel + String get menuDismissLabel => "menuDismissLabel"; + + @override + // TODO: implement searchWebButtonLabel + String get searchWebButtonLabel => "searchWebButtonLabel"; + + @override + // TODO: implement shareButtonLabel + String get shareButtonLabel => "shareButtonLabel"; } /// Cupertino Support @@ -955,4 +999,24 @@ class HaCupertinoLocalizations extends GlobalCupertinoLocalizations { @override String get noSpellCheckReplacementsLabel => ""; + + @override + // TODO: implement clearButtonLabel + String get clearButtonLabel => "clearButtonLabel"; + + @override + // TODO: implement lookUpButtonLabel + String get lookUpButtonLabel => "lookUpButtonLabel"; + + @override + // TODO: implement menuDismissLabel + String get menuDismissLabel => "menuDismissLabel"; + + @override + // TODO: implement searchWebButtonLabel + String get searchWebButtonLabel => "searchWebButtonLabel"; + + @override + // TODO: implement shareButtonLabel + String get shareButtonLabel => "shareButtonLabel"; } diff --git a/lib/locales/yoruba_intl.dart b/lib/locales/yoruba_intl.dart index f16188529..3c720b80e 100644 --- a/lib/locales/yoruba_intl.dart +++ b/lib/locales/yoruba_intl.dart @@ -1,4 +1,3 @@ - import 'dart:async'; import 'package:flutter/cupertino.dart'; @@ -164,62 +163,62 @@ const yoDateSymbols = { 'ọjọ́ Àbámẹ́ta', ], 'STANDALONEWEEKDAYS': [ -'Ọjọ́ Ajé', -'Ọjọ́ Ìsẹ́gun', -'Ọjọ́ Ìsẹ́gun-Ẹtì', -'Ọjọ́ Ìsẹ́gun-Ọ̀rú', -'Ọjọ́ Àìkú', -'Ọjọ́ Jímọ̀', -'Ọjọ́ Àbámẹ́ta', -], -'SHORTWEEKDAYS': [ -'Ajé', -'Ìsẹ́gun', -'Ìsẹ́gun-Ẹtì', -'Ìsẹ́gun-Ọ̀rú', -'Àìkú', -'Jímọ̀', -'Àbámẹ́ta', -], -'STANDALONESHORTWEEKDAYS': [ -'Ajé', -'Ìsẹ́gun', -'Ìsẹ́gun-Ẹtì', -'Ìsẹ́gun-Ọ̀rú', -'Àìkú', -'Jímọ̀', -'Àbámẹ́ta', -], -'NARROWWEEKDAYS': [ -'A', -'A', -'Ì', -'A', -'À', -'J', -'À', -], -'STANDALONENARROWWEEKDAYS': [ -'A', -'A', -'Ì', -'A', -'À', -'J', -'À', -], -'SHORTQUARTERS': [ -'K1', -'K2', -'K3', -'K4', -], -'QUARTERS': [ -'1. kwata', -'2. kwata', -'3. kwata', -'4. kwata', -], + 'Ọjọ́ Ajé', + 'Ọjọ́ Ìsẹ́gun', + 'Ọjọ́ Ìsẹ́gun-Ẹtì', + 'Ọjọ́ Ìsẹ́gun-Ọ̀rú', + 'Ọjọ́ Àìkú', + 'Ọjọ́ Jímọ̀', + 'Ọjọ́ Àbámẹ́ta', + ], + 'SHORTWEEKDAYS': [ + 'Ajé', + 'Ìsẹ́gun', + 'Ìsẹ́gun-Ẹtì', + 'Ìsẹ́gun-Ọ̀rú', + 'Àìkú', + 'Jímọ̀', + 'Àbámẹ́ta', + ], + 'STANDALONESHORTWEEKDAYS': [ + 'Ajé', + 'Ìsẹ́gun', + 'Ìsẹ́gun-Ẹtì', + 'Ìsẹ́gun-Ọ̀rú', + 'Àìkú', + 'Jímọ̀', + 'Àbámẹ́ta', + ], + 'NARROWWEEKDAYS': [ + 'A', + 'A', + 'Ì', + 'A', + 'À', + 'J', + 'À', + ], + 'STANDALONENARROWWEEKDAYS': [ + 'A', + 'A', + 'Ì', + 'A', + 'À', + 'J', + 'À', + ], + 'SHORTQUARTERS': [ + 'K1', + 'K2', + 'K3', + 'K4', + ], + 'QUARTERS': [ + '1. kwata', + '2. kwata', + '3. kwata', + '4. kwata', + ], 'AMPMS': [ 'a.m.', 'p.m.', @@ -316,339 +315,339 @@ class YoMaterialLocalizations extends GlobalMaterialLocalizations { }); // #docregion Getters -@override -String get moreButtonTooltip => r'Kò sí ìròhùn tí ó múni'; + @override + String get moreButtonTooltip => r'Kò sí ìròhùn tí ó múni'; -@override -String get aboutListTileTitleRaw => r'Fun Àpótí àwọn $applicationname'; + @override + String get aboutListTileTitleRaw => r'Fun Àpótí àwọn $applicationname'; -@override -String get alertDialogLabel => r'Ìròhùn Àlàyé'; + @override + String get alertDialogLabel => r'Ìròhùn Àlàyé'; // #enddocregion Getters -@override -String get anteMeridiemAbbreviation => r'AM'; + @override + String get anteMeridiemAbbreviation => r'AM'; -@override -String get backButtonTooltip => r'Fíran'; + @override + String get backButtonTooltip => r'Fíran'; -@override -String get cancelButtonLabel => r'FAGILE'; + @override + String get cancelButtonLabel => r'FAGILE'; -@override -String get closeButtonLabel => r'KÚ'; + @override + String get closeButtonLabel => r'KÚ'; -@override -String get closeButtonTooltip => r'Kú'; + @override + String get closeButtonTooltip => r'Kú'; -@override -String get collapsedIconTapHint => r'Tá'; + @override + String get collapsedIconTapHint => r'Tá'; -@override -String get continueButtonLabel => r'TÓ WÁ'; + @override + String get continueButtonLabel => r'TÓ WÁ'; -@override -String get copyButtonLabel => r'DÚPLÍKÉTÍ'; + @override + String get copyButtonLabel => r'DÚPLÍKÉTÍ'; -@override -String get cutButtonLabel => r'TÒ'; + @override + String get cutButtonLabel => r'TÒ'; -@override -String get deleteButtonTooltip => r'Máa kú'; + @override + String get deleteButtonTooltip => r'Máa kú'; -@override -String get dialogLabel => r'Ìròhùn'; + @override + String get dialogLabel => r'Ìròhùn'; -@override -String get drawerLabel => r'Àgbèjọ àwọn àpọ̀tí'; + @override + String get drawerLabel => r'Àgbèjọ àwọn àpọ̀tí'; -@override -String get expandedIconTapHint => r'Tá'; + @override + String get expandedIconTapHint => r'Tá'; -@override -String get firstPageTooltip => r'Ojú ewe'; + @override + String get firstPageTooltip => r'Ojú ewe'; -@override -String get hideAccountsLabel => r'Fí èrò àpótí wáyé sílẹ̀'; + @override + String get hideAccountsLabel => r'Fí èrò àpótí wáyé sílẹ̀'; -@override -String get lastPageTooltip => r'Ojú ayé'; + @override + String get lastPageTooltip => r'Ojú ayé'; -@override -String get licensesPageTitle => r'Ìròhùn Ọdún'; + @override + String get licensesPageTitle => r'Ìròhùn Ọdún'; -@override -String get modalBarrierDismissLabel => r'Sọ'; + @override + String get modalBarrierDismissLabel => r'Sọ'; -@override -String get nextMonthTooltip => r'Oṣù kọja'; + @override + String get nextMonthTooltip => r'Oṣù kọja'; -@override -String get nextPageTooltip => r'Ojú ọjọ́ kẹta'; + @override + String get nextPageTooltip => r'Ojú ọjọ́ kẹta'; -@override -String get okButtonLabel => r'Ò daájú'; -@override + @override + String get okButtonLabel => r'Ò daájú'; + @override // A custom drawer tooltip message. -String get openAppDrawerTooltip => r'Aya ntọju Iwe Awọn Aka'; + String get openAppDrawerTooltip => r'Aya ntọju Iwe Awọn Aka'; // #docregion Raw -@override -String get pageRowsInfoTitleRaw => r'$firstRow–$lastRow lati $rowCount'; + @override + String get pageRowsInfoTitleRaw => r'$firstRow–$lastRow lati $rowCount'; -@override -String get pageRowsInfoTitleApproximateRaw => r'$firstRow–$lastRow lati kiakia $rowCount'; + @override + String get pageRowsInfoTitleApproximateRaw => r'$firstRow–$lastRow lati kiakia $rowCount'; // #enddocregion Raw -@override -String get pasteButtonLabel => r'TÌ'; - -@override -String get popupMenuLabel => r'Meniu Pop-up'; - -@override -String get menuBarMenuLabel => r'Meniu Akọkọ'; - -@override -String get postMeridiemAbbreviation => r'PM'; - -@override -String get previousMonthTooltip => r'Oṣu Kanakana'; - -@override -String get previousPageTooltip => r'Ojú ewé akọkọ kan'; - -@override -String get refreshIndicatorSemanticLabel => r'Gbiyanju'; - -@override -String? get remainingTextFieldCharacterCountFew => null; - -@override -String? get remainingTextFieldCharacterCountMany => null; - -@override -String get remainingTextFieldCharacterCountOne => r'1 àmì báálẹ̀'; - -@override -String get remainingTextFieldCharacterCountOther => r'$remainingCount àmì báálẹ̀'; - -@override -String? get remainingTextFieldCharacterCountTwo => null; - -@override -String get remainingTextFieldCharacterCountZero => r'Kò sí ìwọlé létà láti ń ṣe'; - -@override -String get reorderItemDown => r'Jù sí ilẹ'; - -@override -String get reorderItemLeft => r'Jù sí àrà'; - -@override -String get reorderItemRight => r'Jù sí òtútù'; - -@override -String get reorderItemToEnd => r'Jù sí ìbẹ̀jì'; - -@override -String get reorderItemToStart => r'Jù sí àkọ́kọ́'; - -@override -String get reorderItemUp => r'Jù sí ọ̀rùn'; - -@override -String get rowsPerPageTitle => r'Ìlò Fún àwọn Ìtọ́kasíwájú:'; - -@override -ScriptCategory get scriptCategory => ScriptCategory.englishLike; - -@override -String get searchFieldLabel => 'Ṣẹda'; - -@override -String get selectAllButtonLabel => 'FADỌHỌN DỌFÚN GBÁJÚMỌ̀'; - -@override -String? get selectedRowCountTitleFew => null; - -@override -String? get selectedRowCountTitleMany => null; - -@override -String get selectedRowCountTitleOne => '1 káyé'; - -@override -String get selectedRowCountTitleOther => r'$selectedRowCount káyé'; - -@override -String? get selectedRowCountTitleTwo => null; - -@override -String get selectedRowCountTitleZero => 'Kò sí káyé ti o wọlé'; - -@override -String get showAccountsLabel => 'Fi iyipada mu kọ'; - -@override -String get showMenuTooltip => 'Fi Meniu mu kọ'; - -@override -String get signedInLabel => 'Ọ̀nà'; - -@override -String get tabLabelRaw => r'Àwọn tabin $tabIndex lati $tabCount'; - @override -TimeOfDayFormat get timeOfDayFormatRaw => TimeOfDayFormat.h_colon_mm_space_a; - -@override -String get timePickerHourModeAnnouncement => 'Tuntun waqtu lọ'; - -@override -String get timePickerMinuteModeAnnouncement => 'Tuntun daɗi minti'; - -@override -String get viewLicensesButtonLabel => 'WO NIKI'; - -@override -List get narrowWeekdays => const ['L', 'L', 'A', 'O', 'Ọ', 'Ẹ', 'Ẹ']; - -@override -int get firstDayOfWeekIndex => 0; - -static const LocalizationsDelegate delegate = -_YoMaterialLocalizationsDelegate(); - -@override -String get calendarModeButtonLabel => 'Tọ́rọ̀ kálẹ̀ndà'; - -@override -String get dateHelpText => 'mm/dd/yyyy'; - -@override -String get dateInputLabel => 'Firanṣẹ̀ Ọjọ́'; - -@override -String get dateOutOfRangeLabel => 'Nínú iwọ̀ lọ́wọ́'; - -@override -String get datePickerHelpText => 'WÁSÍ'; - -@override -String get dateRangeEndDateSemanticLabelRaw => r'Ọjọ́ tuntun to ṣà'; - -@override -String get dateRangeEndLabel => 'Ọjọ́ tuntun to ṣà'; - -@override -String get dateRangePickerHelpText => 'WÁSÍ ÌGBÀ'; - -@override -String get dateRangeStartDateSemanticLabelRaw => 'Ọjọ́ tuntun ti dá'; - -@override -String get dateRangeStartLabel => 'Ọjọ́ tuntun ti dá'; - -@override -String get dateSeparator => '/'; - -@override -String get dialModeButtonLabel => 'Tọ́rọ̀ wakati'; - -@override -String get inputDateModeButtonLabel => 'Tọ́rọ̀ firanṣẹ̀ ọjọ́'; - -@override -String get inputTimeModeButtonLabel => 'Tọ́rọ̀ wakati bayi lọ́wọ́'; - -@override -String get invalidDateFormatLabel => 'Akọ́kọ́tọ́ tó jẹ́kúnrin'; - -@override -String get invalidDateRangeLabel => 'Àmì jẹ́ káàkiri lẹ́yìn ilé'; - -@override -String get invalidTimeLabel => 'Akọ́kọ́tọ́ àkójọ ìwádìí'; - -@override -String get licensesPackageDetailTextOther => r'$licenseCount àwọn níkí'; - -@override -String get saveButtonLabel => 'TÙN DÁRA'; - -@override -String get selectYearSemanticsLabel => 'Fọ́ọ̀ shẹ́kàrà'; - -@override -String get timePickerDialHelpText => 'WÁSÍ WÁKÀTÌ'; - -@override -String get timePickerHourLabel => 'Wákàtì àṣà'; - -@override -String get timePickerInputHelpText => 'Shìgárà wákàtì'; - -@override -String get timePickerMinuteLabel => 'Mìntì'; - -@override -String get unspecifiedDate => 'Ọjọ̀kúnrin'; - -@override -String get unspecifiedDateRange => 'Ọjọ̀kúnrin àdáyọ̀'; - -@override -String get keyboardKeyAlt => 'Alt'; - -@override -String get keyboardKeyAltGraph => 'AltGraph'; - -@override -String get keyboardKeyBackspace => 'Báckspàcè'; - -@override -String get keyboardKeyCapsLock => 'Caps Lock'; - -@override -String get keyboardKeyChannelDown => 'Báyàkàmmàlàsàké'; - -@override -String get keyboardKeyChannelUp => 'Yíkàmmàlàsàké'; - -@override -String get keyboardKeyControl => 'Kọ́ntírọ̀l'; - -@override -String get keyboardKeyDelete => 'Shápè'; - -@override -String get keyboardKeyEject => 'Èjẹ̀tì'; - -@override -String get keyboardKeyEnd => 'Tàbí'; - -@override -String get keyboardKeyEscape => 'Tòkè'; + String get pasteButtonLabel => r'TÌ'; @override -String get keyboardKeyFn => 'Fn'; + String get popupMenuLabel => r'Meniu Pop-up'; -@override -String get keyboardKeyHome => 'Ile'; + @override + String get menuBarMenuLabel => r'Meniu Akọkọ'; -@override -String get keyboardKeyInsert => 'Fi sori'; + @override + String get postMeridiemAbbreviation => r'PM'; -@override -String get keyboardKeyMeta => 'Meta'; + @override + String get previousMonthTooltip => r'Oṣu Kanakana'; -@override -String get keyboardKeyMetaMacOs => 'Amfani pẹlu Command'; + @override + String get previousPageTooltip => r'Ojú ewé akọkọ kan'; -@override -String get keyboardKeyMetaWindows => 'Windows'; + @override + String get refreshIndicatorSemanticLabel => r'Gbiyanju'; + + @override + String? get remainingTextFieldCharacterCountFew => null; + + @override + String? get remainingTextFieldCharacterCountMany => null; + + @override + String get remainingTextFieldCharacterCountOne => r'1 àmì báálẹ̀'; + + @override + String get remainingTextFieldCharacterCountOther => r'$remainingCount àmì báálẹ̀'; + + @override + String? get remainingTextFieldCharacterCountTwo => null; + + @override + String get remainingTextFieldCharacterCountZero => r'Kò sí ìwọlé létà láti ń ṣe'; + + @override + String get reorderItemDown => r'Jù sí ilẹ'; + + @override + String get reorderItemLeft => r'Jù sí àrà'; + + @override + String get reorderItemRight => r'Jù sí òtútù'; + + @override + String get reorderItemToEnd => r'Jù sí ìbẹ̀jì'; + + @override + String get reorderItemToStart => r'Jù sí àkọ́kọ́'; + + @override + String get reorderItemUp => r'Jù sí ọ̀rùn'; + + @override + String get rowsPerPageTitle => r'Ìlò Fún àwọn Ìtọ́kasíwájú:'; + + @override + ScriptCategory get scriptCategory => ScriptCategory.englishLike; + + @override + String get searchFieldLabel => 'Ṣẹda'; + + @override + String get selectAllButtonLabel => 'FADỌHỌN DỌFÚN GBÁJÚMỌ̀'; + + @override + String? get selectedRowCountTitleFew => null; + + @override + String? get selectedRowCountTitleMany => null; + + @override + String get selectedRowCountTitleOne => '1 káyé'; + + @override + String get selectedRowCountTitleOther => r'$selectedRowCount káyé'; + + @override + String? get selectedRowCountTitleTwo => null; + + @override + String get selectedRowCountTitleZero => 'Kò sí káyé ti o wọlé'; + + @override + String get showAccountsLabel => 'Fi iyipada mu kọ'; + + @override + String get showMenuTooltip => 'Fi Meniu mu kọ'; + + @override + String get signedInLabel => 'Ọ̀nà'; + + @override + String get tabLabelRaw => r'Àwọn tabin $tabIndex lati $tabCount'; + + @override + TimeOfDayFormat get timeOfDayFormatRaw => TimeOfDayFormat.h_colon_mm_space_a; + + @override + String get timePickerHourModeAnnouncement => 'Tuntun waqtu lọ'; + + @override + String get timePickerMinuteModeAnnouncement => 'Tuntun daɗi minti'; + + @override + String get viewLicensesButtonLabel => 'WO NIKI'; + + @override + List get narrowWeekdays => const ['L', 'L', 'A', 'O', 'Ọ', 'Ẹ', 'Ẹ']; + + @override + int get firstDayOfWeekIndex => 0; + + static const LocalizationsDelegate delegate = + _YoMaterialLocalizationsDelegate(); + + @override + String get calendarModeButtonLabel => 'Tọ́rọ̀ kálẹ̀ndà'; + + @override + String get dateHelpText => 'mm/dd/yyyy'; + + @override + String get dateInputLabel => 'Firanṣẹ̀ Ọjọ́'; + + @override + String get dateOutOfRangeLabel => 'Nínú iwọ̀ lọ́wọ́'; + + @override + String get datePickerHelpText => 'WÁSÍ'; + + @override + String get dateRangeEndDateSemanticLabelRaw => r'Ọjọ́ tuntun to ṣà'; + + @override + String get dateRangeEndLabel => 'Ọjọ́ tuntun to ṣà'; + + @override + String get dateRangePickerHelpText => 'WÁSÍ ÌGBÀ'; + + @override + String get dateRangeStartDateSemanticLabelRaw => 'Ọjọ́ tuntun ti dá'; + + @override + String get dateRangeStartLabel => 'Ọjọ́ tuntun ti dá'; + + @override + String get dateSeparator => '/'; + + @override + String get dialModeButtonLabel => 'Tọ́rọ̀ wakati'; + + @override + String get inputDateModeButtonLabel => 'Tọ́rọ̀ firanṣẹ̀ ọjọ́'; + + @override + String get inputTimeModeButtonLabel => 'Tọ́rọ̀ wakati bayi lọ́wọ́'; + + @override + String get invalidDateFormatLabel => 'Akọ́kọ́tọ́ tó jẹ́kúnrin'; + + @override + String get invalidDateRangeLabel => 'Àmì jẹ́ káàkiri lẹ́yìn ilé'; + + @override + String get invalidTimeLabel => 'Akọ́kọ́tọ́ àkójọ ìwádìí'; + + @override + String get licensesPackageDetailTextOther => r'$licenseCount àwọn níkí'; + + @override + String get saveButtonLabel => 'TÙN DÁRA'; + + @override + String get selectYearSemanticsLabel => 'Fọ́ọ̀ shẹ́kàrà'; + + @override + String get timePickerDialHelpText => 'WÁSÍ WÁKÀTÌ'; + + @override + String get timePickerHourLabel => 'Wákàtì àṣà'; + + @override + String get timePickerInputHelpText => 'Shìgárà wákàtì'; + + @override + String get timePickerMinuteLabel => 'Mìntì'; + + @override + String get unspecifiedDate => 'Ọjọ̀kúnrin'; + + @override + String get unspecifiedDateRange => 'Ọjọ̀kúnrin àdáyọ̀'; + + @override + String get keyboardKeyAlt => 'Alt'; + + @override + String get keyboardKeyAltGraph => 'AltGraph'; + + @override + String get keyboardKeyBackspace => 'Báckspàcè'; + + @override + String get keyboardKeyCapsLock => 'Caps Lock'; + + @override + String get keyboardKeyChannelDown => 'Báyàkàmmàlàsàké'; + + @override + String get keyboardKeyChannelUp => 'Yíkàmmàlàsàké'; + + @override + String get keyboardKeyControl => 'Kọ́ntírọ̀l'; + + @override + String get keyboardKeyDelete => 'Shápè'; + + @override + String get keyboardKeyEject => 'Èjẹ̀tì'; + + @override + String get keyboardKeyEnd => 'Tàbí'; + + @override + String get keyboardKeyEscape => 'Tòkè'; + + @override + String get keyboardKeyFn => 'Fn'; + + @override + String get keyboardKeyHome => 'Ile'; + + @override + String get keyboardKeyInsert => 'Fi sori'; + + @override + String get keyboardKeyMeta => 'Meta'; + + @override + String get keyboardKeyMetaMacOs => 'Amfani pẹlu Command'; + + @override + String get keyboardKeyMetaWindows => 'Windows'; @override String get keyboardKeyNumLock => 'Num Lock'; @@ -751,6 +750,50 @@ String get keyboardKeyMetaWindows => 'Windows'; @override String get scrimOnTapHintRaw => "Scrip on Tap"; + + @override + // TODO: implement collapsedHint + String get collapsedHint => "collapsedHint"; + + @override + // TODO: implement expandedHint + String get expandedHint => "expandedHint"; + + @override + // TODO: implement expansionTileCollapsedHint + String get expansionTileCollapsedHint => "expansionTileCollapsedHint"; + + @override + // TODO: implement expansionTileCollapsedTapHint + String get expansionTileCollapsedTapHint => "expansionTileCollapsedTapHint"; + + @override + // TODO: implement expansionTileExpandedHint + String get expansionTileExpandedHint => "expansionTileExpandedHint"; + + @override + // TODO: implement expansionTileExpandedTapHint + String get expansionTileExpandedTapHint => "expansionTileExpandedTapHint"; + + @override + // TODO: implement scanTextButtonLabel + String get scanTextButtonLabel => "scanTextButtonLabel"; + + @override + // TODO: implement lookUpButtonLabel + String get lookUpButtonLabel => "lookUpButtonLabel"; + + @override + // TODO: implement menuDismissLabel + String get menuDismissLabel => "menuDismissLabel"; + + @override + // TODO: implement searchWebButtonLabel + String get searchWebButtonLabel => "searchWebButtonLabel"; + + @override + // TODO: implement shareButtonLabel + String get shareButtonLabel => "shareButtonLabel"; } /// Cupertino Support @@ -821,138 +864,158 @@ class YoCupertinoLocalizations extends GlobalCupertinoLocalizations { required super.singleDigitSecondFormat, }); -@override -String get alertDialogLabel => 'Àdàkárò'; + @override + String get alertDialogLabel => 'Àdàkárò'; -@override -String get anteMeridiemAbbreviation => 'AM'; + @override + String get anteMeridiemAbbreviation => 'AM'; -@override -String get copyButtonLabel => 'Kòpy'; + @override + String get copyButtonLabel => 'Kòpy'; -@override -String get cutButtonLabel => 'Kọ́t'; + @override + String get cutButtonLabel => 'Kọ́t'; -@override -String get datePickerDateOrderString => 'mdy'; + @override + String get datePickerDateOrderString => 'mdy'; -@override -String get datePickerDateTimeOrderString => 'date_time_dayPeriod'; + @override + String get datePickerDateTimeOrderString => 'date_time_dayPeriod'; -@override -String? get datePickerHourSemanticsLabelFew => null; + @override + String? get datePickerHourSemanticsLabelFew => null; -@override -String? get datePickerHourSemanticsLabelMany => null; + @override + String? get datePickerHourSemanticsLabelMany => null; -@override -String? get datePickerHourSemanticsLabelOne => r"$hour o'clock"; + @override + String? get datePickerHourSemanticsLabelOne => r"$hour o'clock"; -@override -String get datePickerHourSemanticsLabelOther => r"$hour o'clock"; + @override + String get datePickerHourSemanticsLabelOther => r"$hour o'clock"; -@override -String? get datePickerHourSemanticsLabelTwo => null; + @override + String? get datePickerHourSemanticsLabelTwo => null; -@override -String? get datePickerHourSemanticsLabelZero => null; + @override + String? get datePickerHourSemanticsLabelZero => null; -@override -String? get datePickerMinuteSemanticsLabelFew => null; + @override + String? get datePickerMinuteSemanticsLabelFew => null; -@override -String? get datePickerMinuteSemanticsLabelMany => null; + @override + String? get datePickerMinuteSemanticsLabelMany => null; -@override -String? get datePickerMinuteSemanticsLabelOne => '1 wakati'; + @override + String? get datePickerMinuteSemanticsLabelOne => '1 wakati'; -@override -String get datePickerMinuteSemanticsLabelOther => r'$minute wakati'; + @override + String get datePickerMinuteSemanticsLabelOther => r'$minute wakati'; -@override -String? get datePickerMinuteSemanticsLabelTwo => null; + @override + String? get datePickerMinuteSemanticsLabelTwo => null; -@override -String? get datePickerMinuteSemanticsLabelZero => null; + @override + String? get datePickerMinuteSemanticsLabelZero => null; -@override -String get modalBarrierDismissLabel => 'Búta'; + @override + String get modalBarrierDismissLabel => 'Búta'; -@override -String get pasteButtonLabel => 'Tẹ́ẹ́'; + @override + String get pasteButtonLabel => 'Tẹ́ẹ́'; -@override -String get postMeridiemAbbreviation => 'PM'; + @override + String get postMeridiemAbbreviation => 'PM'; -@override -String get searchTextFieldPlaceholderLabel => 'Wúró àtúntà'; + @override + String get searchTextFieldPlaceholderLabel => 'Wúró àtúntà'; -@override -String get selectAllButtonLabel => 'Fírànsé gbógbo'; + @override + String get selectAllButtonLabel => 'Fírànsé gbógbo'; -@override -String get tabSemanticsLabelRaw => r'Tab $tabIndex nínú $tabCount'; + @override + String get tabSemanticsLabelRaw => r'Tab $tabIndex nínú $tabCount'; -@override -String? get timerPickerHourLabelFew => null; + @override + String? get timerPickerHourLabelFew => null; -@override -String? get timerPickerHourLabelMany => null; + @override + String? get timerPickerHourLabelMany => null; -@override -String? get timerPickerHourLabelOne => 'òǹdì'; + @override + String? get timerPickerHourLabelOne => 'òǹdì'; -@override -String get timerPickerHourLabelOther => 'òǹdì'; + @override + String get timerPickerHourLabelOther => 'òǹdì'; -@override -String? get timerPickerHourLabelTwo => null; + @override + String? get timerPickerHourLabelTwo => null; -@override -String? get timerPickerHourLabelZero => null; + @override + String? get timerPickerHourLabelZero => null; -@override -String? get timerPickerMinuteLabelFew => null; + @override + String? get timerPickerMinuteLabelFew => null; -@override -String? get timerPickerMinuteLabelMany => null; + @override + String? get timerPickerMinuteLabelMany => null; -@override -String? get timerPickerMinuteLabelOne => 'wakati.'; + @override + String? get timerPickerMinuteLabelOne => 'wakati.'; -@override -String get timerPickerMinuteLabelOther => 'wakati.'; + @override + String get timerPickerMinuteLabelOther => 'wakati.'; -@override -String? get timerPickerMinuteLabelTwo => null; + @override + String? get timerPickerMinuteLabelTwo => null; -@override -String? get timerPickerMinuteLabelZero => null; + @override + String? get timerPickerMinuteLabelZero => null; -@override -String? get timerPickerSecondLabelFew => null; + @override + String? get timerPickerSecondLabelFew => null; -@override -String? get timerPickerSecondLabelMany => null; + @override + String? get timerPickerSecondLabelMany => null; -@override -String? get timerPickerSecondLabelOne => 'dákìkà.'; + @override + String? get timerPickerSecondLabelOne => 'dákìkà.'; -@override -String get timerPickerSecondLabelOther => 'dákìkà.'; + @override + String get timerPickerSecondLabelOther => 'dákìkà.'; -@override -String? get timerPickerSecondLabelTwo => null; + @override + String? get timerPickerSecondLabelTwo => null; -@override -String? get timerPickerSecondLabelZero => null; + @override + String? get timerPickerSecondLabelZero => null; -@override -String get todayLabel => 'Oyọ'; + @override + String get todayLabel => 'Oyọ'; static const LocalizationsDelegate delegate = _YoCupertinoLocalizationsDelegate(); @override String get noSpellCheckReplacementsLabel => ""; -} \ No newline at end of file + + @override + // TODO: implement clearButtonLabel + String get clearButtonLabel => "clearButtonLabel"; + + @override + // TODO: implement lookUpButtonLabel + String get lookUpButtonLabel => "lookUpButtonLabel"; + + @override + // TODO: implement menuDismissLabel + String get menuDismissLabel => "menuDismissLabel"; + + @override + // TODO: implement searchWebButtonLabel + String get searchWebButtonLabel => "searchWebButtonLabel"; + + @override + // TODO: implement shareButtonLabel + String get shareButtonLabel => "shareButtonLabel"; +} diff --git a/lib/main.dart b/lib/main.dart index b274c7a84..b2e32d7a9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -41,6 +41,7 @@ import 'package:uni_links/uni_links.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cw_core/cake_hive.dart'; +import 'package:cw_core/window_size.dart'; final navigatorKey = GlobalKey(); final rootKey = GlobalKey(); @@ -60,6 +61,8 @@ Future main() async { return true; }; + await setDefaultMinimumWindowSize(); + await CakeHive.close(); await initializeAppConfigs(); diff --git a/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart b/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart index aa7012ae5..f8f92dc08 100644 --- a/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart +++ b/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart @@ -22,7 +22,7 @@ class DropDownItemWidget extends StatelessWidget { child: Text( title, style: TextStyle( - fontSize: 22, + fontSize: 18, fontWeight: FontWeight.w500, color: Theme.of(context).extension()!.titleColor, ), diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index d9e119038..c4e4aa199 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -330,10 +330,12 @@ class ExchangePage extends BasePage { void applyTemplate( BuildContext context, ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async { - exchangeViewModel.changeDepositCurrency( - currency: CryptoCurrency.fromString(template.depositCurrency)); - exchangeViewModel.changeReceiveCurrency( - currency: CryptoCurrency.fromString(template.receiveCurrency)); + + final depositCryptoCurrency = CryptoCurrency.fromString(template.depositCurrency); + final receiveCryptoCurrency = CryptoCurrency.fromString(template.receiveCurrency); + + exchangeViewModel.changeDepositCurrency(currency: depositCryptoCurrency); + exchangeViewModel.changeReceiveCurrency(currency: receiveCryptoCurrency); exchangeViewModel.changeDepositAmount(amount: template.amount); exchangeViewModel.depositAddress = template.depositAddress; @@ -342,12 +344,10 @@ class ExchangePage extends BasePage { exchangeViewModel.isFixedRateMode = false; var domain = template.depositAddress; - var ticker = template.depositCurrency.toLowerCase(); - exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, depositCryptoCurrency); domain = template.receiveAddress; - ticker = template.receiveCurrency.toLowerCase(); - exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, receiveCryptoCurrency); } void _setReactions(BuildContext context, ExchangeViewModel exchangeViewModel) { @@ -519,16 +519,14 @@ class ExchangePage extends BasePage { _depositAddressFocus.addListener(() async { if (!_depositAddressFocus.hasFocus && depositAddressController.text.isNotEmpty) { final domain = depositAddressController.text; - final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); - exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); } }); _receiveAddressFocus.addListener(() async { if (!_receiveAddressFocus.hasFocus && receiveAddressController.text.isNotEmpty) { final domain = receiveAddressController.text; - final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); - exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); } }); @@ -575,8 +573,8 @@ class ExchangePage extends BasePage { } } - Future fetchParsedAddress(BuildContext context, String domain, String ticker) async { - final parsedAddress = await getIt.get().resolve(context, domain, ticker); + Future fetchParsedAddress(BuildContext context, String domain, CryptoCurrency currency) async { + final parsedAddress = await getIt.get().resolve(context, domain, currency); final address = await extractAddressFromParsed(context, parsedAddress); return address; } @@ -663,15 +661,13 @@ class ExchangePage extends BasePage { addressTextFieldValidator: AddressValidator(type: exchangeViewModel.depositCurrency), onPushPasteButton: (context) async { final domain = exchangeViewModel.depositAddress; - final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); }, onPushAddressBookButton: (context) async { final domain = exchangeViewModel.depositAddress; - final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); }, )); @@ -712,15 +708,13 @@ class ExchangePage extends BasePage { addressTextFieldValidator: AddressValidator(type: exchangeViewModel.receiveCurrency), onPushPasteButton: (context) async { final domain = exchangeViewModel.receiveAddress; - final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); }, onPushAddressBookButton: (context) async { final domain = exchangeViewModel.receiveAddress; - final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); }, )); diff --git a/lib/src/screens/send/widgets/extract_address_from_parsed.dart b/lib/src/screens/send/widgets/extract_address_from_parsed.dart index eb997c11b..9ce3ca2b1 100644 --- a/lib/src/screens/send/widgets/extract_address_from_parsed.dart +++ b/lib/src/screens/send/widgets/extract_address_from_parsed.dart @@ -56,6 +56,11 @@ Future extractAddressFromParsed( profileImageUrl = parsedAddress.profileImageUrl; profileName = parsedAddress.profileName; break; + case ParseFrom.thorChain: + title = S.of(context).address_detected; + content = S.of(context).extracted_address_content('${parsedAddress.name} (ThorChain)'); + address = parsedAddress.addresses.first; + break; case ParseFrom.yatRecord: if (parsedAddress.name.isEmpty) { title = S.of(context).yat_error; diff --git a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart index 1d6168e4a..5355b7bb8 100644 --- a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart +++ b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart @@ -12,7 +12,6 @@ final _settingsNavigatorKey = GlobalKey(); class DesktopSettingsPage extends StatefulWidget { const DesktopSettingsPage({super.key}); - @override State createState() => _DesktopSettingsPageState(); } @@ -33,22 +32,21 @@ class _DesktopSettingsPageState extends State { return Scaffold( body: Container( height: MediaQuery.of(context).size.height, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + child: Row( children: [ - Padding( - padding: const EdgeInsets.all(24), - child: Text( - S.current.settings, - style: textXLarge(), - ), - ), Expanded( - child: Row( + flex: 1, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + Padding( + padding: const EdgeInsets.fromLTRB(24, 24, 24, 4), + child: Text( + S.current.settings, + style: textXLarge(), + ), + ), Expanded( - flex: 1, child: ListView.separated( padding: EdgeInsets.only(top: 0), itemBuilder: (_, index) { @@ -78,27 +76,27 @@ class _DesktopSettingsPageState extends State { itemCount: itemCount, ), ), - Flexible( - flex: 2, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 500), - child: Navigator( - key: _settingsNavigatorKey, - initialRoute: Routes.empty_no_route, - onGenerateRoute: (settings) => Router.createRoute(settings), - onGenerateInitialRoutes: - (NavigatorState navigator, String initialRouteName) { - return [ - navigator - .widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! - ]; - }, - ), - ), - ) ], ), ), + Flexible( + flex: 2, + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 500), + child: Navigator( + key: _settingsNavigatorKey, + initialRoute: Routes.empty_no_route, + onGenerateRoute: (settings) => Router.createRoute(settings), + onGenerateInitialRoutes: + (NavigatorState navigator, String initialRouteName) { + return [ + navigator + .widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! + ]; + }, + ), + ), + ) ], ), ), diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart index e559e9b15..1f0f58ad4 100644 --- a/lib/src/screens/settings/security_backup_page.dart +++ b/lib/src/screens/settings/security_backup_page.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/entities/pin_code_required_duration.dart'; import 'package:cake_wallet/routes.dart'; @@ -58,7 +60,7 @@ class SecurityBackupPage extends BasePage { .shouldRequireTOTP2FAForAllSecurityAndBackupSettings, ), ), - if (DeviceInfo.instance.isMobile) + if (DeviceInfo.instance.isMobile || Platform.isMacOS || Platform.isLinux) Observer(builder: (_) { return SettingsSwitcherCell( title: S.current.settings_allow_biometrical_authentication, diff --git a/lib/src/screens/settings/tor_page.dart b/lib/src/screens/settings/tor_page.dart index ae1ef1677..2f544be35 100644 --- a/lib/src/screens/settings/tor_page.dart +++ b/lib/src/screens/settings/tor_page.dart @@ -146,7 +146,7 @@ class ConnectScreen extends StatelessWidget { ElevatedButton( onPressed: connect, style: ElevatedButton.styleFrom( - primary: Colors.blue, + // primary: Colors.blue, padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), @@ -211,7 +211,7 @@ class DisconnectScreen extends StatelessWidget { ElevatedButton( onPressed: disconnect, style: ElevatedButton.styleFrom( - primary: Colors.red, + // primary: Colors.red, padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), diff --git a/lib/src/screens/support_chat/widgets/chatwoot_widget.dart b/lib/src/screens/support_chat/widgets/chatwoot_widget.dart index 2557761a7..60c9ea97f 100644 --- a/lib/src/screens/support_chat/widgets/chatwoot_widget.dart +++ b/lib/src/screens/support_chat/widgets/chatwoot_widget.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; @@ -58,7 +59,6 @@ class ChatwootWidgetState extends State { } Future storeCookie(String value) async { - await widget.secureStorage.delete(key: COOKIE_KEY); - await widget.secureStorage.write(key: COOKIE_KEY, value: value); + await writeSecureStorage(widget.secureStorage, key: COOKIE_KEY, value: value); } } diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index 4110c9883..a89d5e66f 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -175,7 +175,7 @@ class WalletListBodyState extends State { maxLines: null, softWrap: true, style: TextStyle( - fontSize: 20, + fontSize: DeviceInfo.instance.isDesktop ? 18 : 20, fontWeight: FontWeight.w500, color: Theme.of(context) .extension()! diff --git a/lib/src/widgets/validable_annotated_editable_text.dart b/lib/src/widgets/validable_annotated_editable_text.dart index 16ccc76f6..134eb16a8 100644 --- a/lib/src/widgets/validable_annotated_editable_text.dart +++ b/lib/src/widgets/validable_annotated_editable_text.dart @@ -1,8 +1,14 @@ -import 'package:cake_wallet/core/seed_validator.dart'; -import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; -class Annotation extends Comparable { + +extension Compare on Comparable { + bool operator <=(T other) => compareTo(other) <= 0; + bool operator >=(T other) => compareTo(other) >= 0; + bool operator <(T other) => compareTo(other) < 0; + bool operator >(T other) => compareTo(other) > 0; +} + +class Annotation implements Comparable { Annotation({required this.range, required this.style}); final TextRange range; @@ -12,7 +18,7 @@ class Annotation extends Comparable { int compareTo(Annotation other) => range.start.compareTo(other.range.start); } -class TextAnnotation extends Comparable { +class TextAnnotation implements Comparable { TextAnnotation({required this.text, required this.style}); final TextStyle style; diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 607551827..cd9b44391 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart'; import 'package:cake_wallet/entities/provider_types.dart'; import 'package:cake_wallet/entities/cake_2fa_preset_options.dart'; @@ -434,79 +435,83 @@ abstract class SettingsStoreBase with Store { // secure storage keys: reaction( (_) => allowBiometricalAuthentication, - (bool biometricalAuthentication) => secureStorage.write( + (bool biometricalAuthentication) => writeSecureStorage(secureStorage, key: SecureKey.allowBiometricalAuthenticationKey, value: biometricalAuthentication.toString())); reaction( (_) => selectedCake2FAPreset, - (Cake2FAPresetsOptions selectedCake2FAPreset) => secureStorage.write( + (Cake2FAPresetsOptions selectedCake2FAPreset) => writeSecureStorage(secureStorage, key: SecureKey.selectedCake2FAPreset, value: selectedCake2FAPreset.serialize().toString())); reaction( (_) => shouldRequireTOTP2FAForAccessingWallet, - (bool requireTOTP2FAForAccessingWallet) => secureStorage.write( + (bool requireTOTP2FAForAccessingWallet) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForAccessingWallet, value: requireTOTP2FAForAccessingWallet.toString())); reaction( (_) => shouldRequireTOTP2FAForSendsToContact, - (bool requireTOTP2FAForSendsToContact) => secureStorage.write( + (bool requireTOTP2FAForSendsToContact) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForSendsToContact, value: requireTOTP2FAForSendsToContact.toString())); reaction( (_) => shouldRequireTOTP2FAForSendsToNonContact, - (bool requireTOTP2FAForSendsToNonContact) => secureStorage.write( + (bool requireTOTP2FAForSendsToNonContact) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact, value: requireTOTP2FAForSendsToNonContact.toString())); reaction( (_) => shouldRequireTOTP2FAForSendsToInternalWallets, - (bool requireTOTP2FAForSendsToInternalWallets) => secureStorage.write( + (bool requireTOTP2FAForSendsToInternalWallets) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets, value: requireTOTP2FAForSendsToInternalWallets.toString())); reaction( (_) => shouldRequireTOTP2FAForExchangesToInternalWallets, - (bool requireTOTP2FAForExchangesToInternalWallets) => secureStorage.write( + (bool requireTOTP2FAForExchangesToInternalWallets) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets, value: requireTOTP2FAForExchangesToInternalWallets.toString())); reaction( (_) => shouldRequireTOTP2FAForExchangesToExternalWallets, - (bool requireTOTP2FAForExchangesToExternalWallets) => secureStorage.write( + (bool requireTOTP2FAForExchangesToExternalWallets) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets, value: requireTOTP2FAForExchangesToExternalWallets.toString())); reaction( (_) => shouldRequireTOTP2FAForAddingContacts, - (bool requireTOTP2FAForAddingContacts) => secureStorage.write( + (bool requireTOTP2FAForAddingContacts) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForAddingContacts, value: requireTOTP2FAForAddingContacts.toString())); reaction( (_) => shouldRequireTOTP2FAForCreatingNewWallets, - (bool requireTOTP2FAForCreatingNewWallets) => secureStorage.write( + (bool requireTOTP2FAForCreatingNewWallets) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets, value: requireTOTP2FAForCreatingNewWallets.toString())); reaction( (_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings, - (bool requireTOTP2FAForAllSecurityAndBackupSettings) => secureStorage.write( + (bool requireTOTP2FAForAllSecurityAndBackupSettings) => writeSecureStorage(secureStorage, key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings, value: requireTOTP2FAForAllSecurityAndBackupSettings.toString())); - reaction((_) => useTOTP2FA, - (bool use) => secureStorage.write(key: SecureKey.useTOTP2FA, value: use.toString())); + reaction( + (_) => useTOTP2FA, + (bool use) => + writeSecureStorage(secureStorage, key: SecureKey.useTOTP2FA, value: use.toString())); - reaction((_) => totpSecretKey, - (String totpKey) => secureStorage.write(key: SecureKey.totpSecretKey, value: totpKey)); + reaction( + (_) => totpSecretKey, + (String totpKey) => + writeSecureStorage(secureStorage, key: SecureKey.totpSecretKey, value: totpKey)); reaction( (_) => pinTimeOutDuration, - (PinCodeRequiredDuration pinCodeInterval) => secureStorage.write( + (PinCodeRequiredDuration pinCodeInterval) => writeSecureStorage(secureStorage, key: SecureKey.pinTimeOutDuration, value: pinCodeInterval.value.toString())); reaction( diff --git a/lib/view_model/auth_view_model.dart b/lib/view_model/auth_view_model.dart index 4fb93cfea..6f6e29662 100644 --- a/lib/view_model/auth_view_model.dart +++ b/lib/view_model/auth_view_model.dart @@ -106,14 +106,10 @@ abstract class AuthViewModelBase with Store { @action Future biometricAuth() async { try { - final canBiometricAuth = await _biometricAuth.canCheckBiometrics(); - - if (canBiometricAuth) { - final isAuthenticated = await _biometricAuth.isAuthenticated(); - - if (isAuthenticated) { - state = ExecutedSuccessfullyState(); - } + if (await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated()) { + state = ExecutedSuccessfullyState(); + } else { + throw Exception('Biometric authentication failed'); } } catch (e) { state = FailureState(e.toString()); diff --git a/lib/view_model/edit_backup_password_view_model.dart b/lib/view_model/edit_backup_password_view_model.dart index aca76502a..729551e74 100644 --- a/lib/view_model/edit_backup_password_view_model.dart +++ b/lib/view_model/edit_backup_password_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:mobx/mobx.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cake_wallet/entities/secret_store_key.dart'; @@ -37,8 +38,7 @@ abstract class EditBackupPasswordViewModelBase with Store { @action Future save() async { final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword); - await secureStorage.delete(key: key); - await secureStorage.write(key: key, value: backupPassword); + await writeSecureStorage(secureStorage, key: key, value: backupPassword); secretStore.write(key: key, value: backupPassword); } } diff --git a/lib/view_model/send/output.dart b/lib/view_model/send/output.dart index a79baea48..d6f2589c1 100644 --- a/lib/view_model/send/output.dart +++ b/lib/view_model/send/output.dart @@ -296,8 +296,8 @@ abstract class OutputBase with Store { Future fetchParsedAddress(BuildContext context) async { final domain = address; - final ticker = cryptoCurrencyHandler().title.toLowerCase(); - parsedAddress = await getIt.get().resolve(context, domain, ticker); + final currency = cryptoCurrencyHandler(); + parsedAddress = await getIt.get().resolve(context, domain, currency); extractedAddress = await extractAddressFromParsed(context, parsedAddress); note = parsedAddress.description; } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 8cdca5953..635d43d53 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -247,7 +247,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor wallet.type != WalletType.banano && wallet.type != WalletType.solana && wallet.type != WalletType.tron; - + @observable CryptoCurrency selectedCryptoCurrency; @@ -363,7 +363,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor } catch (e) { if (e is LedgerException) { final errorCode = e.errorCode.toRadixString(16); - final fallbackMsg = e.message.isNotEmpty ? e.message : "Unexpected Ledger Error Code: $errorCode"; + final fallbackMsg = + e.message.isNotEmpty ? e.message : "Unexpected Ledger Error Code: $errorCode"; final errorMsg = ledgerViewModel.interpretErrorCode(errorCode) ?? fallbackMsg; state = FailureState(errorMsg); @@ -444,7 +445,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor Object _credentials() { final priority = _settingsStore.priority[wallet.type]; - if (priority == null && wallet.type != WalletType.nano && wallet.type != WalletType.banano && wallet.type != WalletType.solana && + if (priority == null && + wallet.type != WalletType.nano && + wallet.type != WalletType.banano && + wallet.type != WalletType.solana && wallet.type != WalletType.tron) { throw Exception('Priority is null for wallet type: ${wallet.type}'); } @@ -570,6 +574,16 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor return errorMessage; } + if (walletType == WalletType.tron) { + if (errorMessage.contains('balance is not sufficient')) { + return S.current.do_not_have_enough_gas_asset(currency.toString()); + } + + if (errorMessage.contains('Transaction expired')) { + return 'An error occurred while processing the transaction. Kindly retry the transaction'; + } + } + if (walletType == WalletType.bitcoin || walletType == WalletType.litecoin || walletType == WalletType.bitcoinCash) { diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 75a78404f..51f61d9e3 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,6 +10,7 @@ import cw_monero import device_info_plus import devicelocale import flutter_inappwebview_macos +import flutter_local_authentication import flutter_secure_storage_macos import in_app_review import package_info @@ -26,6 +27,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) + FlutterLocalAuthenticationPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalAuthenticationPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin")) FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index b82513de2..f1f72a818 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -26,6 +26,8 @@ PODS: - flutter_inappwebview_macos (0.0.1): - FlutterMacOS - OrderedSet (~> 5.0) + - flutter_local_authentication (1.2.0): + - FlutterMacOS - flutter_secure_storage_macos (6.1.1): - FlutterMacOS - FlutterMacOS (1.0.0) @@ -56,6 +58,7 @@ DEPENDENCIES: - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`) - flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`) + - flutter_local_authentication (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_authentication/macos`) - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`) @@ -83,6 +86,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/devicelocale/macos flutter_inappwebview_macos: :path: Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos + flutter_local_authentication: + :path: Flutter/ephemeral/.symlinks/plugins/flutter_local_authentication/macos flutter_secure_storage_macos: :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos FlutterMacOS: @@ -110,6 +115,7 @@ SPEC CHECKSUMS: device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d + flutter_local_authentication: 85674893931e1c9cfa7c9e4f5973cb8c56b018b0 flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0 diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index 0c8973175..cd7f006e6 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -24,7 +24,21 @@ class AppDelegate: FlutterAppDelegate { } result(secRandom(count: count)) - + case "setMinWindowSize": + guard let self = self else { + result(false) + return + } + if let arguments = call.arguments as? [String: Any], + let width = arguments["width"] as? Double, + let height = arguments["height"] as? Double { + DispatchQueue.main.async { + self.mainFlutterWindow?.minSize = CGSize(width: width, height: height) + } + result(true) + } else { + result(false) + } default: result(FlutterMethodNotImplemented) } diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 63496057a..5e4115b02 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -26,15 +26,17 @@ dependencies: path_provider: ^2.0.11 mobx: ^2.1.4 flutter_mobx: ^2.0.6+5 - flutter_slidable: ^2.0.0 + flutter_slidable: ^3.0.1 share_plus: ^4.0.10 # date_range_picker: ^1.0.6 #https://api.flutter.dev/flutter/material/showDateRangePicker.html dio: ^4.0.6 hive: ^2.2.3 hive_flutter: ^1.1.0 - local_auth: ^2.1.0 local_auth_android: 1.0.21 + flutter_local_authentication: + git: + url: https://github.com/cake-tech/flutter_local_authentication package_info: ^2.0.0 #package_info_plus: ^1.4.2 devicelocale: diff --git a/pubspec_description.yaml b/pubspec_description.yaml index ebb6bf001..b51fe96d6 100644 --- a/pubspec_description.yaml +++ b/pubspec_description.yaml @@ -4,4 +4,4 @@ version: 0.0.0 publish_to: none environment: - sdk: ">=2.17.5 <3.0.0" \ No newline at end of file + sdk: ">=3.1.0 <4.0.0" \ No newline at end of file diff --git a/scripts/android/app_env.fish b/scripts/android/app_env.fish index be82ab9e6..2268fe4dc 100644 --- a/scripts/android/app_env.fish +++ b/scripts/android/app_env.fish @@ -15,15 +15,15 @@ set -l TYPES $MONERO_COM $CAKEWALLET $HAVEN set APP_ANDROID_TYPE $argv[1] set MONERO_COM_NAME "Monero.com" -set MONERO_COM_VERSION "1.10.0" -set MONERO_COM_BUILD_NUMBER 72 +set MONERO_COM_VERSION "1.12.3" +set MONERO_COM_BUILD_NUMBER 84 set MONERO_COM_BUNDLE_ID "com.monero.app" set MONERO_COM_PACKAGE "com.monero.app" set MONERO_COM_SCHEME "monero.com" set CAKEWALLET_NAME "Cake Wallet" -set CAKEWALLET_VERSION "4.13.0" -set CAKEWALLET_BUILD_NUMBER 189 +set CAKEWALLET_VERSION "4.15.6" +set CAKEWALLET_BUILD_NUMBER 207 set CAKEWALLET_BUNDLE_ID "com.cakewallet.cake_wallet" set CAKEWALLET_PACKAGE "com.cakewallet.cake_wallet" set CAKEWALLET_SCHEME "cakewallet"