diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index 471c8ee03..c8827d545 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -164,7 +164,11 @@ jobs: - name: Send Test APK continue-on-error: true - run: | - cd /opt/android/cake_wallet - var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk -H "Max-Days: 10") - curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}' + uses: adrey/slack-file-upload-action@1.0.5 + with: + token: ${{ secrets.SLACK_APP_TOKEN }} + path: /opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk + channel: ${{ secrets.SLACK_APK_CHANNEL }} + title: '${{github.head_ref}}.apk' + filename: ${{github.head_ref}}.apk + initial_comment: ${{ github.event.head_commit.message }} diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock index 01e19dda4..e399526fd 100644 --- a/cw_core/pubspec.lock +++ b/cw_core/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" boolean_selector: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" checked_yaml: dependency: transitive description: @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" convert: dependency: transitive description: @@ -279,10 +279,10 @@ packages: dependency: "direct main" description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -303,10 +303,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.18.1" io: dependency: transitive description: @@ -319,10 +319,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" json_annotation: dependency: transitive description: @@ -343,10 +343,10 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -359,10 +359,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mime: dependency: transitive description: @@ -399,10 +399,10 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_provider: dependency: "direct main" description: @@ -596,10 +596,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" timing: dependency: transitive description: @@ -665,5 +665,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.19.0 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.0.0" diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock index a79d2d3cf..a63aa3237 100644 --- a/cw_haven/pubspec.lock +++ b/cw_haven/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" boolean_selector: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" checked_yaml: dependency: transitive description: @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" convert: dependency: transitive description: @@ -286,10 +286,10 @@ packages: dependency: "direct main" description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -310,10 +310,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.18.1" io: dependency: transitive description: @@ -326,10 +326,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" json_annotation: dependency: transitive description: @@ -350,10 +350,10 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -366,10 +366,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mime: dependency: transitive description: @@ -406,10 +406,10 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_provider: dependency: "direct main" description: @@ -603,10 +603,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" timing: dependency: transitive description: @@ -672,5 +672,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.19.0 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.0.0" diff --git a/cw_monero/example/pubspec.lock b/cw_monero/example/pubspec.lock index f4c36e69c..1aae6b0c9 100644 --- a/cw_monero/example/pubspec.lock +++ b/cw_monero/example/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" boolean_selector: dependency: transitive description: @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" convert: dependency: transitive description: @@ -157,10 +157,10 @@ packages: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "1.1.0" http_parser: dependency: transitive description: @@ -173,18 +173,18 @@ packages: dependency: transitive description: name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.18.1" js: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" lints: dependency: transitive description: @@ -197,10 +197,10 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mobx: dependency: transitive description: @@ -229,10 +229,10 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_provider: dependency: transitive description: @@ -362,10 +362,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" typed_data: dependency: transitive description: @@ -399,5 +399,5 @@ packages: source: hosted version: "0.2.0+3" sdks: - dart: ">=2.18.1 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.0.0" diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp index 66b8605c6..1cb01fac7 100644 --- a/cw_monero/ios/Classes/monero_api.cpp +++ b/cw_monero/ios/Classes/monero_api.cpp @@ -139,7 +139,7 @@ extern "C" int8_t direction; int8_t isPending; uint32_t subaddrIndex; - + char *hash; char *paymentId; @@ -154,7 +154,7 @@ extern "C" std::set::iterator it = transaction->subaddrIndex().begin(); subaddrIndex = *it; confirmations = transaction->confirmations(); - datetime = static_cast(transaction->timestamp()); + datetime = static_cast(transaction->timestamp()); direction = transaction->direction(); isPending = static_cast(transaction->isPending()); std::string *hash_str = new std::string(transaction->hash()); @@ -234,7 +234,7 @@ extern "C" } void setUnlocked(bool unlocked); - + }; Monero::Coins *m_coins; @@ -254,7 +254,7 @@ extern "C" { m_wallet = wallet; m_listener = nullptr; - + if (wallet != nullptr) { @@ -479,7 +479,7 @@ extern "C" { nice(19); Monero::Wallet *wallet = get_current_wallet(); - + std::string _login = ""; std::string _password = ""; std::string _socksProxyAddress = ""; @@ -568,7 +568,7 @@ extern "C" _preferred_inputs.insert(std::string(*preferred_inputs)); preferred_inputs++; } - + auto priority = static_cast(priority_raw); std::string _payment_id; Monero::PendingTransaction *transaction; @@ -587,7 +587,7 @@ extern "C" { transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs); } - + int status = transaction->status(); if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical) diff --git a/cw_monero/lib/monero_wallet_addresses.dart b/cw_monero/lib/monero_wallet_addresses.dart index fcc3576f4..a9da3d5d4 100644 --- a/cw_monero/lib/monero_wallet_addresses.dart +++ b/cw_monero/lib/monero_wallet_addresses.dart @@ -41,6 +41,7 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store { Future init() async { accountList.update(); account = accountList.accounts.first; + updateSubaddressList(accountIndex: account?.id ?? 0); await updateAddressesInBox(); } diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index 437184a7d..37e08e7ca 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" boolean_selector: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" checked_yaml: dependency: transitive description: @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" convert: dependency: transitive description: @@ -286,10 +286,10 @@ packages: dependency: "direct main" description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -310,10 +310,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.17.0" + version: "0.18.1" io: dependency: transitive description: @@ -326,10 +326,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" json_annotation: dependency: transitive description: @@ -350,10 +350,10 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -366,10 +366,10 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mime: dependency: transitive description: @@ -406,10 +406,10 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_provider: dependency: "direct main" description: @@ -603,10 +603,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.5.1" timing: dependency: transitive description: @@ -672,5 +672,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.19.0 <3.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.0.0" diff --git a/lib/core/fiat_conversion_service.dart b/lib/core/fiat_conversion_service.dart index 9690c430a..479aa3b82 100644 --- a/lib/core/fiat_conversion_service.dart +++ b/lib/core/fiat_conversion_service.dart @@ -21,7 +21,7 @@ Future _fetchPrice(Map args) async { 'key': secrets.fiatApiKey, }; - double price = 0.0; + num price = 0.0; try { late final Uri uri; @@ -41,12 +41,12 @@ Future _fetchPrice(Map args) async { final results = responseJSON['results'] as Map; if (results.isNotEmpty) { - price = results.values.first as double; + price = results.values.first as num; } - return price; + return price.toDouble(); } catch (e) { - return price; + return price.toDouble(); } } diff --git a/lib/core/wallet_change_listener_view_model.dart b/lib/core/wallet_change_listener_view_model.dart new file mode 100644 index 000000000..6735afee5 --- /dev/null +++ b/lib/core/wallet_change_listener_view_model.dart @@ -0,0 +1,30 @@ +import 'package:cw_core/balance.dart'; +import 'package:cw_core/transaction_history.dart'; +import 'package:cw_core/transaction_info.dart'; +import 'package:mobx/mobx.dart'; +import 'package:cw_core/wallet_base.dart'; +import 'package:cake_wallet/store/app_store.dart'; + +part 'wallet_change_listener_view_model.g.dart'; + +class WalletChangeListenerViewModel = WalletChangeListenerViewModelBase + with _$WalletChangeListenerViewModel; + +abstract class WalletChangeListenerViewModelBase with Store { + WalletChangeListenerViewModelBase({ + required AppStore appStore, + }) : _wallet = appStore.wallet! { + reaction((_) => appStore.wallet, (WalletBase? wallet) { + _wallet = wallet!; + onWalletChange(wallet); + }); + } + + void onWalletChange(WalletBase wallet) {} + + @observable + WalletBase, TransactionInfo> _wallet; + @computed + WalletBase, TransactionInfo> get wallet => + _wallet; +} diff --git a/lib/di.dart b/lib/di.dart index a50b7d933..2573eb6dd 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -543,8 +543,7 @@ Future setup({ getIt.registerFactory( () => SendViewModel( - getIt.get().wallet!, - getIt.get().settingsStore, + getIt.get(), getIt.get(), getIt.get(), getIt.get(), @@ -776,7 +775,7 @@ Future setup({ )); getIt.registerFactory(() => ExchangeViewModel( - getIt.get().wallet!, + getIt.get(), _tradesSource, getIt.get(), getIt.get(), diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart index ad2291ba5..5e1f8d16a 100644 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart +++ b/lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart @@ -73,12 +73,12 @@ class DesktopDashboardActions extends StatelessWidget { ), ], ), - Expanded( - child: MarketPlacePage( - dashboardViewModel: dashboardViewModel, - marketPlaceViewModel: getIt.get(), - ), + Expanded( + child: MarketPlacePage( + dashboardViewModel: dashboardViewModel, + marketPlaceViewModel: getIt.get(), ), + ), ], ); } diff --git a/lib/src/screens/dashboard/widgets/market_place_page.dart b/lib/src/screens/dashboard/widgets/market_place_page.dart index 2d6539370..1bdcb61b4 100644 --- a/lib/src/screens/dashboard/widgets/market_place_page.dart +++ b/lib/src/screens/dashboard/widgets/market_place_page.dart @@ -48,15 +48,15 @@ class MarketPlacePage extends StatelessWidget { child: ListView( controller: _scrollController, children: [ - SizedBox(height: 20), - DashBoardRoundedCardWidget( - onTap: () => launchUrl( - Uri.parse("https://cakelabs.com/news/cake-pay-mobile-to-shut-down/"), - mode: LaunchMode.externalApplication, - ), - title: S.of(context).cake_pay_title, - subTitle: S.of(context).cake_pay_subtitle, - ), + // SizedBox(height: 20), + // DashBoardRoundedCardWidget( + // onTap: () => launchUrl( + // Uri.parse("https://cakelabs.com/news/cake-pay-mobile-to-shut-down/"), + // mode: LaunchMode.externalApplication, + // ), + // title: S.of(context).cake_pay_title, + // subTitle: S.of(context).cake_pay_subtitle, + // ), SizedBox(height: 20), DashBoardRoundedCardWidget( onTap: () => launchUrl( diff --git a/lib/src/screens/settings/manage_nodes_page.dart b/lib/src/screens/settings/manage_nodes_page.dart index 0a67f0502..4b1034f2b 100644 --- a/lib/src/screens/settings/manage_nodes_page.dart +++ b/lib/src/screens/settings/manage_nodes_page.dart @@ -42,36 +42,40 @@ class ManageNodesPage extends BasePage { return nodeListViewModel.nodes.length; }, itemBuilder: (_, index) { - final node = nodeListViewModel.nodes[index]; - final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex; - final nodeListRow = NodeListRow( - title: node.uriRaw, - node: node, - isSelected: isSelected, - onTap: (_) async { - if (isSelected) { - return; - } + return Observer( + builder: (context) { + final node = nodeListViewModel.nodes[index]; + final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex; + final nodeListRow = NodeListRow( + title: node.uriRaw, + node: node, + isSelected: isSelected, + onTap: (_) async { + if (isSelected) { + return; + } - await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithTwoActions( - alertTitle: S.of(context).change_current_node_title, - alertContent: nodeListViewModel.getAlertContent(node.uriRaw), - leftButtonText: S.of(context).cancel, - rightButtonText: S.of(context).change, - actionLeftButton: () => Navigator.of(context).pop(), - actionRightButton: () async { - await nodeListViewModel.setAsCurrent(node); - Navigator.of(context).pop(); - }, - ); - }); + await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithTwoActions( + alertTitle: S.of(context).change_current_node_title, + alertContent: nodeListViewModel.getAlertContent(node.uriRaw), + leftButtonText: S.of(context).cancel, + rightButtonText: S.of(context).change, + actionLeftButton: () => Navigator.of(context).pop(), + actionRightButton: () async { + await nodeListViewModel.setAsCurrent(node); + Navigator.of(context).pop(); + }, + ); + }, + ); + }, + ); + return nodeListRow; }, ); - - return nodeListRow; }, ), ); diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 1ac3ad7fd..4603b2007 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:collection'; import 'dart:convert'; +import 'package:cake_wallet/core/wallet_change_listener_view_model.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/wallet_contact.dart'; @@ -13,7 +14,7 @@ import 'package:cake_wallet/exchange/trocador/trocador_exchange_provider.dart'; import 'package:cake_wallet/exchange/trocador/trocador_request.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; import 'package:cw_core/transaction_priority.dart'; -import 'package:cw_core/wallet_base.dart'; +import 'package:cake_wallet/store/app_store.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/sync_status.dart'; import 'package:cw_core/wallet_type.dart'; @@ -45,16 +46,22 @@ part 'exchange_view_model.g.dart'; class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel; -abstract class ExchangeViewModelBase with Store { +abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with Store { + @override + void onWalletChange(wallet) { + receiveCurrency = wallet.currency; + depositCurrency = wallet.currency; + } + ExchangeViewModelBase( - this.wallet, - this.trades, - this._exchangeTemplateStore, - this.tradesStore, - this._settingsStore, - this.sharedPreferences, - this.contactListViewModel) - : _cryptoNumberFormat = NumberFormat(), + AppStore appStore, + this.trades, + this._exchangeTemplateStore, + this.tradesStore, + this._settingsStore, + this.sharedPreferences, + this.contactListViewModel, + ) : _cryptoNumberFormat = NumberFormat(), isFixedRateMode = false, isReceiveAmountEntered = false, depositAmount = '', @@ -70,10 +77,11 @@ abstract class ExchangeViewModelBase with Store { limits = Limits(min: 0, max: 0), tradeState = ExchangeTradeStateInitial(), limitsState = LimitsInitialState(), - receiveCurrency = wallet.currency, - depositCurrency = wallet.currency, + receiveCurrency = appStore.wallet!.currency, + depositCurrency = appStore.wallet!.currency, providerList = [], - selectedProviders = ObservableList() { + selectedProviders = ObservableList(), + super(appStore: appStore) { _useTorOnly = _settingsStore.exchangeStatus == ExchangeApiMode.torOnly; _setProviders(); const excludeDepositCurrencies = [CryptoCurrency.btt, CryptoCurrency.nano]; @@ -86,10 +94,9 @@ abstract class ExchangeViewModelBase with Store { ]; _initialPairBasedOnWallet(); - final Map exchangeProvidersSelection = json.decode( - sharedPreferences - .getString(PreferencesKey.exchangeProvidersSelection) ?? - "{}") as Map; + final Map exchangeProvidersSelection = + json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") + as Map; /// if the provider is not in the user settings (user's first time or newly added provider) /// then use its default value decided by us @@ -102,17 +109,14 @@ abstract class ExchangeViewModelBase with Store { _setAvailableProviders(); _calculateBestRate(); - bestRateSync = - Timer.periodic(Duration(seconds: 10), (timer) => _calculateBestRate()); + bestRateSync = Timer.periodic(Duration(seconds: 10), (timer) => _calculateBestRate()); isDepositAddressEnabled = !(depositCurrency == wallet.currency); isReceiveAddressEnabled = !(receiveCurrency == wallet.currency); depositAmount = ''; receiveAmount = ''; receiveAddress = ''; - depositAddress = depositCurrency == wallet.currency - ? wallet.walletAddresses.address - : ''; + depositAddress = depositCurrency == wallet.currency ? wallet.walletAddresses.address : ''; provider = providersForCurrentPair().first; final initialProvider = provider; provider!.checkIsAvailable().then((bool isAvailable) { @@ -123,12 +127,10 @@ abstract class ExchangeViewModelBase with Store { } }); receiveCurrencies = CryptoCurrency.all - .where((cryptoCurrency) => - !excludeReceiveCurrencies.contains(cryptoCurrency)) + .where((cryptoCurrency) => !excludeReceiveCurrencies.contains(cryptoCurrency)) .toList(); depositCurrencies = CryptoCurrency.all - .where((cryptoCurrency) => - !excludeDepositCurrencies.contains(cryptoCurrency)) + .where((cryptoCurrency) => !excludeDepositCurrencies.contains(cryptoCurrency)) .toList(); _defineIsReceiveAmountEditable(); loadLimits(); @@ -139,7 +141,6 @@ abstract class ExchangeViewModelBase with Store { }); } bool _useTorOnly; - final WalletBase wallet; final Box trades; final ExchangeTemplateStore _exchangeTemplateStore; final TradesStore tradesStore; @@ -164,8 +165,7 @@ abstract class ExchangeViewModelBase with Store { /// initialize with descending comparator /// since we want largest rate first final SplayTreeMap _sortedAvailableProviders = - SplayTreeMap( - (double a, double b) => b.compareTo(a)); + SplayTreeMap((double a, double b) => b.compareTo(a)); final List _tradeAvailableProviders = []; @@ -221,21 +221,17 @@ abstract class ExchangeViewModelBase with Store { SyncStatus get status => wallet.syncStatus; @computed - ObservableList get templates => - _exchangeTemplateStore.templates; + ObservableList get templates => _exchangeTemplateStore.templates; @computed - List get walletContactsToShow => - contactListViewModel.walletContacts - .where((element) => - receiveCurrency == null || element.type == receiveCurrency) - .toList(); + List get walletContactsToShow => contactListViewModel.walletContacts + .where((element) => receiveCurrency == null || element.type == receiveCurrency) + .toList(); @action bool checkIfWalletIsAnInternalWallet(String address) { - final walletContactList = walletContactsToShow - .where((element) => element.address == address) - .toList(); + final walletContactList = + walletContactsToShow.where((element) => element.address == address).toList(); return walletContactList.isNotEmpty; } @@ -255,7 +251,6 @@ abstract class ExchangeViewModelBase with Store { return false; } - @computed TransactionPriority get transactionPriority { final priority = _settingsStore.priority[wallet.type]; @@ -277,14 +272,11 @@ abstract class ExchangeViewModelBase with Store { switch (wallet.type) { case WalletType.monero: case WalletType.haven: - return transactionPriority == - monero!.getMoneroTransactionPrioritySlow(); + return transactionPriority == monero!.getMoneroTransactionPrioritySlow(); case WalletType.bitcoin: - return transactionPriority == - bitcoin!.getBitcoinTransactionPrioritySlow(); + return transactionPriority == bitcoin!.getBitcoinTransactionPrioritySlow(); case WalletType.litecoin: - return transactionPriority == - bitcoin!.getLitecoinTransactionPrioritySlow(); + return transactionPriority == bitcoin!.getLitecoinTransactionPrioritySlow(); default: return false; } @@ -390,20 +382,18 @@ abstract class ExchangeViewModelBase with Store { } Future _calculateBestRate() async { - final amount = - double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1; + final amount = double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1; final _providers = _tradeAvailableProviders .where((element) => !isFixedRateMode || element.supportsFixedRate) .toList(); - final result = await Future.wait(_providers.map((element) => - element.fetchRate( - from: depositCurrency, - to: receiveCurrency, - amount: amount, - isFixedRateMode: isFixedRateMode, - isReceiveAmount: isFixedRateMode))); + final result = await Future.wait(_providers.map((element) => element.fetchRate( + from: depositCurrency, + to: receiveCurrency, + amount: amount, + isFixedRateMode: isFixedRateMode, + isReceiveAmount: isFixedRateMode))); _sortedAvailableProviders.clear(); @@ -445,14 +435,13 @@ abstract class ExchangeViewModelBase with Store { } try { - final tempLimits = await provider.fetchLimits( - from: from, to: to, isFixedRateMode: isFixedRateMode); + final tempLimits = + await provider.fetchLimits(from: from, to: to, isFixedRateMode: isFixedRateMode); if (lowestMin != null && (tempLimits.min ?? -1) < lowestMin) { lowestMin = tempLimits.min; } - if (highestMax != null && - (tempLimits.max ?? double.maxFinite) > highestMax) { + if (highestMax != null && (tempLimits.max ?? double.maxFinite) > highestMax) { highestMax = tempLimits.max; } } catch (e) { @@ -604,12 +593,8 @@ abstract class ExchangeViewModelBase with Store { isReceiveAmountEntered = false; depositAmount = ''; receiveAmount = ''; - depositAddress = depositCurrency == wallet.currency - ? wallet.walletAddresses.address - : ''; - receiveAddress = receiveCurrency == wallet.currency - ? wallet.walletAddresses.address - : ''; + depositAddress = depositCurrency == wallet.currency ? wallet.walletAddresses.address : ''; + receiveAddress = receiveCurrency == wallet.currency ? wallet.walletAddresses.address : ''; isDepositAddressEnabled = !(depositCurrency == wallet.currency); isReceiveAddressEnabled = !(receiveCurrency == wallet.currency); isFixedRateMode = false; @@ -628,8 +613,7 @@ abstract class ExchangeViewModelBase with Store { } final amount = availableBalance - fee; - changeDepositAmount( - amount: bitcoin!.formatterBitcoinAmountToString(amount: amount)); + changeDepositAmount(amount: bitcoin!.formatterBitcoinAmountToString(amount: amount)); } } @@ -664,9 +648,8 @@ abstract class ExchangeViewModelBase with Store { List _providersForPair( {required CryptoCurrency from, required CryptoCurrency to}) { final providers = providerList - .where((provider) => provider.pairList - .where((pair) => pair.from == from && pair.to == to) - .isNotEmpty) + .where((provider) => + provider.pairList.where((pair) => pair.from == from && pair.to == to).isNotEmpty) .toList(); return providers; @@ -750,14 +733,12 @@ abstract class ExchangeViewModelBase with Store { _bestRate = 0; _calculateBestRate(); - final Map exchangeProvidersSelection = json.decode( - sharedPreferences - .getString(PreferencesKey.exchangeProvidersSelection) ?? - "{}") as Map; + final Map exchangeProvidersSelection = + json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") + as Map; for (var provider in providerList) { - exchangeProvidersSelection[provider.title] = - selectedProviders.contains(provider); + exchangeProvidersSelection[provider.title] = selectedProviders.contains(provider); } sharedPreferences.setString( @@ -768,15 +749,15 @@ abstract class ExchangeViewModelBase with Store { bool get isAvailableInSelected { final providersForPair = providersForCurrentPair(); - return selectedProviders.any( - (element) => element.isAvailable && providersForPair.contains(element)); + return selectedProviders + .any((element) => element.isAvailable && providersForPair.contains(element)); } void _setAvailableProviders() { _tradeAvailableProviders.clear(); - _tradeAvailableProviders.addAll(selectedProviders - .where((provider) => providersForCurrentPair().contains(provider))); + _tradeAvailableProviders.addAll( + selectedProviders.where((provider) => providersForCurrentPair().contains(provider))); } @action @@ -784,16 +765,13 @@ abstract class ExchangeViewModelBase with Store { switch (wallet.type) { case WalletType.monero: case WalletType.haven: - _settingsStore.priority[wallet.type] = - monero!.getMoneroTransactionPriorityAutomatic(); + _settingsStore.priority[wallet.type] = monero!.getMoneroTransactionPriorityAutomatic(); break; case WalletType.bitcoin: - _settingsStore.priority[wallet.type] = - bitcoin!.getBitcoinTransactionPriorityMedium(); + _settingsStore.priority[wallet.type] = bitcoin!.getBitcoinTransactionPriorityMedium(); break; case WalletType.litecoin: - _settingsStore.priority[wallet.type] = - bitcoin!.getLitecoinTransactionPriorityMedium(); + _settingsStore.priority[wallet.type] = bitcoin!.getLitecoinTransactionPriorityMedium(); break; default: break; @@ -802,9 +780,7 @@ abstract class ExchangeViewModelBase with Store { void _setProviders() { if (_settingsStore.exchangeStatus == ExchangeApiMode.torOnly) { - providerList = _allProviders - .where((provider) => provider.supportsOnionAddress) - .toList(); + providerList = _allProviders.where((provider) => provider.supportsOnionAddress).toList(); } else { providerList = _allProviders; } diff --git a/lib/view_model/node_list/node_list_view_model.dart b/lib/view_model/node_list/node_list_view_model.dart index 59d150ae9..fb1198c41 100644 --- a/lib/view_model/node_list/node_list_view_model.dart +++ b/lib/view_model/node_list/node_list_view_model.dart @@ -79,6 +79,7 @@ abstract class NodeListViewModelBase with Store { @action Future delete(Node node) async => node.delete(); + @action Future setAsCurrent(Node node) async => settingsStore.nodes[_appStore.wallet!.type] = node; @action diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 78bde55db..487be1cfe 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -3,13 +3,11 @@ import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/nano/nano.dart'; +import 'package:cake_wallet/core/wallet_change_listener_view_model.dart'; import 'package:cake_wallet/entities/contact_record.dart'; -import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; -import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/entities/wallet_contact.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; -import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; import 'package:cw_core/transaction_priority.dart'; import 'package:cake_wallet/view_model/send/output.dart'; @@ -22,7 +20,6 @@ import 'package:cake_wallet/core/address_validator.dart'; import 'package:cake_wallet/core/amount_validator.dart'; import 'package:cw_core/pending_transaction.dart'; import 'package:cake_wallet/core/validator.dart'; -import 'package:cw_core/wallet_base.dart'; import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cw_core/sync_status.dart'; @@ -41,30 +38,38 @@ part 'send_view_model.g.dart'; class SendViewModel = SendViewModelBase with _$SendViewModel; -abstract class SendViewModelBase with Store { - SendViewModelBase( - this._wallet, - this._settingsStore, - this.sendTemplateViewModel, - this._fiatConversationStore, - this.balanceViewModel, - this.contactListViewModel, - this.transactionDescriptionBox) - : state = InitialExecutionState(), - currencies = _wallet.balance.keys.toList(), - selectedCryptoCurrency = _wallet.currency, - hasMultipleTokens = _wallet.type == WalletType.ethereum, - outputs = ObservableList(), - fiatFromSettings = _settingsStore.fiatCurrency { - final priority = _settingsStore.priority[_wallet.type]; - final priorities = priorityForWalletType(_wallet.type); +abstract class SendViewModelBase extends WalletChangeListenerViewModel with Store { + @override + void onWalletChange(wallet) { + currencies = wallet.balance.keys.toList(); + selectedCryptoCurrency = wallet.currency; + hasMultipleTokens = wallet.type == WalletType.ethereum; + } - if (!priorityForWalletType(_wallet.type).contains(priority)) { - _settingsStore.priority[_wallet.type] = priorities.first; + SendViewModelBase( + AppStore appStore, + this.sendTemplateViewModel, + this._fiatConversationStore, + this.balanceViewModel, + this.contactListViewModel, + this.transactionDescriptionBox, + ) : state = InitialExecutionState(), + currencies = appStore.wallet!.balance.keys.toList(), + selectedCryptoCurrency = appStore.wallet!.currency, + hasMultipleTokens = appStore.wallet!.type == WalletType.ethereum, + outputs = ObservableList(), + _settingsStore = appStore.settingsStore, + fiatFromSettings = appStore.settingsStore.fiatCurrency, + super(appStore: appStore) { + final priority = _settingsStore.priority[wallet.type]; + final priorities = priorityForWalletType(wallet.type); + + if (!priorityForWalletType(wallet.type).contains(priority)) { + _settingsStore.priority[wallet.type] = priorities.first; } outputs - .add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency)); + .add(Output(wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency)); } @observable @@ -75,7 +80,7 @@ abstract class SendViewModelBase with Store { @action void addOutput() { outputs - .add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency)); + .add(Output(wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency)); } @action @@ -115,7 +120,7 @@ abstract class SendViewModelBase with Store { try { if (pendingTransaction != null) { final currency = - walletType == WalletType.ethereum ? _wallet.currency : selectedCryptoCurrency; + walletType == WalletType.ethereum ? wallet.currency : selectedCryptoCurrency; final fiat = calculateFiatAmount( price: _fiatConversationStore.prices[currency]!, cryptoAmount: pendingTransaction!.feeFormatted); @@ -131,19 +136,19 @@ abstract class SendViewModelBase with Store { FiatCurrency get fiat => _settingsStore.fiatCurrency; TransactionPriority get transactionPriority { - final priority = _settingsStore.priority[_wallet.type]; + final priority = _settingsStore.priority[wallet.type]; if (priority == null) { - throw Exception('Unexpected type ${_wallet.type}'); + throw Exception('Unexpected type ${wallet.type}'); } return priority; } - CryptoCurrency get currency => _wallet.currency; + CryptoCurrency get currency => wallet.currency; Validator get amountValidator => - AmountValidator(currency: walletTypeToCryptoCurrency(_wallet.type)); + AmountValidator(currency: walletTypeToCryptoCurrency(wallet.type)); Validator get allAmountValidator => AllAmountValidator(); @@ -157,7 +162,7 @@ abstract class SendViewModelBase with Store { PendingTransaction? pendingTransaction; @computed - String get balance => _wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance; + String get balance => wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance; @computed bool get isFiatDisabled => balanceViewModel.isFiatDisabled; @@ -171,7 +176,7 @@ abstract class SendViewModelBase with Store { isFiatDisabled ? '' : pendingTransactionFeeFiatAmount + ' ' + fiat.title; @computed - bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus; + bool get isReadyForSend => wallet.syncStatus is SyncedSyncStatus; @computed List