diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index e2b932202..47378eef5 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -127,6 +127,7 @@ jobs: echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_ethereum/lib/.secrets.g.dart + echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart - name: Rename app run: echo -e "id=com.cakewallet.test\nname=$GITHUB_HEAD_REF" > /opt/android/cake_wallet/android/app.properties diff --git a/PRIVACY.md b/PRIVACY.md index d740dcba8..88f180c5e 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -1,6 +1,6 @@ Privacy Policy -Last modified: July 21, 2022 +Last modified: August 9, 2023 Introduction ============ @@ -13,7 +13,7 @@ Introduction - On this App. - In email, text, and other electronic messages between you and this App. It does not apply to information collected by: - - Us offline or through any other means, including on any other App operated by Company or any third party (including our affiliates and subsidiaries)]; or + - Us offline or through any other means, including on any other App operated by Company or any third party (including our affiliates and subsidiaries); or - Any third party (including our affiliates and subsidiaries), including through any application or content (including advertising) that may link to or be accessible from or on the App. Please read this policy carefully to understand our policies and practices regarding your information and how we will treat it. If you do not agree with our policies and practices, you have the choice to not use the App. By accessing or using this App, you agree to this privacy policy. This policy may change from time to time. Your continued use of this App after we make changes is deemed to be acceptance of those changes, so please check the policy periodically for updates. @@ -25,7 +25,7 @@ Definitions - "Node" means a server on a supported cryptocurrency network which transmits data to your App for processing and synchronization, and to which your Device transmits transactions which you would like to submit to the supported cryptocurrency networks. This includes full nodes, Electrum servers, and lightning network nodes. - "Cake Labs Nodes" refers to the set of cryptocurrency nodes operated and maintained by Cake Labs LLC. - "Service" refers to the App. - - "Third-party Service" refers to any service integrated into the App. This includes but is not limited to ChangeNOW, Wyre, MoonPay, and BlockBuy. + - "Third-party Service" refers to any service integrated into the App. This includes but is not limited to ChangeNOW, Onramper, and MoonPay. - "Usage Data" refers to data collected automatically about your usage of an App. - "You" means the individual, group, corporation, or any other entity accessing or using the Service. @@ -40,26 +40,29 @@ Information We Never Receive Nor Collect Information We May Receive But Do Not Retain -------------------------------------------- - We receive but do NOT store information from and about users of our App, including: + We may receive but do NOT store information from and about users of our App, including: - The device IP address, the block height to which your wallet is synchronized, and any transactions or channels which you use our Node to submit to supported cryptocurrency networks. We receive this information: - - Automatically as you use the App. + - Automatically as you use the App, unless you turn certain features off in your App privacy settings. - This data is provided by connecting to the Nodes and price API maintained by Cake Labs. You have the right to choose not to provide synchronization data to Cake Labs by choosing a different Node. We provide a list of Nodes in the app that include our own and third party Nodes, or you can use your own Node (which we recommend). + This data is provided by connecting to the Nodes and price API maintained by Cake Labs. You have the right to choose not to provide synchronization data to Cake Labs by choosing a different Node. We provide a list of Nodes in the app that include our own and third party Nodes, or you can use your own Node (which we recommend). You have the right to choose not to connect to our Fiat API service by disabling this Fiat API in App privacy settings. - Personal Data sent through the Cake Labs Nodes is limited to your device's IP address, the block height to which your wallet is synchronized, and any transactions or channels which you use our Node to submit to the supported cryptocurrency networks. Personal Data received by Cake Labs in this manner is not stored for any length of time, and thus Cake Labs is both unwilling to and incapable of sharing this data, or using it for any purpose beyond ensuring your appropriate connection to our Nodes. + Personal Data that may be sent through the Cake Labs Nodes is limited to your device's IP address, the block height to which your wallet is synchronized, and any transactions or channels which you use our Node to submit to the supported cryptocurrency networks. Personal Data received by Cake Labs in this manner is not stored for any length of time, and thus Cake Labs is incapable of sharing this data and will not use it for any purpose beyond ensuring your appropriate connection to our Nodes. If you decide to use a Node offered by any third party, some of which we include in our Apps, said third party will receive this Personal Data instead of Cake Labs. We take no responsibility for the actions of any third-party Node offered within the Application. We recommend connecting to your own Node to limit third party sharing of your Personal Information. + If you use our Fiat API service, you will share your IP address and the cryptocurrency and fiat currency exchange pair for which your wallet requests a spot price quote. You can disable this Fiat API in App privacy settings. + Information We May Collect About You and How We Collect It ---------------------------------------------------------- We collect several types of information from and about users of our App, including information: - - By which you may be personally identified, such as name, e-mail address, or and a/any other identifier by which you may be contacted online or offline ("personal information" or "Personal Data”), ONLY when you provide it to us; + - By which you may be personally identified, such as name, e-mail address, or and a/any other identifier by which you may be contacted online or offline ("personal information" or "Personal Data”); + - Device data and error log data; We collect this information: - - Directly from you when you provide it to us. + - Directly from you ONLY when you provide it to us. - Personal information is received by Cake Labs ONLY in the event that you choose to provide it to us by voluntarily contacting Cake Labs regarding support, questions or suggestions. + Personal information is received by Cake Labs ONLY in the event that you choose to provide it to us by voluntarily contacting Cake Labs regarding support, questions or suggestions. You may optionally send us Error reports to help us improve the App. These Error reports contain error logs and basic device data. You can review and make modifications to these Error reports before sending them to us, or you may choose not to send them to us at all. How We Use Your Information --------------------------- @@ -112,7 +115,9 @@ Data Security Links to Other Websites ----------------------- - The App may contain links to other websites that are not operated by us. If you click on a third-party link, you will be directed to that third party's site. We strongly advise you to review the Privacy Policy of every site you visit. We have no control over and assume no responsibility for the content, privacy policies or practices of any third-party sites or services. + The App may contain links to other websites that are not operated by us. If you click on a Third-Party Service link, you will be directed to that third party's site. We strongly advise you to review the Privacy Policy of every site you visit. We have no control over and assume no responsibility for the content, privacy policies or practices of any third-party sites or services. + + The App includes several optional Third-Party Services, which may not be available to all users. If you use Third-Party Services, you must agree to their respective Privacy Policies. Changes to Our Privacy Policy ----------------------------- diff --git a/README.md b/README.md index 317ad91b7..7b739f980 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Cake Wallet for Android and iOS +# Cake Wallet for Mobile and Desktop ## Open Source Multi-Currency Wallet @@ -7,6 +7,7 @@ * Website: https://cakewallet.com * App Store (iOS / MacOS): https://cakewallet.com/ios * Google Play: https://cakewallet.com/gp +* F-Droid: https://fdroid.cakelabs.com * APK: https://github.com/cake-tech/cake_wallet/releases * Linux: https://github.com/cake-tech/cake_wallet/releases @@ -17,9 +18,8 @@ * Completely noncustodial. *Your keys, your coins.* * Built-in exchange for dozens of pairs * Easily pay cryptocurrency invoices with fixed rate exchanges -* Buy cryptocurrency (BTC/LTC/XMR) with credit/debit/bank +* Buy cryptocurrency (BTC/LTC/XMR/ETH) with credit/debit/bank * Sell cryptocurrency by bank transfer -* Purchase gift cards at a discount using only an email with [Cake Pay](https://cakepay.com), available in-app * Scan QR codes for easy cryptocurrency transfers * Create several wallets * Select your own custom nodes/servers @@ -32,6 +32,7 @@ * Convenient exchange and sending templates for recurring payments * Create donation links and invoices in the receive screen * Robust privacy settings (eg: Tor-only connections) +* Robust security settings (eg: Cake 2FA) ### Monero Specific Features @@ -40,13 +41,19 @@ * Specify restore height for faster syncing * Specify multiple recipients for batch sending * Optionally set Monero nodes as trusted for faster syncing +* Specify a proxy for Monero nodes, compatible with Tor and i2p ### Bitcoin Specific Features * Bitcoin coin control (specify specific outputs to spend) * Automatically generate new addresses * Specify multiple recipients for batch sending -* Sell BTC for USD + +### Ethereum Specific Features + +* Store ETH and all ERc-20 tokens +* Add custom tokens by contract address +* Enable or disable Etherscan for transaction history ### Litecoin Specific Features @@ -69,6 +76,7 @@ * Website: https://monero.com * App Store (iOS): https://apps.apple.com/app/id1601990386 * Google Play: https://play.google.com/store/apps/details?id=com.monero.app +* F-Droid: https://fdroid.cakelabs.com * APK: https://github.com/cake-tech/cake_wallet/releases # Support @@ -123,7 +131,7 @@ Edit the applicable `strings_XX.arb` file in `res/values/` and open a pull reque 2. Edit the strings in this file, replacing XXX below with the translation for each string. -`"welcome" : "Welcome to",` -> `"welcome" : "XXX",` +`"welcome": "Welcome to",` -> `"welcome": "XXX",` 3. For strings where there is a variable, denoted by a $ symbol and braces, such as ${status}, the string in braces should not be translated. For example, when editing line 106: diff --git a/assets/images/live_support.png b/assets/images/live_support.png new file mode 100644 index 000000000..89ad61f45 Binary files /dev/null and b/assets/images/live_support.png differ diff --git a/assets/images/more_links.png b/assets/images/more_links.png new file mode 100644 index 000000000..97891f3ad Binary files /dev/null and b/assets/images/more_links.png differ diff --git a/assets/images/wallet_guides.png b/assets/images/wallet_guides.png new file mode 100644 index 000000000..3f2d9f270 Binary files /dev/null and b/assets/images/wallet_guides.png differ diff --git a/cw_core/lib/cake_hive.dart b/cw_core/lib/cake_hive.dart new file mode 100644 index 000000000..aadf6bf9a --- /dev/null +++ b/cw_core/lib/cake_hive.dart @@ -0,0 +1,4 @@ +import 'package:hive/hive.dart'; +import 'package:hive/src/hive_impl.dart'; + +final HiveInterface CakeHive = HiveImpl(); diff --git a/cw_core/lib/erc20_token.dart b/cw_core/lib/erc20_token.dart index db5b6db5b..fd27aaba6 100644 --- a/cw_core/lib/erc20_token.dart +++ b/cw_core/lib/erc20_token.dart @@ -1,4 +1,5 @@ import 'package:cw_core/crypto_currency.dart'; +import 'package:cw_core/hive_type_ids.dart'; import 'package:hive/hive.dart'; part 'erc20_token.g.dart'; @@ -53,7 +54,7 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin { iconPath: icon, ); - static const typeId = 12; + static const typeId = ERC20_TOKEN_TYPE_ID; static const boxName = 'Erc20Tokens'; @override diff --git a/cw_core/lib/hive_type_ids.dart b/cw_core/lib/hive_type_ids.dart new file mode 100644 index 000000000..0961182bc --- /dev/null +++ b/cw_core/lib/hive_type_ids.dart @@ -0,0 +1,13 @@ +const CONTACT_TYPE_ID = 0; +const NODE_TYPE_ID = 1; +const TRANSACTION_TYPE_ID = 2; +const TRADE_TYPE_ID = 3; +const WALLET_INFO_TYPE_ID = 4; +const WALLET_TYPE_TYPE_ID = 5; +const TEMPLATE_TYPE_ID = 6; +const EXCHANGE_TEMPLATE_TYPE_ID = 7; +const ORDER_TYPE_ID = 8; +const UNSPENT_COINS_INFO_TYPE_ID = 9; +const ANONPAY_INVOICE_INFO_TYPE_ID = 10; + +const ERC20_TOKEN_TYPE_ID = 12; diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart index 3fa45b44c..59a1450f6 100644 --- a/cw_core/lib/node.dart +++ b/cw_core/lib/node.dart @@ -3,6 +3,7 @@ import 'package:cw_core/keyable.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:hive/hive.dart'; +import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:http/io_client.dart' as ioc; @@ -37,7 +38,7 @@ class Node extends HiveObject with Keyable { trusted = map['trusted'] as bool? ?? false, socksProxyAddress = map['socksProxyPort'] as String?; - static const typeId = 1; + static const typeId = NODE_TYPE_ID; static const boxName = 'Nodes'; @HiveField(0, defaultValue: '') diff --git a/cw_core/lib/unspent_coins_info.dart b/cw_core/lib/unspent_coins_info.dart index 75c13f2cd..33be2eb2c 100644 --- a/cw_core/lib/unspent_coins_info.dart +++ b/cw_core/lib/unspent_coins_info.dart @@ -1,3 +1,4 @@ +import 'package:cw_core/hive_type_ids.dart'; import 'package:hive/hive.dart'; part 'unspent_coins_info.g.dart'; @@ -14,7 +15,7 @@ class UnspentCoinsInfo extends HiveObject { required this.vout, required this.value}); - static const typeId = 9; + static const typeId = UNSPENT_COINS_INFO_TYPE_ID; static const boxName = 'Unspent'; static const boxKey = 'unspentBoxKey'; @@ -45,4 +46,4 @@ class UnspentCoinsInfo extends HiveObject { String get note => noteRaw ?? ''; set note(String value) => noteRaw = value; -} \ No newline at end of file +} diff --git a/cw_core/lib/wallet_info.dart b/cw_core/lib/wallet_info.dart index a25702cf7..6b3fa9e98 100644 --- a/cw_core/lib/wallet_info.dart +++ b/cw_core/lib/wallet_info.dart @@ -1,7 +1,7 @@ -import 'package:flutter/foundation.dart'; -import 'package:hive/hive.dart'; -import 'package:cw_core/wallet_type.dart'; import 'dart:async'; +import 'package:cw_core/hive_type_ids.dart'; +import 'package:cw_core/wallet_type.dart'; +import 'package:hive/hive.dart'; part 'wallet_info.g.dart'; @@ -30,7 +30,7 @@ class WalletInfo extends HiveObject { yatEid, yatLastUsedAddressRaw, showIntroCakePayCard); } - static const typeId = 4; + static const typeId = WALLET_INFO_TYPE_ID; static const boxName = 'WalletInfo'; @HiveField(0, defaultValue: '') diff --git a/cw_core/lib/wallet_type.dart b/cw_core/lib/wallet_type.dart index a65839041..62c2ad410 100644 --- a/cw_core/lib/wallet_type.dart +++ b/cw_core/lib/wallet_type.dart @@ -1,4 +1,5 @@ import 'package:cw_core/crypto_currency.dart'; +import 'package:cw_core/hive_type_ids.dart'; import 'package:hive/hive.dart'; part 'wallet_type.g.dart'; @@ -10,9 +11,8 @@ const walletTypes = [ WalletType.haven, WalletType.ethereum, ]; -const walletTypeTypeId = 5; -@HiveType(typeId: walletTypeTypeId) +@HiveType(typeId: WALLET_TYPE_TYPE_ID) enum WalletType { @HiveField(0) monero, diff --git a/cw_ethereum/lib/default_erc20_tokens.dart b/cw_ethereum/lib/default_erc20_tokens.dart index 241e301ce..8c38e2e64 100644 --- a/cw_ethereum/lib/default_erc20_tokens.dart +++ b/cw_ethereum/lib/default_erc20_tokens.dart @@ -283,6 +283,13 @@ class DefaultErc20Tokens { decimal: 18, enabled: false, ), + Erc20Token( + name: "PayPal USD", + symbol: "PYUSD", + contractAddress: "0x6c3ea9036406852006290770bedfcaba0e23a0e8", + decimal: 6, + enabled: false, + ), ]; List get initialErc20Tokens => _defaultTokens.map((token) { diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart index ae05e6a4f..404b78ca2 100644 --- a/cw_ethereum/lib/ethereum_wallet.dart +++ b/cw_ethereum/lib/ethereum_wallet.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'dart:math'; import 'package:cw_core/crypto_currency.dart'; +import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/node.dart'; import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pending_transaction.dart'; @@ -58,8 +59,8 @@ abstract class EthereumWalletBase this.walletInfo = walletInfo; transactionHistory = EthereumTransactionHistory(walletInfo: walletInfo, password: password); - if (!Hive.isAdapterRegistered(Erc20Token.typeId)) { - Hive.registerAdapter(Erc20TokenAdapter()); + if (!CakeHive.isAdapterRegistered(Erc20Token.typeId)) { + CakeHive.registerAdapter(Erc20TokenAdapter()); } _sharedPrefs.complete(SharedPreferences.getInstance()); @@ -95,7 +96,7 @@ abstract class EthereumWalletBase Completer _sharedPrefs = Completer(); Future init() async { - erc20TokensBox = await Hive.openBox(Erc20Token.boxName); + erc20TokensBox = await CakeHive.openBox(Erc20Token.boxName); await walletAddresses.init(); await transactionHistory.init(); _privateKey = await getPrivateKey(_mnemonic, _password); @@ -180,8 +181,15 @@ abstract class EthereumWalletBase } } else { final output = outputs.first; - final BigInt allAmount = - _erc20Balance.balance - BigInt.from(calculateEstimatedFee(_credentials.priority!, null)); + // since the fees are taken from Ethereum + // then no need to subtract the fees from the amount if send all + final BigInt allAmount; + if (transactionCurrency is Erc20Token) { + allAmount = _erc20Balance.balance; + } else { + allAmount = _erc20Balance.balance - + BigInt.from(calculateEstimatedFee(_credentials.priority!, null)); + } final totalOriginalAmount = EthereumFormatter.parseEthereumAmountToDouble(output.formattedCryptoAmount ?? 0); totalAmount = output.sendAll @@ -195,7 +203,9 @@ abstract class EthereumWalletBase final pendingEthereumTransaction = await _client.signTransaction( privateKey: _privateKey, - toAddress: _credentials.outputs.first.address, + toAddress: _credentials.outputs.first.isParsedAddress + ? _credentials.outputs.first.extractedAddress! + : _credentials.outputs.first.address, amount: totalAmount.toString(), gas: _estimatedGas!, priority: _credentials.priority!, diff --git a/cw_ethereum/lib/pending_ethereum_transaction.dart b/cw_ethereum/lib/pending_ethereum_transaction.dart index 23dfa3b87..35b0123cc 100644 --- a/cw_ethereum/lib/pending_ethereum_transaction.dart +++ b/cw_ethereum/lib/pending_ethereum_transaction.dart @@ -20,13 +20,19 @@ class PendingEthereumTransaction with PendingTransaction { }); @override - String get amountFormatted => (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString(); + String get amountFormatted { + final _amount = BigInt.parse(amount) / BigInt.from(pow(10, exponent)); + return _amount.toStringAsFixed(min(15, _amount.toString().length)); + } @override Future commit() async => await sendTransaction(); @override - String get feeFormatted => (fee / BigInt.from(pow(10, 18))).toString(); + String get feeFormatted { + final _fee = fee / BigInt.from(pow(10, 18)); + return _fee.toStringAsFixed(min(15, _fee.toString().length)); + } @override String get hex => bytesToHex(signedTransaction, include0x: true); diff --git a/lib/anonpay/anonpay_invoice_info.dart b/lib/anonpay/anonpay_invoice_info.dart index 89613224e..bd6776d00 100644 --- a/lib/anonpay/anonpay_invoice_info.dart +++ b/lib/anonpay/anonpay_invoice_info.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/anonpay/anonpay_info_base.dart'; +import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/keyable.dart'; import 'package:hive/hive.dart'; @@ -35,7 +36,7 @@ class AnonpayInvoiceInfo extends HiveObject with Keyable implements AnonpayInfoB @HiveField(13) final String provider; - static const typeId = 10; + static const typeId = ANONPAY_INVOICE_INFO_TYPE_ID; static const boxName = 'AnonpayInvoiceInfo'; AnonpayInvoiceInfo({ diff --git a/lib/buy/order.dart b/lib/buy/order.dart index 387fbcd34..5a677d291 100644 --- a/lib/buy/order.dart +++ b/lib/buy/order.dart @@ -1,7 +1,8 @@ import 'package:cake_wallet/buy/buy_provider_description.dart'; -import 'package:hive/hive.dart'; import 'package:cake_wallet/exchange/trade_state.dart'; import 'package:cw_core/format_amount.dart'; +import 'package:cw_core/hive_type_ids.dart'; +import 'package:hive/hive.dart'; part 'order.g.dart'; @@ -26,7 +27,7 @@ class Order extends HiveObject { } } - static const typeId = 8; + static const typeId = ORDER_TYPE_ID; static const boxName = 'Orders'; static const boxKey = 'ordersBoxKey'; @@ -66,4 +67,4 @@ class Order extends HiveObject { BuyProviderDescription.deserialize(raw: providerRaw); String amountFormatted() => formatAmount(amount); -} \ No newline at end of file +} diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart index 2e27d83c9..6476891ed 100644 --- a/lib/core/backup_service.dart +++ b/lib/core/backup_service.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; -import 'package:cake_wallet/entities/cake_2fa_preset_options.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; @@ -10,6 +9,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:cryptography/cryptography.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:archive/archive_io.dart'; +import 'package:cw_core/cake_hive.dart'; import 'package:cake_wallet/core/key_service.dart'; import 'package:cake_wallet/entities/encrypt.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; @@ -17,6 +17,7 @@ import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/wallet_types.g.dart'; + import 'package:cake_backup/backup.dart' as cake_backup; class BackupService { @@ -170,14 +171,14 @@ class BackupService { Future> _reloadHiveWalletInfoBox() async { final appDir = await getApplicationDocumentsDirectory(); - await Hive.close(); - Hive.init(appDir.path); + await CakeHive.close(); + CakeHive.init(appDir.path); - if (!Hive.isAdapterRegistered(WalletInfo.typeId)) { - Hive.registerAdapter(WalletInfoAdapter()); + if (!CakeHive.isAdapterRegistered(WalletInfo.typeId)) { + CakeHive.registerAdapter(WalletInfoAdapter()); } - return await Hive.openBox(WalletInfo.boxName); + return await CakeHive.openBox(WalletInfo.boxName); } Future _importPreferencesDump() async { diff --git a/lib/di.dart b/lib/di.dart index b93a41edf..9ef8e7193 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -37,6 +37,8 @@ import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart'; +import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart'; +import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart'; import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart'; import 'package:cake_wallet/themes/theme_list.dart'; import 'package:cake_wallet/utils/device_info.dart'; @@ -870,6 +872,12 @@ Future setup({ getIt.registerFactory(() => SupportPage(getIt.get())); + getIt.registerFactory(() => + SupportChatPage( + getIt.get(), secureStorage: getIt.get())); + + getIt.registerFactory(() => SupportOtherLinksPage(getIt.get())); + getIt.registerFactory(() { final wallet = getIt.get().wallet; diff --git a/lib/entities/contact.dart b/lib/entities/contact.dart index e111429ca..cd4fa55a2 100644 --- a/lib/entities/contact.dart +++ b/lib/entities/contact.dart @@ -1,8 +1,7 @@ -import 'package:flutter/foundation.dart'; -import 'package:hive/hive.dart'; import 'package:cw_core/crypto_currency.dart'; -import 'package:cake_wallet/utils/mobx.dart'; +import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/keyable.dart'; +import 'package:hive/hive.dart'; part 'contact.g.dart'; @@ -14,7 +13,7 @@ class Contact extends HiveObject with Keyable { } } - static const typeId = 0; + static const typeId = CONTACT_TYPE_ID; static const boxName = 'Contacts'; @HiveField(0, defaultValue: '') diff --git a/lib/entities/get_encryption_key.dart b/lib/entities/get_encryption_key.dart index 5fc4983d7..e67380bb8 100644 --- a/lib/entities/get_encryption_key.dart +++ b/lib/entities/get_encryption_key.dart @@ -1,23 +1,18 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:hive/hive.dart'; +import 'package:cw_core/cake_hive.dart'; Future> getEncryptionKey( {required String forKey, required FlutterSecureStorage secureStorage}) async { - final stringifiedKey = - await secureStorage.read(key: 'transactionDescriptionsBoxKey'); + final stringifiedKey = await secureStorage.read(key: 'transactionDescriptionsBoxKey'); List key; if (stringifiedKey == null) { - key = Hive.generateSecureKey(); + key = CakeHive.generateSecureKey(); final keyStringified = key.join(','); - await secureStorage.write( - key: 'transactionDescriptionsBoxKey', value: keyStringified); + await secureStorage.write(key: 'transactionDescriptionsBoxKey', value: keyStringified); } else { - key = stringifiedKey - .split(',') - .map((i) => int.parse(i)) - .toList(); + key = stringifiedKey.split(',').map((i) => int.parse(i)).toList(); } return key; -} \ No newline at end of file +} diff --git a/lib/entities/main_actions.dart b/lib/entities/main_actions.dart index d6a7445f9..912269d8e 100644 --- a/lib/entities/main_actions.dart +++ b/lib/entities/main_actions.dart @@ -47,6 +47,7 @@ class MainActions { case WalletType.bitcoin: case WalletType.litecoin: case WalletType.ethereum: + case WalletType.monero: if (viewModel.isEnabledBuyAction) { final uri = getIt.get().requestUrl(); if (DeviceInfo.instance.isMobile) { @@ -57,13 +58,6 @@ class MainActions { } } break; - case WalletType.monero: - if (viewModel.isEnabledBuyAction) { - // final uri = getIt.get().requestUrl(); - final uri = Uri.parse("https://monero.com/trade"); - await launchUrl(uri); - } - break; default: await showPopUp( context: context, diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 8ac9bb51f..c0eab6d65 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -19,14 +19,19 @@ class AddressResolver { 'crypto', 'zil', 'x', - 'coin', 'wallet', 'bitcoin', '888', 'nft', 'dao', 'blockchain', - 'polygon' + 'polygon', + 'klever', + 'hi', + 'kresus', + 'anime', + 'manga', + 'binanceus' ]; static String? extractAddressByType({required String raw, required CryptoCurrency type}) { diff --git a/lib/entities/template.dart b/lib/entities/template.dart index 6955136e0..7cdd2c74a 100644 --- a/lib/entities/template.dart +++ b/lib/entities/template.dart @@ -1,3 +1,4 @@ +import 'package:cw_core/hive_type_ids.dart'; import 'package:hive/hive.dart'; part 'template.g.dart'; @@ -14,7 +15,7 @@ class Template extends HiveObject { required this.amountFiatRaw, this.additionalRecipientsRaw}); - static const typeId = 6; + static const typeId = TEMPLATE_TYPE_ID; static const boxName = 'Template'; @HiveField(0) diff --git a/lib/entities/transaction_description.dart b/lib/entities/transaction_description.dart index 86d6b043a..088f9c480 100644 --- a/lib/entities/transaction_description.dart +++ b/lib/entities/transaction_description.dart @@ -1,3 +1,4 @@ +import 'package:cw_core/hive_type_ids.dart'; import 'package:hive/hive.dart'; part 'transaction_description.g.dart'; @@ -6,7 +7,7 @@ part 'transaction_description.g.dart'; class TransactionDescription extends HiveObject { TransactionDescription({required this.id, this.recipientAddress, this.transactionNote}); - static const typeId = 2; + static const typeId = TRANSACTION_TYPE_ID; static const boxName = 'TransactionDescriptions'; static const boxKey = 'transactionDescriptionsBoxKey'; diff --git a/lib/exchange/exchange_template.dart b/lib/exchange/exchange_template.dart index dcfd8d8e8..2182efd8c 100644 --- a/lib/exchange/exchange_template.dart +++ b/lib/exchange/exchange_template.dart @@ -1,3 +1,4 @@ +import 'package:cw_core/hive_type_ids.dart'; import 'package:hive/hive.dart'; part 'exchange_template.g.dart'; @@ -14,7 +15,7 @@ class ExchangeTemplate extends HiveObject { required this.depositCurrencyTitleRaw, required this.receiveCurrencyTitleRaw}); - static const typeId = 7; + static const typeId = EXCHANGE_TEMPLATE_TYPE_ID; static const boxName = 'ExchangeTemplate'; @HiveField(0) diff --git a/lib/exchange/trade.dart b/lib/exchange/trade.dart index 70dfa5713..db8c8fb3b 100644 --- a/lib/exchange/trade.dart +++ b/lib/exchange/trade.dart @@ -1,8 +1,9 @@ -import 'package:hive/hive.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/exchange/trade_state.dart'; import 'package:cw_core/format_amount.dart'; +import 'package:cw_core/hive_type_ids.dart'; +import 'package:hive/hive.dart'; part 'trade.g.dart'; @@ -41,7 +42,7 @@ class Trade extends HiveObject { } } - static const typeId = 3; + static const typeId = TRADE_TYPE_ID; static const boxName = 'Trades'; static const boxKey = 'tradesBoxKey'; diff --git a/lib/main.dart b/lib/main.dart index e0cf58e62..62a0bfc9c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:cake_wallet/locales/locale.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart'; +import 'package:cw_core/hive_type_ids.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -38,6 +39,7 @@ import 'package:uni_links/uni_links.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; +import 'package:cw_core/cake_hive.dart'; final navigatorKey = GlobalKey(); final rootKey = GlobalKey(); @@ -57,7 +59,7 @@ Future main() async { return true; }; - await Hive.close(); + await CakeHive.close(); await initializeAppConfigs(); @@ -69,50 +71,50 @@ Future main() async { Future initializeAppConfigs() async { final appDir = await getApplicationDocumentsDirectory(); - Hive.init(appDir.path); + CakeHive.init(appDir.path); - if (!Hive.isAdapterRegistered(Contact.typeId)) { - Hive.registerAdapter(ContactAdapter()); + if (!CakeHive.isAdapterRegistered(Contact.typeId)) { + CakeHive.registerAdapter(ContactAdapter()); } - if (!Hive.isAdapterRegistered(Node.typeId)) { - Hive.registerAdapter(NodeAdapter()); + if (!CakeHive.isAdapterRegistered(Node.typeId)) { + CakeHive.registerAdapter(NodeAdapter()); } - if (!Hive.isAdapterRegistered(TransactionDescription.typeId)) { - Hive.registerAdapter(TransactionDescriptionAdapter()); + if (!CakeHive.isAdapterRegistered(TransactionDescription.typeId)) { + CakeHive.registerAdapter(TransactionDescriptionAdapter()); } - if (!Hive.isAdapterRegistered(Trade.typeId)) { - Hive.registerAdapter(TradeAdapter()); + if (!CakeHive.isAdapterRegistered(Trade.typeId)) { + CakeHive.registerAdapter(TradeAdapter()); } - if (!Hive.isAdapterRegistered(WalletInfo.typeId)) { - Hive.registerAdapter(WalletInfoAdapter()); + if (!CakeHive.isAdapterRegistered(WalletInfo.typeId)) { + CakeHive.registerAdapter(WalletInfoAdapter()); } - if (!Hive.isAdapterRegistered(walletTypeTypeId)) { - Hive.registerAdapter(WalletTypeAdapter()); + if (!CakeHive.isAdapterRegistered(WALLET_TYPE_TYPE_ID)) { + CakeHive.registerAdapter(WalletTypeAdapter()); } - if (!Hive.isAdapterRegistered(Template.typeId)) { - Hive.registerAdapter(TemplateAdapter()); + if (!CakeHive.isAdapterRegistered(Template.typeId)) { + CakeHive.registerAdapter(TemplateAdapter()); } - if (!Hive.isAdapterRegistered(ExchangeTemplate.typeId)) { - Hive.registerAdapter(ExchangeTemplateAdapter()); + if (!CakeHive.isAdapterRegistered(ExchangeTemplate.typeId)) { + CakeHive.registerAdapter(ExchangeTemplateAdapter()); } - if (!Hive.isAdapterRegistered(Order.typeId)) { - Hive.registerAdapter(OrderAdapter()); + if (!CakeHive.isAdapterRegistered(Order.typeId)) { + CakeHive.registerAdapter(OrderAdapter()); } - if (!isMoneroOnly && !Hive.isAdapterRegistered(UnspentCoinsInfo.typeId)) { - Hive.registerAdapter(UnspentCoinsInfoAdapter()); + if (!isMoneroOnly && !CakeHive.isAdapterRegistered(UnspentCoinsInfo.typeId)) { + CakeHive.registerAdapter(UnspentCoinsInfoAdapter()); } - if (!Hive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) { - Hive.registerAdapter(AnonpayInvoiceInfoAdapter()); + if (!CakeHive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) { + CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter()); } final secureStorage = FlutterSecureStorage(); @@ -120,21 +122,21 @@ Future initializeAppConfigs() async { await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey); final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey); final ordersBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Order.boxKey); - final contacts = await Hive.openBox(Contact.boxName); - final nodes = await Hive.openBox(Node.boxName); - final transactionDescriptions = await Hive.openBox( + final contacts = await CakeHive.openBox(Contact.boxName); + final nodes = await CakeHive.openBox(Node.boxName); + final transactionDescriptions = await CakeHive.openBox( TransactionDescription.boxName, encryptionKey: transactionDescriptionsBoxKey); - final trades = await Hive.openBox(Trade.boxName, encryptionKey: tradesBoxKey); - final orders = await Hive.openBox(Order.boxName, encryptionKey: ordersBoxKey); - final walletInfoSource = await Hive.openBox(WalletInfo.boxName); - final templates = await Hive.openBox