From e92e8df3aaab119679f94d4561a0931d0a305a82 Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Mon, 13 May 2024 23:59:11 +0300
Subject: [PATCH 1/3] Generic enhancements (#1447)

* Disable hardware wallets for Monero.com

* disable ble permission on Monero.com

* code cleanup [skip ci]

* Fix missing Trade bytes issue
---
 assets/text/Monerocom_Release_Notes.txt       |   2 +-
 assets/text/Release_Notes.txt                 |   2 -
 cw_bitcoin/pubspec.lock                       |  72 ++++++---
 cw_core/pubspec.lock                          |  72 ++++++---
 cw_haven/pubspec.lock                         |  74 ++++++----
 cw_monero/example/pubspec.lock                |  66 ++++++---
 cw_monero/pubspec.lock                        |  74 ++++++----
 cw_nano/pubspec.lock                          |  72 ++++++---
 ios/Podfile.lock                              |   2 +-
 lib/exchange/trade.dart                       | 138 ++++++++++++++++--
 lib/main.dart                                 |  86 ++++-------
 .../screens/restore/restore_options_page.dart |  20 ++-
 lib/src/screens/root/root.dart                |   4 -
 .../hardware_wallet/ledger_view_model.dart    |  19 ++-
 scripts/android/app_env.sh                    |   8 +-
 scripts/ios/app_env.sh                        |   8 +-
 scripts/macos/app_env.sh                      |   8 +-
 17 files changed, 499 insertions(+), 228 deletions(-)

diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt
index d5297ebe1..faad67777 100644
--- a/assets/text/Monerocom_Release_Notes.txt
+++ b/assets/text/Monerocom_Release_Notes.txt
@@ -1 +1 @@
-Generic bug fixes and enhancements
\ No newline at end of file
+Bug fixes and generic enhancements
\ No newline at end of file
diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt
index f9b05cea2..faad67777 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,3 +1 @@
-Hardware wallets support for Bitcoin, Ethereum and Polygon
-Security enhancements
 Bug fixes and generic enhancements
\ No newline at end of file
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index a398a11e0..e6f0b34dd 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -217,10 +217,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:
@@ -446,6 +446,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:
@@ -483,26 +507,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:
@@ -547,10 +571,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:
@@ -736,26 +760,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:
@@ -784,10 +808,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:
@@ -820,8 +844,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"
@@ -861,5 +893,5 @@ packages:
     source: hosted
     version: "3.1.2"
 sdks:
-  dart: ">=3.0.6 <4.0.0"
+  dart: ">=3.2.0-0 <4.0.0"
   flutter: ">=3.10.0"
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_haven/pubspec.lock b/cw_haven/pubspec.lock
index d84523539..8aeb70a97 100644
--- a/cw_haven/pubspec.lock
+++ b/cw_haven/pubspec.lock
@@ -149,10 +149,10 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
+      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.2"
+    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: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
+      sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
       url: "https://pub.dev"
     source: hosted
-    version: "0.12.16"
+    version: "0.12.16+1"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
-      sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
       url: "https://pub.dev"
     source: hosted
-    version: "0.5.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:
@@ -571,18 +595,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:
@@ -611,10 +635,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
+      sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.0"
+    version: "0.6.1"
   timing:
     dependency: transitive
     description:
@@ -639,6 +663,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"
   watcher:
     dependency: "direct overridden"
     description:
@@ -647,14 +679,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.1.0"
-  web:
-    dependency: transitive
-    description:
-      name: web
-      sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.1.4-beta"
   web_socket_channel:
     dependency: transitive
     description:
@@ -688,5 +712,5 @@ packages:
     source: hosted
     version: "3.1.1"
 sdks:
-  dart: ">=3.1.0-185.0.dev <4.0.0"
+  dart: ">=3.2.0-0 <4.0.0"
   flutter: ">=3.7.0"
diff --git a/cw_monero/example/pubspec.lock b/cw_monero/example/pubspec.lock
index ece0d4395..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: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
+      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.2"
+    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: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
+      sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
       url: "https://pub.dev"
     source: hosted
-    version: "0.12.16"
+    version: "0.12.16+1"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
-      sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
       url: "https://pub.dev"
     source: hosted
-    version: "0.5.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:
@@ -362,18 +386,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"
   string_scanner:
     dependency: transitive
     description:
@@ -394,10 +418,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
+      sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.0"
+    version: "0.6.1"
   typed_data:
     dependency: transitive
     description:
@@ -414,14 +438,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.4"
-  web:
+  vm_service:
     dependency: transitive
     description:
-      name: web
-      sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
+      name: vm_service
+      sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
       url: "https://pub.dev"
     source: hosted
-    version: "0.1.4-beta"
+    version: "13.0.0"
   win32:
     dependency: transitive
     description:
@@ -439,5 +463,5 @@ packages:
     source: hosted
     version: "0.2.0+3"
 sdks:
-  dart: ">=3.1.0-185.0.dev <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 b736f80cb..adb50bd02 100644
--- a/cw_monero/pubspec.lock
+++ b/cw_monero/pubspec.lock
@@ -149,10 +149,10 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
+      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.2"
+    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: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
+      sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
       url: "https://pub.dev"
     source: hosted
-    version: "0.12.16"
+    version: "0.12.16+1"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
-      sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
       url: "https://pub.dev"
     source: hosted
-    version: "0.5.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:
@@ -595,18 +619,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:
@@ -635,10 +659,10 @@ packages:
     dependency: transitive
     description:
       name: test_api
-      sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
+      sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.0"
+    version: "0.6.1"
   timing:
     dependency: transitive
     description:
@@ -663,6 +687,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"
   watcher:
     dependency: "direct overridden"
     description:
@@ -671,14 +703,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.1.0"
-  web:
-    dependency: transitive
-    description:
-      name: web
-      sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.1.4-beta"
   web_socket_channel:
     dependency: transitive
     description:
@@ -712,5 +736,5 @@ packages:
     source: hosted
     version: "3.1.1"
 sdks:
-  dart: ">=3.1.0-185.0.dev <4.0.0"
+  dart: ">=3.2.0-0 <4.0.0"
   flutter: ">=3.7.0"
diff --git a/cw_nano/pubspec.lock b/cw_nano/pubspec.lock
index cbcf3d38d..2c2a342ca 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.7.0"
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 0cc57e075..c4ee98c37 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -307,7 +307,7 @@ SPEC CHECKSUMS:
   Toast: ec33c32b8688982cecc6348adeae667c1b9938da
   uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
   UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
-  url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586
+  url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
   wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
   workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
 
diff --git a/lib/exchange/trade.dart b/lib/exchange/trade.dart
index 6cc3fddbe..aeb544ece 100644
--- a/lib/exchange/trade.dart
+++ b/lib/exchange/trade.dart
@@ -5,9 +5,6 @@ import 'package:cw_core/format_amount.dart';
 import 'package:cw_core/hive_type_ids.dart';
 import 'package:hive/hive.dart';
 
-part 'trade.g.dart';
-
-@HiveType(typeId: Trade.typeId)
 class Trade extends HiveObject {
   Trade({
     required this.id,
@@ -32,6 +29,7 @@ class Trade extends HiveObject {
     this.txId,
     this.isRefund,
     this.isSendAll,
+    this.router,
   }) {
     if (provider != null) providerRaw = provider.raw;
 
@@ -121,21 +119,26 @@ class Trade extends HiveObject {
   @HiveField(21)
   bool? isSendAll;
 
+  @HiveField(22)
+  String? router;
+
   static Trade fromMap(Map<String, Object?> map) {
     return Trade(
-        id: map['id'] as String,
-        provider: ExchangeProviderDescription.deserialize(raw: map['provider'] as int),
-        from: CryptoCurrency.deserialize(raw: map['input'] as int),
-        to: CryptoCurrency.deserialize(raw: map['output'] as int),
-        createdAt:
-            map['date'] != null ? DateTime.fromMillisecondsSinceEpoch(map['date'] as int) : null,
-        amount: map['amount'] as String,
-        walletId: map['wallet_id'] as String,
-        fromWalletAddress: map['from_wallet_address'] as String?,
-        memo: map['memo'] as String?,
-        txId: map['tx_id'] as String?,
-        isRefund: map['isRefund'] as bool?,
-        isSendAll: map['isSendAll'] as bool?);
+      id: map['id'] as String,
+      provider: ExchangeProviderDescription.deserialize(raw: map['provider'] as int),
+      from: CryptoCurrency.deserialize(raw: map['input'] as int),
+      to: CryptoCurrency.deserialize(raw: map['output'] as int),
+      createdAt:
+          map['date'] != null ? DateTime.fromMillisecondsSinceEpoch(map['date'] as int) : null,
+      amount: map['amount'] as String,
+      walletId: map['wallet_id'] as String,
+      fromWalletAddress: map['from_wallet_address'] as String?,
+      memo: map['memo'] as String?,
+      txId: map['tx_id'] as String?,
+      isRefund: map['isRefund'] as bool?,
+      isSendAll: map['isSendAll'] as bool?,
+      router: map['router'] as String?,
+    );
   }
 
   Map<String, dynamic> toMap() {
@@ -152,8 +155,111 @@ class Trade extends HiveObject {
       'tx_id': txId,
       'isRefund': isRefund,
       'isSendAll': isSendAll,
+      'router': router,
     };
   }
 
   String amountFormatted() => formatAmount(amount);
 }
+
+class TradeAdapter extends TypeAdapter<Trade> {
+  @override
+  final int typeId = Trade.typeId;
+
+  @override
+  Trade read(BinaryReader reader) {
+    final numOfFields = reader.readByte();
+    final fields = <int, dynamic>{};
+    for (int i = 0; i < numOfFields; i++) {
+      try {
+        fields[reader.readByte()] = reader.read();
+      } catch (_) {}
+    }
+
+    return Trade(
+      id: fields[0] == null ? '' : fields[0] as String,
+      amount: fields[7] == null ? '' : fields[7] as String,
+      createdAt: fields[5] as DateTime?,
+      expiredAt: fields[6] as DateTime?,
+      inputAddress: fields[8] as String?,
+      extraId: fields[9] as String?,
+      outputTransaction: fields[10] as String?,
+      refundAddress: fields[11] as String?,
+      walletId: fields[12] as String?,
+      payoutAddress: fields[13] as String?,
+      password: fields[14] as String?,
+      providerId: fields[15] as String?,
+      providerName: fields[16] as String?,
+      fromWalletAddress: fields[17] as String?,
+      memo: fields[18] as String?,
+      txId: fields[19] as String?,
+      isRefund: fields[20] as bool?,
+      isSendAll: fields[21] as bool?,
+      router: fields[22] as String?,
+    )
+      ..providerRaw = fields[1] == null ? 0 : fields[1] as int
+      ..fromRaw = fields[2] == null ? 0 : fields[2] as int
+      ..toRaw = fields[3] == null ? 0 : fields[3] as int
+      ..stateRaw = fields[4] == null ? '' : fields[4] as String;
+  }
+
+  @override
+  void write(BinaryWriter writer, Trade obj) {
+    writer
+      ..writeByte(23)
+      ..writeByte(0)
+      ..write(obj.id)
+      ..writeByte(1)
+      ..write(obj.providerRaw)
+      ..writeByte(2)
+      ..write(obj.fromRaw)
+      ..writeByte(3)
+      ..write(obj.toRaw)
+      ..writeByte(4)
+      ..write(obj.stateRaw)
+      ..writeByte(5)
+      ..write(obj.createdAt)
+      ..writeByte(6)
+      ..write(obj.expiredAt)
+      ..writeByte(7)
+      ..write(obj.amount)
+      ..writeByte(8)
+      ..write(obj.inputAddress)
+      ..writeByte(9)
+      ..write(obj.extraId)
+      ..writeByte(10)
+      ..write(obj.outputTransaction)
+      ..writeByte(11)
+      ..write(obj.refundAddress)
+      ..writeByte(12)
+      ..write(obj.walletId)
+      ..writeByte(13)
+      ..write(obj.payoutAddress)
+      ..writeByte(14)
+      ..write(obj.password)
+      ..writeByte(15)
+      ..write(obj.providerId)
+      ..writeByte(16)
+      ..write(obj.providerName)
+      ..writeByte(17)
+      ..write(obj.fromWalletAddress)
+      ..writeByte(18)
+      ..write(obj.memo)
+      ..writeByte(19)
+      ..write(obj.txId)
+      ..writeByte(20)
+      ..write(obj.isRefund)
+      ..writeByte(21)
+      ..write(obj.isSendAll)
+      ..writeByte(22)
+      ..write(obj.router);
+  }
+
+  @override
+  int get hashCode => typeId.hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      identical(this, other) ||
+      other is TradeAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
+}
diff --git a/lib/main.dart b/lib/main.dart
index fa71da31d..f043b0cd2 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -5,7 +5,6 @@ import 'package:cake_wallet/core/secure_storage.dart';
 import 'package:cake_wallet/entities/language_service.dart';
 import 'package:cake_wallet/buy/order.dart';
 import 'package:cake_wallet/locales/locale.dart';
-import 'package:cake_wallet/store/yat/yat_store.dart';
 import 'package:cake_wallet/utils/device_info.dart';
 import 'package:cake_wallet/utils/exception_handler.dart';
 import 'package:cake_wallet/view_model/link_view_model.dart';
@@ -38,7 +37,6 @@ import 'package:cake_wallet/entities/template.dart';
 import 'package:cake_wallet/exchange/trade.dart';
 import 'package:cake_wallet/exchange/exchange_template.dart';
 import 'package:cake_wallet/src/screens/root/root.dart';
-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';
@@ -46,7 +44,7 @@ import 'package:cw_core/window_size.dart';
 
 final navigatorKey = GlobalKey<NavigatorState>();
 final rootKey = GlobalKey<RootState>();
-final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
+final RouteObserver<PageRoute<dynamic>> routeObserver = RouteObserver<PageRoute<dynamic>>();
 
 Future<void> main() async {
   await runZonedGuarded(() async {
@@ -63,13 +61,38 @@ Future<void> main() async {
     };
 
     await setDefaultMinimumWindowSize();
-    
+
     await CakeHive.close();
 
     await initializeAppConfigs();
 
     runApp(App());
   }, (error, stackTrace) async {
+    runApp(
+      MaterialApp(
+        debugShowCheckedModeBanner: false,
+        home: Scaffold(
+          body: SingleChildScrollView(
+            child: Container(
+              margin: EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
+              child: Column(
+                children: [
+                  Text(
+                    'Error:\n${error.toString()}',
+                    style: TextStyle(fontSize: 22),
+                  ),
+                  Text(
+                    'Stack trace:\n${stackTrace.toString()}',
+                    style: TextStyle(fontSize: 16),
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ),
+    );
+
     ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace));
   });
 }
@@ -229,61 +252,6 @@ class App extends StatefulWidget {
 }
 
 class AppState extends State<App> with SingleTickerProviderStateMixin {
-  AppState() : yatStore = getIt.get<YatStore>();
-
-  YatStore yatStore;
-  StreamSubscription? stream;
-
-  @override
-  void initState() {
-    super.initState();
-    //_handleIncomingLinks();
-    //_handleInitialUri();
-  }
-
-  Future<void> _handleInitialUri() async {
-    try {
-      final uri = await getInitialUri();
-      print('uri: $uri');
-      if (uri == null) {
-        return;
-      }
-      if (!mounted) return;
-      //_fetchEmojiFromUri(uri);
-    } catch (e) {
-      if (!mounted) return;
-      print(e.toString());
-    }
-  }
-
-  void _handleIncomingLinks() {
-    if (!kIsWeb) {
-      stream = getUriLinksStream().listen((Uri? uri) {
-        print('uri: $uri');
-        if (!mounted) return;
-        //_fetchEmojiFromUri(uri);
-      }, onError: (Object error) {
-        if (!mounted) return;
-        print('Error: $error');
-      });
-    }
-  }
-
-  void _fetchEmojiFromUri(Uri uri) {
-    //final queryParameters = uri.queryParameters;
-    //if (queryParameters?.isEmpty ?? true) {
-    //  return;
-    //}
-    //final emoji = queryParameters['eid'];
-    //final refreshToken = queryParameters['refresh_token'];
-    //if ((emoji?.isEmpty ?? true)||(refreshToken?.isEmpty ?? true)) {
-    //  return;
-    //}
-    //yatStore.emoji = emoji;
-    //yatStore.refreshToken = refreshToken;
-    //yatStore.emojiIncommingSC.add(emoji);
-  }
-
   @override
   Widget build(BuildContext context) {
     return Observer(builder: (BuildContext context) {
diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart
index 454d124da..a703c9f9e 100644
--- a/lib/src/screens/restore/restore_options_page.dart
+++ b/lib/src/screens/restore/restore_options_page.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
 import 'package:cake_wallet/core/execution_state.dart';
 import 'package:cake_wallet/di.dart';
 import 'package:cake_wallet/generated/i18n.dart';
@@ -13,6 +15,9 @@ import 'package:cake_wallet/utils/responsive_layout_util.dart';
 import 'package:cake_wallet/utils/show_pop_up.dart';
 import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
 import 'package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart';
+import 'package:cake_wallet/wallet_type_utils.dart';
+import 'package:cw_core/hardware/device_connection_type.dart';
+import 'package:cw_core/wallet_type.dart';
 import 'package:flutter/material.dart';
 import 'package:permission_handler/permission_handler.dart';
 
@@ -24,6 +29,19 @@ class RestoreOptionsPage extends BasePage {
 
   final bool isNewInstall;
 
+  bool get _doesSupportHardwareWallets {
+    if (!DeviceInfo.instance.isMobile) {
+      return false;
+    }
+
+    if (isMoneroOnly) {
+      return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS)
+          .isNotEmpty;
+    }
+
+    return true;
+  }
+
   @override
   Widget body(BuildContext context) {
     final imageColor = Theme.of(context).extension<OptionTileTheme>()!.titleColor;
@@ -57,7 +75,7 @@ class RestoreOptionsPage extends BasePage {
                       description: S.of(context).restore_description_from_backup,
                     ),
                   ),
-                if (DeviceInfo.instance.isMobile)
+                if (_doesSupportHardwareWallets)
                   Padding(
                     padding: EdgeInsets.only(top: 24),
                     child: OptionTile(
diff --git a/lib/src/screens/root/root.dart b/lib/src/screens/root/root.dart
index afdd14865..b6406dfbd 100644
--- a/lib/src/screens/root/root.dart
+++ b/lib/src/screens/root/root.dart
@@ -1,10 +1,7 @@
 import 'dart:async';
 import 'package:cake_wallet/core/auth_service.dart';
 import 'package:cake_wallet/core/totp_request_details.dart';
-import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cake_wallet/reactions/wallet_connect.dart';
 import 'package:cake_wallet/utils/device_info.dart';
-import 'package:cake_wallet/utils/payment_request.dart';
 import 'package:cake_wallet/view_model/link_view_model.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:flutter/material.dart';
@@ -13,7 +10,6 @@ import 'package:cake_wallet/src/screens/auth/auth_page.dart';
 import 'package:cake_wallet/store/app_store.dart';
 import 'package:cake_wallet/store/authentication_store.dart';
 import 'package:cake_wallet/entities/qr_scanner.dart';
-import 'package:fluttertoast/fluttertoast.dart';
 import 'package:mobx/mobx.dart';
 import 'package:uni_links/uni_links.dart';
 import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart
index 06ddaf275..f05b1c805 100644
--- a/lib/view_model/hardware_wallet/ledger_view_model.dart
+++ b/lib/view_model/hardware_wallet/ledger_view_model.dart
@@ -1,8 +1,12 @@
+import 'dart:io';
+
 import 'package:cake_wallet/bitcoin/bitcoin.dart';
 import 'package:cake_wallet/ethereum/ethereum.dart';
 import 'package:cake_wallet/generated/i18n.dart';
 import 'package:cake_wallet/polygon/polygon.dart';
 import 'package:cake_wallet/utils/device_info.dart';
+import 'package:cake_wallet/wallet_type_utils.dart';
+import 'package:cw_core/hardware/device_connection_type.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:ledger_flutter/ledger_flutter.dart';
@@ -11,8 +15,21 @@ import 'package:permission_handler/permission_handler.dart';
 class LedgerViewModel {
   late final Ledger ledger;
 
+  bool get _doesSupportHardwareWallets {
+    if (!DeviceInfo.instance.isMobile) {
+      return false;
+    }
+
+    if (isMoneroOnly) {
+      return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS)
+          .isNotEmpty;
+    }
+
+    return true;
+  }
+
   LedgerViewModel() {
-    if (DeviceInfo.instance.isMobile) {
+    if (_doesSupportHardwareWallets) {
       ledger = Ledger(
         options: LedgerOptions(
           scanMode: ScanMode.balanced,
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index c671a013f..3e5db68d2 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.13.0"
-MONERO_COM_BUILD_NUMBER=86
+MONERO_COM_VERSION="1.13.1"
+MONERO_COM_BUILD_NUMBER=87
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 MONERO_COM_SCHEME="monero.com"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.16.0"
-CAKEWALLET_BUILD_NUMBER=210
+CAKEWALLET_VERSION="4.16.1"
+CAKEWALLET_BUILD_NUMBER=211
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index f7887e4bf..c5a2e6306 100644
--- a/scripts/ios/app_env.sh
+++ b/scripts/ios/app_env.sh
@@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_IOS_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.13.0"
-MONERO_COM_BUILD_NUMBER=84
+MONERO_COM_VERSION="1.13.1"
+MONERO_COM_BUILD_NUMBER=85
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.16.0"
-CAKEWALLET_BUILD_NUMBER=236
+CAKEWALLET_VERSION="4.16.1"
+CAKEWALLET_BUILD_NUMBER=239
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index e16df1e61..ebe3115be 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
 fi
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.3.0"
-MONERO_COM_BUILD_NUMBER=17
+MONERO_COM_VERSION="1.3.1"
+MONERO_COM_BUILD_NUMBER=18
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.9.0"
-CAKEWALLET_BUILD_NUMBER=71
+CAKEWALLET_VERSION="1.9.1"
+CAKEWALLET_BUILD_NUMBER=72
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

From c12b4f5ff611810edf8e3668c0c26b25049ecada Mon Sep 17 00:00:00 2001
From: Omar Hatem <omarh.ismail1@gmail.com>
Date: Tue, 14 May 2024 04:27:16 +0300
Subject: [PATCH 2/3] improve error handling (#1451)

---
 lib/main.dart              | 45 +++++++++++++++++++++-----------------
 scripts/android/app_env.sh |  8 +++----
 scripts/ios/app_env.sh     |  8 +++----
 scripts/macos/app_env.sh   |  8 +++----
 4 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index f043b0cd2..eeee4fbc3 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -47,6 +47,7 @@ final rootKey = GlobalKey<RootState>();
 final RouteObserver<PageRoute<dynamic>> routeObserver = RouteObserver<PageRoute<dynamic>>();
 
 Future<void> main() async {
+  bool isAppRunning = false;
   await runZonedGuarded(() async {
     WidgetsFlutterBinding.ensureInitialized();
 
@@ -67,31 +68,35 @@ Future<void> main() async {
     await initializeAppConfigs();
 
     runApp(App());
+
+    isAppRunning = true;
   }, (error, stackTrace) async {
-    runApp(
-      MaterialApp(
-        debugShowCheckedModeBanner: false,
-        home: Scaffold(
-          body: SingleChildScrollView(
-            child: Container(
-              margin: EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
-              child: Column(
-                children: [
-                  Text(
-                    'Error:\n${error.toString()}',
-                    style: TextStyle(fontSize: 22),
-                  ),
-                  Text(
-                    'Stack trace:\n${stackTrace.toString()}',
-                    style: TextStyle(fontSize: 16),
-                  ),
-                ],
+    if (!isAppRunning) {
+      runApp(
+        MaterialApp(
+          debugShowCheckedModeBanner: false,
+          home: Scaffold(
+            body: SingleChildScrollView(
+              child: Container(
+                margin: EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
+                child: Column(
+                  children: [
+                    Text(
+                      'Error:\n${error.toString()}',
+                      style: TextStyle(fontSize: 22),
+                    ),
+                    Text(
+                      'Stack trace:\n${stackTrace.toString()}',
+                      style: TextStyle(fontSize: 16),
+                    ),
+                  ],
+                ),
               ),
             ),
           ),
         ),
-      ),
-    );
+      );
+    }
 
     ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace));
   });
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index 3e5db68d2..b520a3179 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_ANDROID_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.13.1"
-MONERO_COM_BUILD_NUMBER=87
+MONERO_COM_VERSION="1.13.2"
+MONERO_COM_BUILD_NUMBER=88
 MONERO_COM_BUNDLE_ID="com.monero.app"
 MONERO_COM_PACKAGE="com.monero.app"
 MONERO_COM_SCHEME="monero.com"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.16.1"
-CAKEWALLET_BUILD_NUMBER=211
+CAKEWALLET_VERSION="4.16.2"
+CAKEWALLET_BUILD_NUMBER=212
 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
 CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index c5a2e6306..f70963745 100644
--- a/scripts/ios/app_env.sh
+++ b/scripts/ios/app_env.sh
@@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
 APP_IOS_TYPE=$1
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.13.1"
-MONERO_COM_BUILD_NUMBER=85
+MONERO_COM_VERSION="1.13.2"
+MONERO_COM_BUILD_NUMBER=86
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.16.1"
-CAKEWALLET_BUILD_NUMBER=239
+CAKEWALLET_VERSION="4.16.2"
+CAKEWALLET_BUILD_NUMBER=240
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 HAVEN_NAME="Haven"
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index ebe3115be..afdac3e6c 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
 fi
 
 MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.3.1"
-MONERO_COM_BUILD_NUMBER=18
+MONERO_COM_VERSION="1.3.2"
+MONERO_COM_BUILD_NUMBER=19
 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
 
 CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.9.1"
-CAKEWALLET_BUILD_NUMBER=72
+CAKEWALLET_VERSION="1.9.2"
+CAKEWALLET_BUILD_NUMBER=73
 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
 
 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

From 4947e231e9afcd38267bab82617130067b1e857b Mon Sep 17 00:00:00 2001
From: Matthew Fosse <matt@fosse.co>
Date: Mon, 13 May 2024 19:07:16 -0700
Subject: [PATCH 3/3] Cw 613 quantex (#1377)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* save progress

* [skip ci]

* forgot to add [skip ci]

* not sure what exactly I changed but it just works now! ¯\_(ツ)_/¯

* status updates

* minor cleanup

* minor fix (toUppercase needed)

* remove unnecessary apikey + keep original raw values

* fix track url for quantex

* only increment raw values

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
---
 .github/workflows/pr_test_build.yml           |   1 +
 assets/images/quantex.png                     | Bin 0 -> 16353 bytes
 .../exchange_provider_description.dart        |  13 +-
 .../provider/quantex_exchange_provider.dart   | 252 ++++++++++++++++++
 lib/exchange/trade_state.dart                 |  27 ++
 .../exchange/exchange_trade_view_model.dart   |   4 +
 .../exchange/exchange_view_model.dart         |   2 +
 lib/view_model/trade_details_view_model.dart  |   6 +
 tool/utils/secret_key.dart                    |   1 +
 9 files changed, 301 insertions(+), 5 deletions(-)
 create mode 100644 assets/images/quantex.png
 create mode 100644 lib/exchange/provider/quantex_exchange_provider.dart

diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 69c632967..acaa12fe0 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -151,6 +151,7 @@ jobs:
           echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
           echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
           echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
+          echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
           echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
           echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
 
diff --git a/assets/images/quantex.png b/assets/images/quantex.png
new file mode 100644
index 0000000000000000000000000000000000000000..cfa32b3825a29161e38e708955bc96de3671098e
GIT binary patch
literal 16353
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
LQj)9@HwpP46BFQ5

literal 0
HcmV?d00001

diff --git a/lib/exchange/exchange_provider_description.dart b/lib/exchange/exchange_provider_description.dart
index 4d9691035..c28de5b72 100644
--- a/lib/exchange/exchange_provider_description.dart
+++ b/lib/exchange/exchange_provider_description.dart
@@ -22,10 +22,11 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
       ExchangeProviderDescription(title: 'Trocador', raw: 5, image: 'assets/images/trocador.png');
   static const exolix =
       ExchangeProviderDescription(title: 'Exolix', raw: 6, image: 'assets/images/exolix.png');
-  static const thorChain =
-  ExchangeProviderDescription(title: 'ThorChain' , raw: 8, image: 'assets/images/thorchain.png');
-
   static const all = ExchangeProviderDescription(title: 'All trades', raw: 7, image: '');
+  static const thorChain =
+      ExchangeProviderDescription(title: 'ThorChain', raw: 8, image: 'assets/images/thorchain.png');
+  static const quantex =
+      ExchangeProviderDescription(title: 'Quantex', raw: 9, image: 'assets/images/quantex.png');
 
   static ExchangeProviderDescription deserialize({required int raw}) {
     switch (raw) {
@@ -43,10 +44,12 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
         return trocador;
       case 6:
         return exolix;
-      case 8:
-        return thorChain;
       case 7:
         return all;
+      case 8:
+        return thorChain;
+      case 9:
+        return quantex;
       default:
         throw Exception('Unexpected token: $raw for ExchangeProviderDescription deserialize');
     }
diff --git a/lib/exchange/provider/quantex_exchange_provider.dart b/lib/exchange/provider/quantex_exchange_provider.dart
new file mode 100644
index 000000000..9ab7fbb55
--- /dev/null
+++ b/lib/exchange/provider/quantex_exchange_provider.dart
@@ -0,0 +1,252 @@
+import 'dart:convert';
+
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
+import 'package:cake_wallet/exchange/exchange_provider_description.dart';
+import 'package:cake_wallet/exchange/limits.dart';
+import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
+import 'package:cake_wallet/exchange/trade.dart';
+import 'package:cake_wallet/exchange/trade_not_created_exception.dart';
+import 'package:cake_wallet/exchange/trade_not_found_exception.dart';
+import 'package:cake_wallet/exchange/trade_request.dart';
+import 'package:cake_wallet/exchange/trade_state.dart';
+import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
+import 'package:cw_core/crypto_currency.dart';
+import 'package:http/http.dart';
+
+class QuantexExchangeProvider extends ExchangeProvider {
+  QuantexExchangeProvider() : super(pairList: supportedPairs(_notSupported));
+
+  static final List<CryptoCurrency> _notSupported = [
+    ...(CryptoCurrency.all
+        .where((element) => ![
+              CryptoCurrency.btc,
+              CryptoCurrency.sol,
+              CryptoCurrency.eth,
+              CryptoCurrency.ltc,
+              CryptoCurrency.ada,
+              CryptoCurrency.bch,
+              CryptoCurrency.usdt,
+              CryptoCurrency.bnb,
+              CryptoCurrency.xmr,
+            ].contains(element))
+        .toList())
+  ];
+
+  static final markup = secrets.quantexExchangeMarkup;
+
+  static const apiAuthority = 'api.myquantex.com';
+  static const getRate = '/api/swap/get-rate';
+  static const getCoins = '/api/swap/get-coins';
+  static const createOrder = '/api/swap/create-order';
+
+  @override
+  String get title => 'Quantex';
+
+  @override
+  bool get isAvailable => true;
+
+  @override
+  bool get isEnabled => true;
+
+  @override
+  bool get supportsFixedRate => false;
+
+  @override
+  ExchangeProviderDescription get description => ExchangeProviderDescription.quantex;
+
+  @override
+  Future<bool> checkIsAvailable() async => true;
+
+  @override
+  Future<Limits> fetchLimits({
+    required CryptoCurrency from,
+    required CryptoCurrency to,
+    required bool isFixedRateMode,
+  }) async {
+    try {
+      final uri = Uri.https(apiAuthority, getCoins);
+      final response = await get(uri);
+
+      final responseJSON = json.decode(response.body) as Map<String, dynamic>;
+
+      if (response.statusCode != 200)
+        throw Exception('Unexpected http status: ${response.statusCode}');
+
+      final coinsInfo = responseJSON['data'] as List<dynamic>;
+
+      for (var coin in coinsInfo) {
+        if (coin['id'].toString().toUpperCase() == _normalizeCurrency(from)) {
+          return Limits(
+            min: double.parse(coin['min'].toString()),
+            max: double.parse(coin['max'].toString()),
+          );
+        }
+      }
+
+      // coin not found:
+      return Limits(min: 0, max: 0);
+    } catch (e) {
+      print(e.toString());
+      return Limits(min: 0, max: 0);
+    }
+  }
+
+  @override
+  Future<double> fetchRate({
+    required CryptoCurrency from,
+    required CryptoCurrency to,
+    required double amount,
+    required bool isFixedRateMode,
+    required bool isReceiveAmount,
+  }) async {
+    try {
+      if (amount == 0) return 0.0;
+
+      final headers = <String, String>{};
+      final params = <String, dynamic>{};
+      final body = <String, String>{
+        'coin_send': _normalizeCurrency(from),
+        'coin_receive': _normalizeCurrency(to),
+        'ref': 'cake',
+      };
+
+      final uri = Uri.https(apiAuthority, getRate, params);
+      final response = await post(uri, body: body, headers: headers);
+      final responseBody = json.decode(response.body) as Map<String, dynamic>;
+
+      if (response.statusCode != 200)
+        throw Exception('Unexpected http status: ${response.statusCode}');
+
+      final data = responseBody['data'] as Map<String, dynamic>;
+      double rate = double.parse(data['price'].toString());
+      return rate;
+    } catch (e) {
+      print("error fetching rate: ${e.toString()}");
+      return 0.0;
+    }
+  }
+
+  @override
+  Future<Trade> createTrade({
+    required TradeRequest request,
+    required bool isFixedRateMode,
+    required bool isSendAll,
+  }) async {
+    try {
+      final headers = <String, String>{};
+      final params = <String, dynamic>{};
+      var body = <String, dynamic>{
+        'coin_send': _normalizeCurrency(request.fromCurrency),
+        'coin_receive': _normalizeCurrency(request.toCurrency),
+        'amount_send': request.fromAmount,
+        'recipient': request.toAddress,
+        'ref': 'cake',
+        'markup': markup,
+      };
+
+      String? fromNetwork = _networkFor(request.fromCurrency);
+      String? toNetwork = _networkFor(request.toCurrency);
+      if (fromNetwork != null) body['coin_send_network'] = fromNetwork;
+      if (toNetwork != null) body['coin_receive_network'] = toNetwork;
+
+      final uri = Uri.https(apiAuthority, createOrder, params);
+      final response = await post(uri, body: body, headers: headers);
+      final responseBody = json.decode(response.body) as Map<String, dynamic>;
+
+      if (response.statusCode == 400 || responseBody["success"] == false) {
+        final error = responseBody['errors'][0]['msg'] as String;
+        throw TradeNotCreatedException(description, description: error);
+      }
+
+      if (response.statusCode != 200)
+        throw Exception('Unexpected http status: ${response.statusCode}');
+
+      final responseData = responseBody['data'] as Map<String, dynamic>;
+
+      return Trade(
+        id: responseData["order_id"] as String,
+        inputAddress: responseData["server_address"] as String,
+        amount: request.fromAmount,
+        from: request.fromCurrency,
+        to: request.toCurrency,
+        provider: description,
+        createdAt: DateTime.now(),
+        state: TradeState.created,
+        payoutAddress: request.toAddress,
+        isSendAll: isSendAll,
+      );
+    } catch (e) {
+      print("error creating trade: ${e.toString()}");
+      throw TradeNotCreatedException(description, description: e.toString());
+    }
+  }
+
+  @override
+  Future<Trade> findTradeById({required String id}) async {
+    try {
+      final headers = <String, String>{};
+      final params = <String, dynamic>{};
+      var body = <String, dynamic>{
+        'order_id': id,
+      };
+
+      final uri = Uri.https(apiAuthority, createOrder, params);
+      final response = await post(uri, body: body, headers: headers);
+      final responseBody = json.decode(response.body) as Map<String, dynamic>;
+
+      if (response.statusCode == 400 || responseBody["success"] == false) {
+        final error = responseBody['errors'][0]['msg'] as String;
+        throw TradeNotCreatedException(description, description: error);
+      }
+
+      if (response.statusCode != 200)
+        throw Exception('Unexpected http status: ${response.statusCode}');
+
+      final responseData = responseBody['data'] as Map<String, dynamic>;
+      final fromCurrency = responseData['coin_send'] as String;
+      final from = CryptoCurrency.fromString(fromCurrency);
+      final toCurrency = responseData['coin_receive'] as String;
+      final to = CryptoCurrency.fromString(toCurrency);
+      final inputAddress = responseData['server_address'] as String;
+      final status = responseData['status'] as String;
+      final state = TradeState.deserialize(raw: status);
+      final response_id = responseData['order_id'] as String;
+      final expectedSendAmount = responseData['amount_send'] as String;
+
+      return Trade(
+        id: response_id,
+        from: from,
+        to: to,
+        provider: description,
+        inputAddress: inputAddress,
+        amount: expectedSendAmount,
+        state: state,
+      );
+    } catch (e) {
+      print("error getting trade: ${e.toString()}");
+      throw TradeNotFoundException(
+        id,
+        provider: description,
+        description: e.toString(),
+      );
+    }
+  }
+
+  String _normalizeCurrency(CryptoCurrency currency) {
+    switch (currency) {
+      default:
+        return currency.title.toUpperCase();
+    }
+  }
+
+  String? _networkFor(CryptoCurrency currency) {
+    switch (currency) {
+      case CryptoCurrency.usdt:
+        return "USDT_ERC20";
+      case CryptoCurrency.bnb:
+        return "BNB_BSC";
+      default:
+        return null;
+    }
+  }
+}
diff --git a/lib/exchange/trade_state.dart b/lib/exchange/trade_state.dart
index 2c58a96f4..0a196835e 100644
--- a/lib/exchange/trade_state.dart
+++ b/lib/exchange/trade_state.dart
@@ -28,6 +28,7 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
       TradeState(raw: 'waitingAuthorization', title: 'Waiting authorization');
   static const failed = TradeState(raw: 'failed', title: 'Failed');
   static const completed = TradeState(raw: 'completed', title: 'Completed');
+  static const expired = TradeState(raw: 'expired', title: 'Expired');
   static const settling = TradeState(raw: 'settling', title: 'Settlement in progress');
   static const settled = TradeState(raw: 'settled', title: 'Settlement completed');
   static const wait = TradeState(raw: 'wait', title: 'Waiting');
@@ -39,7 +40,33 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
   static const exchanging = TradeState(raw: 'exchanging', title: 'Exchanging');
   static const sending = TradeState(raw: 'sending', title: 'Sending');
   static const success = TradeState(raw: 'success', title: 'Success');
+  
   static TradeState deserialize({required String raw}) {
+
+    switch (raw) {
+      case '1':
+        return unpaid;
+      case '2':
+        return paidUnconfirmed;
+      case '3':
+        return sending;
+      case '4':
+        return confirmed;
+      case '5':
+      case '6':
+        return exchanging;
+      case '7':
+        return sending;
+      case '8':
+        return complete;
+      case '9':
+        return expired;
+      case '10':
+        return underpaid;
+      case '11':
+        return failed;
+    }
+
     switch (raw) {
       case 'NOT_FOUND':
         return notFound;
diff --git a/lib/view_model/exchange/exchange_trade_view_model.dart b/lib/view_model/exchange/exchange_trade_view_model.dart
index 94fec2fa2..c5ce7a591 100644
--- a/lib/view_model/exchange/exchange_trade_view_model.dart
+++ b/lib/view_model/exchange/exchange_trade_view_model.dart
@@ -4,6 +4,7 @@ import 'package:cake_wallet/exchange/exchange_provider_description.dart';
 import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
+import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
@@ -48,6 +49,9 @@ abstract class ExchangeTradeViewModelBase with Store {
       case ExchangeProviderDescription.exolix:
         _provider = ExolixExchangeProvider();
         break;
+      case ExchangeProviderDescription.quantex:
+        _provider = QuantexExchangeProvider();
+        break;
       case ExchangeProviderDescription.thorChain:
         _provider = ThorChainExchangeProvider(tradesStore: trades);
         break;
diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart
index e5533f48a..1560a4be0 100644
--- a/lib/view_model/exchange/exchange_view_model.dart
+++ b/lib/view_model/exchange/exchange_view_model.dart
@@ -30,6 +30,7 @@ import 'package:cake_wallet/exchange/limits_state.dart';
 import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
+import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
@@ -157,6 +158,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
             useTorOnly: _useTorOnly, providerStates: _settingsStore.trocadorProviderStates),
         ThorChainExchangeProvider(tradesStore: trades),
         if (FeatureFlag.isExolixEnabled) ExolixExchangeProvider(),
+        QuantexExchangeProvider(),
       ];
 
   @observable
diff --git a/lib/view_model/trade_details_view_model.dart b/lib/view_model/trade_details_view_model.dart
index 1da322778..c88008982 100644
--- a/lib/view_model/trade_details_view_model.dart
+++ b/lib/view_model/trade_details_view_model.dart
@@ -4,6 +4,7 @@ import 'package:cake_wallet/exchange/exchange_provider_description.dart';
 import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
+import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
 import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
@@ -56,6 +57,9 @@ abstract class TradeDetailsViewModelBase with Store {
       case ExchangeProviderDescription.thorChain:
         _provider = ThorChainExchangeProvider(tradesStore: trades);
         break;
+      case ExchangeProviderDescription.quantex:
+        _provider = QuantexExchangeProvider();
+        break;
     }
 
     _updateItems();
@@ -80,6 +84,8 @@ abstract class TradeDetailsViewModelBase with Store {
         return 'https://exolix.com/transaction/${trade.id}';
       case ExchangeProviderDescription.thorChain:
         return 'https://track.ninerealms.com/${trade.id}';
+      case ExchangeProviderDescription.quantex:
+        return 'https://myquantex.com/send/${trade.id}';
     }
     return null;
   }
diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart
index 89e4de12d..9559e83b3 100644
--- a/tool/utils/secret_key.dart
+++ b/tool/utils/secret_key.dart
@@ -38,6 +38,7 @@ class SecretKey {
     SecretKey('walletConnectProjectId', () => ''),
     SecretKey('moralisApiKey', () => ''),
     SecretKey('ankrApiKey', () => ''),
+    SecretKey('quantexExchangeMarkup', () => ''),
   ];
 
   static final evmChainsSecrets = [