From e92e8df3aaab119679f94d4561a0931d0a305a82 Mon Sep 17 00:00:00 2001 From: Omar Hatem 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 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 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 { + @override + final int typeId = Trade.typeId; + + @override + Trade read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = {}; + 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(); final rootKey = GlobalKey(); -final RouteObserver routeObserver = RouteObserver(); +final RouteObserver> routeObserver = RouteObserver>(); Future main() async { await runZonedGuarded(() async { @@ -63,13 +61,38 @@ Future 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 with SingleTickerProviderStateMixin { - AppState() : yatStore = getIt.get(); - - YatStore yatStore; - StreamSubscription? stream; - - @override - void initState() { - super.initState(); - //_handleIncomingLinks(); - //_handleInitialUri(); - } - - Future _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()!.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 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(); final RouteObserver> routeObserver = RouteObserver>(); Future main() async { + bool isAppRunning = false; await runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); @@ -67,31 +68,35 @@ Future 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 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 --- .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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 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 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 _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 checkIsAvailable() async => true; + + @override + Future 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; + + if (response.statusCode != 200) + throw Exception('Unexpected http status: ${response.statusCode}'); + + final coinsInfo = responseJSON['data'] as List; + + 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 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 = {}; + final params = {}; + final body = { + '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; + + if (response.statusCode != 200) + throw Exception('Unexpected http status: ${response.statusCode}'); + + final data = responseBody['data'] as Map; + double rate = double.parse(data['price'].toString()); + return rate; + } catch (e) { + print("error fetching rate: ${e.toString()}"); + return 0.0; + } + } + + @override + Future createTrade({ + required TradeRequest request, + required bool isFixedRateMode, + required bool isSendAll, + }) async { + try { + final headers = {}; + final params = {}; + var body = { + '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; + + 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; + + 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 findTradeById({required String id}) async { + try { + final headers = {}; + final params = {}; + var body = { + '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; + + 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; + 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 with Serializable { 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 with Serializable { 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 = [