From 2c37e427e9eb7e2c882fdd7577f7ab8cfa28c558 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Tue, 12 Nov 2024 04:26:09 +0100 Subject: [PATCH 01/41] Cw 660 add ledger monero (#1747) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix conflicts with main * fix for multiple wallets * Add tron to windows application configuration. * Add macOS option for description message in configure_cake_wallet.sh * Include missed monero dll for windows. * fix conflicts with main * Disable haven configuration for iOS as default. Add ability to configure cakewallet for iOS with for configuration script. Remove cw_shared configuration for cw_monero. * fix: scan fixes, add date, allow sending while scanning * add missing nano secrets file [skip ci] * ios library * don't pull prebuilds android * Add auto generation of manifest file for android project even for iOS, macOS, Windows. * feat: sync fixes, sp settings * feat: fix resyncing * store crash fix * make init async so it won't lag disable print starts * fix monero_c build issues * libstdc++ * Fix MacOS saving wallet file issue Fix Secure Storage issue (somehow) * update pubspec.lock * fix build script * Use dylib as iOS framework. Use custom path for loading of iOS framework for monero.dart. Add script for generate iOS framework for monero wallet. * fix: date from height logic, status disconnected & chain tip get * fix: params * feat: electrum migration if using cake electrum * fix nodes update versions * re-enable tron * update sp_scanner to work on iOS [skip ci] * bump monero_c hash * bump monero_c commit * bump moneroc version * bump monero_c commit * Add ability to build monero wallet lib as universal lib. Update macOS build guide. Change default arch for macOS project to . * fix: wrong socket for old electrum nodes * Fix unchecked wallet type call * get App Dir correctly in default_settings_migration.dart * handle previous issue with fetching linux documents directory [skip ci] * backup fix * fix NTFS issues * Close the wallet when the wallet gets changed * fix: double balance * feat: node domain * fix: menu name * bump monero_c commit * fix: update tip on set scanning * fix: connection switching back and forth * feat: check if node is electrs, and supports sp * chore: fix build * minor enhancements * fixes and enhancements * solve conflicts with main * Only stop wallet on rename and delete * fix: status toggle * minor enhancement * Monero.com fixes * bump monero_c commit * update sp_scanner to include windows and linux * Update macOS build guide. Change brew dependencies for build unbound locally. * fix conflicts and update macos build guide * remove build cache when on gh actions * update secure storage * free up even more storage * free up more storage * Add initial wownero * fix conflicts * fix workflow issue * build wownero * ios and windows changes * macos * complete wownero flow (app side) * add keychain group entitlement and update script for RunnerBase on macos * update secure_storage version to 8.1.0 in configure.dart * add wownero framework * update ios builds * proper path for wownero and monero * finalizing wownero * finalizing wownero * free up even more storage * revert commenting of build gradle configs * revert commenting of secrets [skip ci] * free more storage * minor fixes * link android wownero libraries * bump monero_c commit * wownero fixes * rename target * build_single.sh using clean env * bump monero_c commit * minor fix * Add wownero polyseed * fix conflicts with main * fix: wallet seed display fix: wownero not refreshing * fix: wallet seed display fix: wownero not refreshing * bump monero_c commit * minor fixes * fix: incorrectly displaying XMR instead of WOW * fix: incorrect restore height in wownero * bump monero_c commit * Add Inno Setup Script for windows exe installer * drop libc++_shared.so * fixes from comments * Fix CMake for windows * Merge latest monero dart changes [skip ci] * bump monero_c commit * add wownero to build scripts for macos [skip ci] * add 14 word seed support to wownero * UI fixes for wownero seed restore * minor fixes * reformat code to pass lints * Add debug ledger code * Add Litecoin Hardware Wallet Creation * Add Litecoin Hardware Wallet Creation * Fix Bitcoin not sending on Ledger * Fixes to sending LTC using Ledger * CW-679 Fix merge conflicts * CW-679 Fix merge conflicts * CW-679 Minor fixes * CW-679 Add derivation Path of change address * Add create Monero Wallet from Ledger * bug fix to create Monero Wallet from Ledger * ledger flutter plus refactoring * ledger flutter plus refactoring * ledger flutter plus refactoring * Ups :| * Ups :| I forgot USB * Handle BT Off * Fix Issue with A14 and USB * Small Ledger Quality of life improvements * Small Ledger Quality of life improvements * Small Ledger Quality of life improvements * Small Ledger Quality of life improvements * Small Ledger Quality of life improvements * Small Ledger Quality of life improvements * Small Ledger Quality of life improvements * Pls work * Pls work * Pls work * Pls work * Fix overpopulation * Fix ble device detection and support for Stax and Flex * clean up pubspec * clean up * MWeb merge fix * MWeb merge fix * Migrate to Ledger Flutter Plus * Add connect device page before loading the wallet (Only monero) * Add connect device page before loading the wallet (Only monero) * Fix merge error * Fix merge error * Fix merge error && Allow for wallet switching * Please compile now * Move monero/ledger.dart from monero_c to cw_monero * Upgrade ledger_flutter_plus * Add more popups if action on the device is needed. * Update monero_c dependency hash * Yay ledger monero is even more efficient and avoids memory leaks 🥳 * [skip-ci] more code * Fix Minor Bug * Fix Minor Bug * Apply requested changes * [skip ci] Apply requested changes * Minor Cleanup * Welp I'm dumb :/ * Implement requested changes * Increase ledger refresh speed * Add Monero Ledger keep connection alive * Add Monero Ledger keep connection alive --------- Co-authored-by: OmarHatem Co-authored-by: Czarek Nakamoto Co-authored-by: m Co-authored-by: Rafael Saes Co-authored-by: Matthew Fosse --- build-guide-win.md | 38 + cw_bitcoin/pubspec.lock | 8 +- .../lib/hardware/device_connection_type.dart | 1 + cw_core/lib/wallet_service.dart | 4 + cw_monero/lib/api/wallet.dart | 4 +- cw_monero/lib/api/wallet_manager.dart | 147 +- cw_monero/lib/ledger.dart | 88 + cw_monero/lib/monero_wallet.dart | 7 + cw_monero/lib/monero_wallet_service.dart | 108 +- cw_monero/pubspec.lock | 130 +- cw_monero/pubspec.yaml | 4 +- .../connection_to_node_exception.dart | 5 + cw_wownero/lib/api/structs/account_row.dart | 12 + .../lib/api/structs/coins_info_row.dart | 73 + .../lib/api/structs/subaddress_row.dart | 15 + .../lib/api/structs/transaction_info_row.dart | 41 + cw_wownero/lib/api/structs/ut8_box.dart | 8 + cw_wownero/lib/cw_wownero.dart | 8 + cw_wownero/lib/cw_wownero_method_channel.dart | 17 + .../lib/cw_wownero_platform_interface.dart | 29 + cw_wownero/lib/mywownero.dart | 1689 +++++++++++++++++ cw_wownero/pubspec.lock | 92 +- cw_wownero/pubspec.yaml | 3 +- lib/core/wallet_loading_service.dart | 14 +- lib/di.dart | 15 +- .../require_hardware_wallet_connection.dart | 25 + lib/monero/cw_monero.dart | 25 + .../on_authentication_state_change.dart | 57 +- lib/router.dart | 9 +- .../connect_device/connect_device_page.dart | 66 +- .../monero_hardware_wallet_options_page.dart | 230 +++ .../screens/wallet_list/wallet_list_page.dart | 135 +- .../dashboard/dashboard_view_model.dart | 2 +- .../hardware_wallet/ledger_view_model.dart | 3 + .../wallet_hardware_restore_view_model.dart | 15 +- .../wallet_list/wallet_list_view_model.dart | 19 +- scripts/prepare_moneroc.sh | 4 +- tool/configure.dart | 11 +- 38 files changed, 2912 insertions(+), 249 deletions(-) create mode 100644 build-guide-win.md create mode 100644 cw_monero/lib/ledger.dart create mode 100644 cw_wownero/lib/api/exceptions/connection_to_node_exception.dart create mode 100644 cw_wownero/lib/api/structs/account_row.dart create mode 100644 cw_wownero/lib/api/structs/coins_info_row.dart create mode 100644 cw_wownero/lib/api/structs/subaddress_row.dart create mode 100644 cw_wownero/lib/api/structs/transaction_info_row.dart create mode 100644 cw_wownero/lib/api/structs/ut8_box.dart create mode 100644 cw_wownero/lib/cw_wownero.dart create mode 100644 cw_wownero/lib/cw_wownero_method_channel.dart create mode 100644 cw_wownero/lib/cw_wownero_platform_interface.dart create mode 100644 cw_wownero/lib/mywownero.dart create mode 100644 lib/entities/hardware_wallet/require_hardware_wallet_connection.dart create mode 100644 lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart diff --git a/build-guide-win.md b/build-guide-win.md new file mode 100644 index 000000000..6ace961af --- /dev/null +++ b/build-guide-win.md @@ -0,0 +1,38 @@ +# Building CakeWallet for Windows + +## Requirements and Setup + +The following are the system requirements to build CakeWallet for your Windows PC. + +``` +Windows 10 or later (64-bit), x86-64 based +Flutter 3 or above +``` + +## Building CakeWallet on Windows + +These steps will help you configure and execute a build of CakeWallet from its source code. + +### 1. Installing Package Dependencies + +For build CakeWallet windows application from sources you will be needed to have: +> [Install Flutter]Follow installation guide (https://docs.flutter.dev/get-started/install/windows) and install do not miss to dev tools (install https://docs.flutter.dev/get-started/install/windows/desktop#development-tools) which are required for windows desktop development (need to install Git for Windows and Visual Studio 2022). Then install `Desktop development with C++` packages via GUI Visual Studio 2022, or Visual Studio Build Tools 2022 including: `C++ Build Tools core features`, `C++ 2022 Redistributable Update`, `C++ core desktop features`, `MVC v143 - VS 2022 C++ x64/x86 build tools`, `C++ CMake tools for Windwos`, `Testing tools core features - Build Tools`, `C++ AddressSanitizer`. +> [Install WSL] for building monero dependencies need to install Windows WSL (https://learn.microsoft.com/en-us/windows/wsl/install) and required packages for WSL (Ubuntu): +`$ sudo apt update ` +`$ sudo apt build-essential cmake gcc-mingw-w64 g++-mingw-w64 autoconf libtool pkg-config` + +### 2. Pull CakeWallet source code + +You can downlaod CakeWallet source code from our [GitHub repository](github.com/cake-tech/cake_wallet) via git by following next command: +`$ git clone https://github.com/cake-tech/cake_wallet.git --branch MrCyjaneK-cyjan-monerodart` +OR you can download it as [Zip archive](https://github.com/cake-tech/cake_wallet/archive/refs/heads/MrCyjaneK-cyjan-monerodart.zip) + +### 3. Build Monero, Monero_c and their dependencies + +For use monero in the application need to build Monero wrapper - Monero_C which will be used by monero.dart package. For that need to run shell (bash - typically same named utility should be available after WSL is enabled in your system) with previously installed WSL, then change current directory to the application project directory with your used shell and then change current directory to `scripts/windows`: `$ cd scripts/windows`. Run build script: `$ ./build_all.sh`. + +### 4. Configure and build CakeWallet application + +To configure the application open directory where you have downloaded or unarchived CakeWallet sources and run `cakewallet.bat`. +Or if you used WSL and have active shell session you can run `$ ./cakewallet.sh` script in `scripts/windows` which will run `cakewallet.bat` in WSL. +After execution of `cakewallet.bat` you should to get `Cake Wallet.zip` in project root directory which will contains `CakeWallet.exe` file and another needed files for run the application. Now you can extract files from `Cake Wallet.zip` archive and run the application. diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index 0e4921a3a..8eafb2a44 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -386,10 +386,10 @@ packages: dependency: transitive description: name: flutter_web_bluetooth - sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02" + sha256: fcd03e2e5f82edcedcbc940f1b6a0635a50757374183254f447640886c53208e url: "https://pub.dev" source: hosted - version: "0.2.3" + version: "0.2.4" flutter_web_plugins: dependency: transitive description: flutter @@ -560,7 +560,7 @@ packages: description: path: "packages/ledger-bitcoin" ref: HEAD - resolved-ref: dbb5c4956949dc734af3fc8febdbabed89da72aa + resolved-ref: "07cd61ef76a2a017b6d5ef233396740163265457" url: "https://github.com/cake-tech/ledger-flutter-plus-plugins" source: git version: "0.0.3" @@ -577,7 +577,7 @@ packages: description: path: "packages/ledger-litecoin" ref: HEAD - resolved-ref: dbb5c4956949dc734af3fc8febdbabed89da72aa + resolved-ref: "07cd61ef76a2a017b6d5ef233396740163265457" url: "https://github.com/cake-tech/ledger-flutter-plus-plugins" source: git version: "0.0.2" diff --git a/cw_core/lib/hardware/device_connection_type.dart b/cw_core/lib/hardware/device_connection_type.dart index 9a3069552..76a501af1 100644 --- a/cw_core/lib/hardware/device_connection_type.dart +++ b/cw_core/lib/hardware/device_connection_type.dart @@ -7,6 +7,7 @@ enum DeviceConnectionType { static List supportedConnectionTypes(WalletType walletType, [bool isIOS = false]) { switch (walletType) { + case WalletType.monero: case WalletType.bitcoin: case WalletType.litecoin: case WalletType.ethereum: diff --git a/cw_core/lib/wallet_service.dart b/cw_core/lib/wallet_service.dart index d90ae30bc..85126853e 100644 --- a/cw_core/lib/wallet_service.dart +++ b/cw_core/lib/wallet_service.dart @@ -61,4 +61,8 @@ abstract class WalletService false; } diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 8e03cff3e..928fd7ef1 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -119,7 +119,7 @@ Future setupNodeSync( daemonUsername: login ?? '', daemonPassword: password ?? ''); }); - // monero.Wallet_init3(wptr!, argv0: '', defaultLogBaseName: 'moneroc', console: true); + // monero.Wallet_init3(wptr!, argv0: '', defaultLogBaseName: 'moneroc', console: true, logPath: ''); final status = monero.Wallet_status(wptr!); @@ -330,4 +330,4 @@ String signMessage(String message, {String address = ""}) { bool verifyMessage(String message, String address, String signature) { return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature); -} \ No newline at end of file +} diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart index 61fd6edf0..7f9dbd8fa 100644 --- a/cw_monero/lib/api/wallet_manager.dart +++ b/cw_monero/lib/api/wallet_manager.dart @@ -7,19 +7,18 @@ import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart'; -import 'package:cw_monero/api/wallet.dart'; import 'package:cw_monero/api/transaction_history.dart'; +import 'package:cw_monero/api/wallet.dart'; +import 'package:cw_monero/ledger.dart'; import 'package:monero/monero.dart' as monero; class MoneroCException implements Exception { final String message; MoneroCException(this.message); - + @override - String toString() { - return message; - } + String toString() => message; } void checkIfMoneroCIsFine() { @@ -43,7 +42,6 @@ void checkIfMoneroCIsFine() { throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'"); } } - monero.WalletManager? _wmPtr; final monero.WalletManager wmPtr = Pointer.fromAddress((() { try { @@ -60,6 +58,13 @@ final monero.WalletManager wmPtr = Pointer.fromAddress((() { return _wmPtr!.address; })()); +void createWalletPointer() { + final newWptr = monero.WalletManager_createWallet(wmPtr, + path: "", password: "", language: "", networkType: 0); + + wptr = newWptr; +} + void createWalletSync( {required String path, required String password, @@ -124,24 +129,24 @@ void restoreWalletFromKeysSync( int restoreHeight = 0}) { txhistory = null; var newWptr = (spendKey != "") - ? monero.WalletManager_createDeterministicWalletFromSpendKey( - wmPtr, - path: path, - password: password, - language: language, - spendKeyString: spendKey, - newWallet: true, // TODO(mrcyjanek): safe to remove - restoreHeight: restoreHeight) - : monero.WalletManager_createWalletFromKeys( - wmPtr, - path: path, - password: password, - restoreHeight: restoreHeight, - addressString: address, - viewKeyString: viewKey, - spendKeyString: spendKey, - nettype: 0, - ); + ? monero.WalletManager_createDeterministicWalletFromSpendKey(wmPtr, + path: path, + password: password, + language: language, + spendKeyString: spendKey, + newWallet: true, + // TODO(mrcyjanek): safe to remove + restoreHeight: restoreHeight) + : monero.WalletManager_createWalletFromKeys( + wmPtr, + path: path, + password: password, + restoreHeight: restoreHeight, + addressString: address, + viewKeyString: viewKey, + spendKeyString: spendKey, + nettype: 0, + ); final status = monero.Wallet_status(newWptr); if (status != 0) { @@ -156,7 +161,7 @@ void restoreWalletFromKeysSync( if (viewKey != viewKeyRestored && viewKey != "") { monero.WalletManager_closeWallet(wmPtr, newWptr, false); File(path).deleteSync(); - File(path+".keys").deleteSync(); + File(path + ".keys").deleteSync(); newWptr = monero.WalletManager_createWalletFromKeys( wmPtr, path: path, @@ -199,7 +204,7 @@ void restoreWalletFromSpendKeySync( // viewKeyString: '', // nettype: 0, // ); - + txhistory = null; final newWptr = monero.WalletManager_createDeterministicWalletFromSpendKey( wmPtr, @@ -230,41 +235,39 @@ void restoreWalletFromSpendKeySync( String _lastOpenedWallet = ""; -// void restoreMoneroWalletFromDevice( -// {required String path, -// required String password, -// required String deviceName, -// int nettype = 0, -// int restoreHeight = 0}) { -// -// final pathPointer = path.toNativeUtf8(); -// final passwordPointer = password.toNativeUtf8(); -// final deviceNamePointer = deviceName.toNativeUtf8(); -// final errorMessagePointer = ''.toNativeUtf8(); -// -// final isWalletRestored = restoreWalletFromDeviceNative( -// pathPointer, -// passwordPointer, -// deviceNamePointer, -// nettype, -// restoreHeight, -// errorMessagePointer) != 0; -// -// calloc.free(pathPointer); -// calloc.free(passwordPointer); -// -// storeSync(); -// -// if (!isWalletRestored) { -// throw WalletRestoreFromKeysException( -// message: convertUTF8ToString(pointer: errorMessagePointer)); -// } -// } +Future restoreWalletFromHardwareWallet( + {required String path, + required String password, + required String deviceName, + int nettype = 0, + int restoreHeight = 0}) async { + txhistory = null; + + final newWptrAddr = await Isolate.run(() { + return monero.WalletManager_createWalletFromDevice(wmPtr, + path: path, + password: password, + restoreHeight: restoreHeight, + deviceName: deviceName) + .address; + }); + final newWptr = Pointer.fromAddress(newWptrAddr); + + final status = monero.Wallet_status(newWptr); + + if (status != 0) { + final error = monero.Wallet_errorString(newWptr); + throw WalletRestoreFromSeedException(message: error); + } + wptr = newWptr; + + openedWalletsByPath[path] = wptr!; +} Map openedWalletsByPath = {}; -void loadWallet( - {required String path, required String password, int nettype = 0}) { +Future loadWallet( + {required String path, required String password, int nettype = 0}) async { if (openedWalletsByPath[path] != null) { txhistory = null; wptr = openedWalletsByPath[path]!; @@ -278,8 +281,29 @@ void loadWallet( }); } txhistory = null; - final newWptr = monero.WalletManager_openWallet(wmPtr, - path: path, password: password); + + /// Get the device type + /// 0: Software Wallet + /// 1: Ledger + /// 2: Trezor + final deviceType = monero.WalletManager_queryWalletDevice(wmPtr, + keysFileName: "$path.keys", password: password, kdfRounds: 1); + + if (deviceType == 1) { + final dummyWPtr = wptr ?? + monero.WalletManager_openWallet(wmPtr, path: '', password: ''); + enableLedgerExchange(dummyWPtr, gLedger!); + } + + final addr = wmPtr.address; + final newWptrAddr = await Isolate.run(() { + return monero.WalletManager_openWallet(Pointer.fromAddress(addr), + path: path, password: password) + .address; + }); + + final newWptr = Pointer.fromAddress(newWptrAddr); + _lastOpenedWallet = path; final status = monero.Wallet_status(newWptr); if (status != 0) { @@ -287,6 +311,7 @@ void loadWallet( print(err); throw WalletOpeningException(message: err); } + wptr = newWptr; openedWalletsByPath[path] = wptr!; } @@ -351,7 +376,7 @@ Future _openWallet(Map args) async => loadWallet( bool _isWalletExist(String path) => isWalletExistSync(path: path); -void openWallet( +Future openWallet( {required String path, required String password, int nettype = 0}) async => diff --git a/cw_monero/lib/ledger.dart b/cw_monero/lib/ledger.dart new file mode 100644 index 000000000..074975df3 --- /dev/null +++ b/cw_monero/lib/ledger.dart @@ -0,0 +1,88 @@ +import 'dart:async'; +import 'dart:ffi'; +import 'dart:typed_data'; + +import 'package:ffi/ffi.dart'; +import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; +import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart'; +import 'package:monero/monero.dart' as monero; +// import 'package:polyseed/polyseed.dart'; + +LedgerConnection? gLedger; + +Timer? _ledgerExchangeTimer; +Timer? _ledgerKeepAlive; + +void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) { + _ledgerExchangeTimer?.cancel(); + _ledgerExchangeTimer = Timer.periodic(Duration(milliseconds: 1), (_) async { + final ledgerRequestLength = monero.Wallet_getSendToDeviceLength(ptr); + final ledgerRequest = monero.Wallet_getSendToDevice(ptr) + .cast() + .asTypedList(ledgerRequestLength); + if (ledgerRequestLength > 0) { + _ledgerKeepAlive?.cancel(); + + final Pointer emptyPointer = malloc(0); + monero.Wallet_setDeviceSendData( + ptr, emptyPointer.cast(), 0); + malloc.free(emptyPointer); + + // print("> ${ledgerRequest.toHexString()}"); + final response = await exchange(connection, ledgerRequest); + // print("< ${response.toHexString()}"); + + final Pointer result = malloc(response.length); + for (var i = 0; i < response.length; i++) { + result.asTypedList(response.length)[i] = response[i]; + } + + monero.Wallet_setDeviceReceivedData( + ptr, result.cast(), response.length); + malloc.free(result); + keepAlive(connection); + } + }); +} + +void keepAlive(LedgerConnection connection) { + if (connection.connectionType == ConnectionType.ble) { + UniversalBle.onConnectionChange = (String deviceId, bool isConnected) { + print("[Monero] Ledger Disconnected"); + _ledgerKeepAlive?.cancel(); + }; + _ledgerKeepAlive = Timer.periodic(Duration(seconds: 10), (_) async { + try { + UniversalBle.setNotifiable( + connection.device.id, + connection.device.deviceInfo.serviceId, + connection.device.deviceInfo.notifyCharacteristicKey, + BleInputProperty.notification, + ); + } catch (_){} + }); + } +} + +void disableLedgerExchange() { + _ledgerExchangeTimer?.cancel(); + _ledgerKeepAlive?.cancel(); + gLedger?.disconnect(); + gLedger = null; +} + +Future exchange(LedgerConnection connection, Uint8List data) async => + connection.sendOperation(ExchangeOperation(data)); + +class ExchangeOperation extends LedgerRawOperation { + final Uint8List inputData; + + ExchangeOperation(this.inputData); + + @override + Future read(ByteDataReader reader) async => + reader.read(reader.remainingLength); + + @override + Future> write(ByteDataWriter writer) async => [inputData]; +} diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index bc8c3c94d..5f53b30ba 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -28,6 +28,7 @@ import 'package:cw_monero/api/wallet.dart' as monero_wallet; import 'package:cw_monero/api/wallet_manager.dart'; import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart'; import 'package:cw_monero/exceptions/monero_transaction_no_inputs_exception.dart'; +import 'package:cw_monero/ledger.dart'; import 'package:cw_monero/monero_transaction_creation_credentials.dart'; import 'package:cw_monero/monero_transaction_history.dart'; import 'package:cw_monero/monero_transaction_info.dart'; @@ -36,6 +37,7 @@ import 'package:cw_monero/monero_wallet_addresses.dart'; import 'package:cw_monero/pending_monero_transaction.dart'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; +import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; import 'package:mobx/mobx.dart'; import 'package:monero/monero.dart' as monero; @@ -828,4 +830,9 @@ abstract class MoneroWalletBase extends WalletBase { + MoneroRestoreWalletFromHardwareCredentials> { MoneroWalletService(this.walletInfoSource, this.unspentCoinsInfoSource); final Box walletInfoSource; @@ -81,7 +92,7 @@ class MoneroWalletService extends WalletService< final lang = PolyseedLang.getByEnglishName(credentials.language); final heightOverride = - getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2))); + getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2))); return _restoreFromPolyseed( path, credentials.password!, polyseed, credentials.walletInfo!, lang, @@ -91,9 +102,9 @@ class MoneroWalletService extends WalletService< await monero_wallet_manager.createWallet( path: path, password: credentials.password!, language: credentials.language); final wallet = MoneroWallet( - walletInfo: credentials.walletInfo!, - unspentCoinsInfo: unspentCoinsInfoSource, - password: credentials.password!); + walletInfo: credentials.walletInfo!, + unspentCoinsInfo: unspentCoinsInfoSource, + password: credentials.password!); await wallet.init(); return wallet; @@ -128,11 +139,11 @@ class MoneroWalletService extends WalletService< await monero_wallet_manager .openWalletAsync({'path': path, 'password': password}); final walletInfo = walletInfoSource.values.firstWhere( - (info) => info.id == WalletBase.idFor(name, getType())); + (info) => info.id == WalletBase.idFor(name, getType())); final wallet = MoneroWallet( - walletInfo: walletInfo, - unspentCoinsInfo: unspentCoinsInfoSource, - password: password); + walletInfo: walletInfo, + unspentCoinsInfo: unspentCoinsInfoSource, + password: password); final isValid = wallet.walletAddresses.validate(); if (!isValid) { @@ -185,10 +196,9 @@ class MoneroWalletService extends WalletService< } @override - Future rename( - String currentName, String password, String newName) async { + Future rename(String currentName, String password, String newName) async { final currentWalletInfo = walletInfoSource.values.firstWhere( - (info) => info.id == WalletBase.idFor(currentName, getType())); + (info) => info.id == WalletBase.idFor(currentName, getType())); final currentWallet = MoneroWallet( walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource, @@ -218,9 +228,9 @@ class MoneroWalletService extends WalletService< viewKey: credentials.viewKey, spendKey: credentials.spendKey); final wallet = MoneroWallet( - walletInfo: credentials.walletInfo!, - unspentCoinsInfo: unspentCoinsInfoSource, - password: credentials.password!); + walletInfo: credentials.walletInfo!, + unspentCoinsInfo: unspentCoinsInfoSource, + password: credentials.password!); await wallet.init(); return wallet; @@ -232,9 +242,34 @@ class MoneroWalletService extends WalletService< } @override - Future restoreFromHardwareWallet(MoneroNewWalletCredentials credentials) { - throw UnimplementedError( - "Restoring a Monero wallet from a hardware wallet is not yet supported!"); + Future restoreFromHardwareWallet( + MoneroRestoreWalletFromHardwareCredentials credentials) async { + try { + final path = await pathForWallet(name: credentials.name, type: getType()); + final password = credentials.password; + final height = credentials.height; + + if (wptr == null ) monero_wallet_manager.createWalletPointer(); + + enableLedgerExchange(wptr!, credentials.ledgerConnection); + await monero_wallet_manager.restoreWalletFromHardwareWallet( + path: path, + password: password!, + restoreHeight: height!, + deviceName: 'Ledger'); + + final wallet = MoneroWallet( + walletInfo: credentials.walletInfo!, + unspentCoinsInfo: unspentCoinsInfoSource, + password: credentials.password!); + await wallet.init(); + + return wallet; + } catch (e) { + // TODO: Implement Exception for wallet list service. + print('MoneroWalletsManager Error: $e'); + rethrow; + } } @override @@ -253,9 +288,9 @@ class MoneroWalletService extends WalletService< seed: credentials.mnemonic, restoreHeight: credentials.height!); final wallet = MoneroWallet( - walletInfo: credentials.walletInfo!, - unspentCoinsInfo: unspentCoinsInfoSource, - password: credentials.password!); + walletInfo: credentials.walletInfo!, + unspentCoinsInfo: unspentCoinsInfoSource, + password: credentials.password!); await wallet.init(); return wallet; @@ -283,8 +318,8 @@ class MoneroWalletService extends WalletService< } } - Future _restoreFromPolyseed( - String path, String password, Polyseed polyseed, WalletInfo walletInfo, PolyseedLang lang, + Future _restoreFromPolyseed(String path, String password, Polyseed polyseed, + WalletInfo walletInfo, PolyseedLang lang, {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight}) async { final height = overrideHeight ?? getMoneroHeigthByDate(date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000)); @@ -329,7 +364,9 @@ class MoneroWalletService extends WalletService< dir.listSync().forEach((f) { final file = File(f.path); - final name = f.path.split('/').last; + final name = f.path + .split('/') + .last; final newPath = newWalletDirPath + '/$name'; final newFile = File(newPath); @@ -366,4 +403,11 @@ class MoneroWalletService extends WalletService< return ''; } } + + @override + bool requireHardwareWalletConnection(String name) { + final walletInfo = walletInfoSource.values + .firstWhere((info) => info.id == WalletBase.idFor(name, getType())); + return walletInfo.isHardwareWallet; + } } diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index ee1d48df1..a6a03dce5 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -29,10 +29,10 @@ packages: dependency: transitive description: name: asn1lib - sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda" + sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70" url: "https://pub.dev" source: hosted - version: "1.5.3" + version: "1.5.5" async: dependency: transitive description: @@ -41,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + bluez: + dependency: transitive + description: + name: bluez + sha256: "203a1924e818a9dd74af2b2c7a8f375ab8e5edf0e486bba8f90a0d8a17ed9fce" + url: "https://pub.dev" + source: hosted + version: "0.8.2" boolean_selector: dependency: transitive description: @@ -209,6 +217,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.4" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" encrypt: dependency: "direct main" description: @@ -229,10 +245,10 @@ packages: dependency: "direct main" description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" file: dependency: transitive description: @@ -267,6 +283,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_bluetooth: + dependency: transitive + description: + name: flutter_web_bluetooth + sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02" + url: "https://pub.dev" + source: hosted + version: "0.2.3" frontend_server_client: dependency: transitive description: @@ -295,18 +319,18 @@ packages: dependency: transitive description: name: hashlib - sha256: d41795742c10947930630118c6836608deeb9047cd05aee32d2baeb697afd66a + sha256: f572f2abce09fc7aee53f15927052b9732ea1053e540af8cae211111ee0b99b1 url: "https://pub.dev" source: hosted - version: "1.19.2" + version: "1.21.0" hashlib_codecs: dependency: transitive description: name: hashlib_codecs - sha256: "2b570061f5a4b378425be28a576c1e11783450355ad4345a19f606ff3d96db0f" + sha256: "8cea9ccafcfeaa7324d2ae52c61c69f7ff71f4237507a018caab31b9e416e3b1" url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" hive: dependency: transitive description: @@ -327,10 +351,10 @@ packages: dependency: "direct main" description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -403,6 +427,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + ledger_flutter_plus: + dependency: "direct main" + description: + name: ledger_flutter_plus + sha256: c7b04008553193dbca7e17b430768eecc372a72b0ff3625b5e7fc5e5c8d3231b + url: "https://pub.dev" + source: hosted + version: "1.4.1" + ledger_usb_plus: + dependency: transitive + description: + name: ledger_usb_plus + sha256: "21cc5d976cf7edb3518bd2a0c4164139cbb0817d2e4f2054707fc4edfdf9ce87" + url: "https://pub.dev" + source: hosted + version: "1.0.4" logging: dependency: transitive description: @@ -439,10 +479,10 @@ packages: dependency: transitive description: name: mime - sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.6" mobx: dependency: "direct main" description: @@ -463,8 +503,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b" - resolved-ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b" + ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b + resolved-ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" @@ -504,10 +544,10 @@ packages: dependency: "direct main" description: name: path_provider - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" path_provider_android: dependency: transitive description: @@ -544,10 +584,18 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" platform: dependency: transitive description: @@ -612,6 +660,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" shelf: dependency: transitive description: @@ -737,6 +793,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + universal_ble: + dependency: transitive + description: + name: universal_ble + sha256: "0dfbd6b64bff3ad61ed7a895c232530d9614e9b01ab261a74433a43267edb7f3" + url: "https://pub.dev" + source: hosted + version: "0.12.0" + universal_platform: + dependency: transitive + description: + name: universal_platform + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" + url: "https://pub.dev" + source: hosted + version: "1.1.0" unorm_dart: dependency: transitive description: @@ -785,22 +857,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.5" - win32: - dependency: transitive - description: - name: win32 - sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb" - url: "https://pub.dev" - source: hosted - version: "5.5.0" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" yaml: dependency: transitive description: @@ -811,4 +883,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=3.16.6" + flutter: ">=3.19.0" diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml index cb1f5519f..6fa235ee4 100644 --- a/cw_monero/pubspec.yaml +++ b/cw_monero/pubspec.yaml @@ -25,9 +25,11 @@ dependencies: monero: git: url: https://github.com/mrcyjanek/monero_c - ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash + ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b +# ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash path: impls/monero.dart mutex: ^3.1.0 + ledger_flutter_plus: ^1.4.1 dev_dependencies: flutter_test: diff --git a/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart b/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart new file mode 100644 index 000000000..483b0a174 --- /dev/null +++ b/cw_wownero/lib/api/exceptions/connection_to_node_exception.dart @@ -0,0 +1,5 @@ +class ConnectionToNodeException implements Exception { + ConnectionToNodeException({required this.message}); + + final String message; +} \ No newline at end of file diff --git a/cw_wownero/lib/api/structs/account_row.dart b/cw_wownero/lib/api/structs/account_row.dart new file mode 100644 index 000000000..aa492ee0f --- /dev/null +++ b/cw_wownero/lib/api/structs/account_row.dart @@ -0,0 +1,12 @@ +import 'dart:ffi'; +import 'package:ffi/ffi.dart'; + +class AccountRow extends Struct { + @Int64() + external int id; + + external Pointer label; + + String getLabel() => label.toDartString(); + int getId() => id; +} diff --git a/cw_wownero/lib/api/structs/coins_info_row.dart b/cw_wownero/lib/api/structs/coins_info_row.dart new file mode 100644 index 000000000..ff6f6ce73 --- /dev/null +++ b/cw_wownero/lib/api/structs/coins_info_row.dart @@ -0,0 +1,73 @@ +import 'dart:ffi'; +import 'package:ffi/ffi.dart'; + +class CoinsInfoRow extends Struct { + @Int64() + external int blockHeight; + + external Pointer hash; + + @Uint64() + external int internalOutputIndex; + + @Uint64() + external int globalOutputIndex; + + @Int8() + external int spent; + + @Int8() + external int frozen; + + @Uint64() + external int spentHeight; + + @Uint64() + external int amount; + + @Int8() + external int rct; + + @Int8() + external int keyImageKnown; + + @Uint64() + external int pkIndex; + + @Uint32() + external int subaddrIndex; + + @Uint32() + external int subaddrAccount; + + external Pointer address; + + external Pointer addressLabel; + + external Pointer keyImage; + + @Uint64() + external int unlockTime; + + @Int8() + external int unlocked; + + external Pointer pubKey; + + @Int8() + external int coinbase; + + external Pointer description; + + String getHash() => hash.toDartString(); + + String getAddress() => address.toDartString(); + + String getAddressLabel() => addressLabel.toDartString(); + + String getKeyImage() => keyImage.toDartString(); + + String getPubKey() => pubKey.toDartString(); + + String getDescription() => description.toDartString(); +} diff --git a/cw_wownero/lib/api/structs/subaddress_row.dart b/cw_wownero/lib/api/structs/subaddress_row.dart new file mode 100644 index 000000000..d593a793d --- /dev/null +++ b/cw_wownero/lib/api/structs/subaddress_row.dart @@ -0,0 +1,15 @@ +import 'dart:ffi'; +import 'package:ffi/ffi.dart'; + +class SubaddressRow extends Struct { + @Int64() + external int id; + + external Pointer address; + + external Pointer label; + + String getLabel() => label.toDartString(); + String getAddress() => address.toDartString(); + int getId() => id; +} \ No newline at end of file diff --git a/cw_wownero/lib/api/structs/transaction_info_row.dart b/cw_wownero/lib/api/structs/transaction_info_row.dart new file mode 100644 index 000000000..bdcc64d3f --- /dev/null +++ b/cw_wownero/lib/api/structs/transaction_info_row.dart @@ -0,0 +1,41 @@ +import 'dart:ffi'; +import 'package:ffi/ffi.dart'; + +class TransactionInfoRow extends Struct { + @Uint64() + external int amount; + + @Uint64() + external int fee; + + @Uint64() + external int blockHeight; + + @Uint64() + external int confirmations; + + @Uint32() + external int subaddrAccount; + + @Int8() + external int direction; + + @Int8() + external int isPending; + + @Uint32() + external int subaddrIndex; + + external Pointer hash; + + external Pointer paymentId; + + @Int64() + external int datetime; + + int getDatetime() => datetime; + int getAmount() => amount >= 0 ? amount : amount * -1; + bool getIsPending() => isPending != 0; + String getHash() => hash.toDartString(); + String getPaymentId() => paymentId.toDartString(); +} diff --git a/cw_wownero/lib/api/structs/ut8_box.dart b/cw_wownero/lib/api/structs/ut8_box.dart new file mode 100644 index 000000000..53e678c88 --- /dev/null +++ b/cw_wownero/lib/api/structs/ut8_box.dart @@ -0,0 +1,8 @@ +import 'dart:ffi'; +import 'package:ffi/ffi.dart'; + +class Utf8Box extends Struct { + external Pointer value; + + String getValue() => value.toDartString(); +} diff --git a/cw_wownero/lib/cw_wownero.dart b/cw_wownero/lib/cw_wownero.dart new file mode 100644 index 000000000..33a55e305 --- /dev/null +++ b/cw_wownero/lib/cw_wownero.dart @@ -0,0 +1,8 @@ + +import 'cw_wownero_platform_interface.dart'; + +class CwWownero { + Future getPlatformVersion() { + return CwWowneroPlatform.instance.getPlatformVersion(); + } +} diff --git a/cw_wownero/lib/cw_wownero_method_channel.dart b/cw_wownero/lib/cw_wownero_method_channel.dart new file mode 100644 index 000000000..d797f5f81 --- /dev/null +++ b/cw_wownero/lib/cw_wownero_method_channel.dart @@ -0,0 +1,17 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import 'cw_wownero_platform_interface.dart'; + +/// An implementation of [CwWowneroPlatform] that uses method channels. +class MethodChannelCwWownero extends CwWowneroPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('cw_wownero'); + + @override + Future getPlatformVersion() async { + final version = await methodChannel.invokeMethod('getPlatformVersion'); + return version; + } +} diff --git a/cw_wownero/lib/cw_wownero_platform_interface.dart b/cw_wownero/lib/cw_wownero_platform_interface.dart new file mode 100644 index 000000000..78b21592c --- /dev/null +++ b/cw_wownero/lib/cw_wownero_platform_interface.dart @@ -0,0 +1,29 @@ +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'cw_wownero_method_channel.dart'; + +abstract class CwWowneroPlatform extends PlatformInterface { + /// Constructs a CwWowneroPlatform. + CwWowneroPlatform() : super(token: _token); + + static final Object _token = Object(); + + static CwWowneroPlatform _instance = MethodChannelCwWownero(); + + /// The default instance of [CwWowneroPlatform] to use. + /// + /// Defaults to [MethodChannelCwWownero]. + static CwWowneroPlatform get instance => _instance; + + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [CwWowneroPlatform] when + /// they register themselves. + static set instance(CwWowneroPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + Future getPlatformVersion() { + throw UnimplementedError('platformVersion() has not been implemented.'); + } +} diff --git a/cw_wownero/lib/mywownero.dart b/cw_wownero/lib/mywownero.dart new file mode 100644 index 000000000..d50e48b64 --- /dev/null +++ b/cw_wownero/lib/mywownero.dart @@ -0,0 +1,1689 @@ +const prefixLength = 3; + +String swapEndianBytes(String original) { + if (original.length != 8) { + return ''; + } + + return original[6] + + original[7] + + original[4] + + original[5] + + original[2] + + original[3] + + original[0] + + original[1]; +} + +List tructWords(List wordSet) { + final start = 0; + final end = prefixLength; + + return wordSet.map((word) => word.substring(start, end)).toList(); +} + +String mnemonicDecode(String seed) { + final n = englistWordSet.length; + var out = ''; + var wlist = seed.split(' '); + wlist.removeLast(); + + for (var i = 0; i < wlist.length; i += 3) { + final w1 = + tructWords(englistWordSet).indexOf(wlist[i].substring(0, prefixLength)); + final w2 = tructWords(englistWordSet) + .indexOf(wlist[i + 1].substring(0, prefixLength)); + final w3 = tructWords(englistWordSet) + .indexOf(wlist[i + 2].substring(0, prefixLength)); + + if (w1 == -1 || w2 == -1 || w3 == -1) { + print("invalid word in mnemonic"); + return ''; + } + + final x = w1 + n * (((n - w1) + w2) % n) + n * n * (((n - w2) + w3) % n); + + if (x % n != w1) { + print("Something went wrong when decoding your private key, please try again"); + return ''; + } + + final _res = '0000000' + x.toRadixString(16); + final start = _res.length - 8; + final end = _res.length; + final res = _res.substring(start, end); + + out += swapEndianBytes(res); + } + + return out; +} + +final englistWordSet = [ + "abbey", + "abducts", + "ability", + "ablaze", + "abnormal", + "abort", + "abrasive", + "absorb", + "abyss", + "academy", + "aces", + "aching", + "acidic", + "acoustic", + "acquire", + "across", + "actress", + "acumen", + "adapt", + "addicted", + "adept", + "adhesive", + "adjust", + "adopt", + "adrenalin", + "adult", + "adventure", + "aerial", + "afar", + "affair", + "afield", + "afloat", + "afoot", + "afraid", + "after", + "against", + "agenda", + "aggravate", + "agile", + "aglow", + "agnostic", + "agony", + "agreed", + "ahead", + "aided", + "ailments", + "aimless", + "airport", + "aisle", + "ajar", + "akin", + "alarms", + "album", + "alchemy", + "alerts", + "algebra", + "alkaline", + "alley", + "almost", + "aloof", + "alpine", + "already", + "also", + "altitude", + "alumni", + "always", + "amaze", + "ambush", + "amended", + "amidst", + "ammo", + "amnesty", + "among", + "amply", + "amused", + "anchor", + "android", + "anecdote", + "angled", + "ankle", + "annoyed", + "answers", + "antics", + "anvil", + "anxiety", + "anybody", + "apart", + "apex", + "aphid", + "aplomb", + "apology", + "apply", + "apricot", + "aptitude", + "aquarium", + "arbitrary", + "archer", + "ardent", + "arena", + "argue", + "arises", + "army", + "around", + "arrow", + "arsenic", + "artistic", + "ascend", + "ashtray", + "aside", + "asked", + "asleep", + "aspire", + "assorted", + "asylum", + "athlete", + "atlas", + "atom", + "atrium", + "attire", + "auburn", + "auctions", + "audio", + "august", + "aunt", + "austere", + "autumn", + "avatar", + "avidly", + "avoid", + "awakened", + "awesome", + "awful", + "awkward", + "awning", + "awoken", + "axes", + "axis", + "axle", + "aztec", + "azure", + "baby", + "bacon", + "badge", + "baffles", + "bagpipe", + "bailed", + "bakery", + "balding", + "bamboo", + "banjo", + "baptism", + "basin", + "batch", + "bawled", + "bays", + "because", + "beer", + "befit", + "begun", + "behind", + "being", + "below", + "bemused", + "benches", + "berries", + "bested", + "betting", + "bevel", + "beware", + "beyond", + "bias", + "bicycle", + "bids", + "bifocals", + "biggest", + "bikini", + "bimonthly", + "binocular", + "biology", + "biplane", + "birth", + "biscuit", + "bite", + "biweekly", + "blender", + "blip", + "bluntly", + "boat", + "bobsled", + "bodies", + "bogeys", + "boil", + "boldly", + "bomb", + "border", + "boss", + "both", + "bounced", + "bovine", + "bowling", + "boxes", + "boyfriend", + "broken", + "brunt", + "bubble", + "buckets", + "budget", + "buffet", + "bugs", + "building", + "bulb", + "bumper", + "bunch", + "business", + "butter", + "buying", + "buzzer", + "bygones", + "byline", + "bypass", + "cabin", + "cactus", + "cadets", + "cafe", + "cage", + "cajun", + "cake", + "calamity", + "camp", + "candy", + "casket", + "catch", + "cause", + "cavernous", + "cease", + "cedar", + "ceiling", + "cell", + "cement", + "cent", + "certain", + "chlorine", + "chrome", + "cider", + "cigar", + "cinema", + "circle", + "cistern", + "citadel", + "civilian", + "claim", + "click", + "clue", + "coal", + "cobra", + "cocoa", + "code", + "coexist", + "coffee", + "cogs", + "cohesive", + "coils", + "colony", + "comb", + "cool", + "copy", + "corrode", + "costume", + "cottage", + "cousin", + "cowl", + "criminal", + "cube", + "cucumber", + "cuddled", + "cuffs", + "cuisine", + "cunning", + "cupcake", + "custom", + "cycling", + "cylinder", + "cynical", + "dabbing", + "dads", + "daft", + "dagger", + "daily", + "damp", + "dangerous", + "dapper", + "darted", + "dash", + "dating", + "dauntless", + "dawn", + "daytime", + "dazed", + "debut", + "decay", + "dedicated", + "deepest", + "deftly", + "degrees", + "dehydrate", + "deity", + "dejected", + "delayed", + "demonstrate", + "dented", + "deodorant", + "depth", + "desk", + "devoid", + "dewdrop", + "dexterity", + "dialect", + "dice", + "diet", + "different", + "digit", + "dilute", + "dime", + "dinner", + "diode", + "diplomat", + "directed", + "distance", + "ditch", + "divers", + "dizzy", + "doctor", + "dodge", + "does", + "dogs", + "doing", + "dolphin", + "domestic", + "donuts", + "doorway", + "dormant", + "dosage", + "dotted", + "double", + "dove", + "down", + "dozen", + "dreams", + "drinks", + "drowning", + "drunk", + "drying", + "dual", + "dubbed", + "duckling", + "dude", + "duets", + "duke", + "dullness", + "dummy", + "dunes", + "duplex", + "duration", + "dusted", + "duties", + "dwarf", + "dwelt", + "dwindling", + "dying", + "dynamite", + "dyslexic", + "each", + "eagle", + "earth", + "easy", + "eating", + "eavesdrop", + "eccentric", + "echo", + "eclipse", + "economics", + "ecstatic", + "eden", + "edgy", + "edited", + "educated", + "eels", + "efficient", + "eggs", + "egotistic", + "eight", + "either", + "eject", + "elapse", + "elbow", + "eldest", + "eleven", + "elite", + "elope", + "else", + "eluded", + "emails", + "ember", + "emerge", + "emit", + "emotion", + "empty", + "emulate", + "energy", + "enforce", + "enhanced", + "enigma", + "enjoy", + "enlist", + "enmity", + "enough", + "enraged", + "ensign", + "entrance", + "envy", + "epoxy", + "equip", + "erase", + "erected", + "erosion", + "error", + "eskimos", + "espionage", + "essential", + "estate", + "etched", + "eternal", + "ethics", + "etiquette", + "evaluate", + "evenings", + "evicted", + "evolved", + "examine", + "excess", + "exhale", + "exit", + "exotic", + "exquisite", + "extra", + "exult", + "fabrics", + "factual", + "fading", + "fainted", + "faked", + "fall", + "family", + "fancy", + "farming", + "fatal", + "faulty", + "fawns", + "faxed", + "fazed", + "feast", + "february", + "federal", + "feel", + "feline", + "females", + "fences", + "ferry", + "festival", + "fetches", + "fever", + "fewest", + "fiat", + "fibula", + "fictional", + "fidget", + "fierce", + "fifteen", + "fight", + "films", + "firm", + "fishing", + "fitting", + "five", + "fixate", + "fizzle", + "fleet", + "flippant", + "flying", + "foamy", + "focus", + "foes", + "foggy", + "foiled", + "folding", + "fonts", + "foolish", + "fossil", + "fountain", + "fowls", + "foxes", + "foyer", + "framed", + "friendly", + "frown", + "fruit", + "frying", + "fudge", + "fuel", + "fugitive", + "fully", + "fuming", + "fungal", + "furnished", + "fuselage", + "future", + "fuzzy", + "gables", + "gadget", + "gags", + "gained", + "galaxy", + "gambit", + "gang", + "gasp", + "gather", + "gauze", + "gave", + "gawk", + "gaze", + "gearbox", + "gecko", + "geek", + "gels", + "gemstone", + "general", + "geometry", + "germs", + "gesture", + "getting", + "geyser", + "ghetto", + "ghost", + "giant", + "giddy", + "gifts", + "gigantic", + "gills", + "gimmick", + "ginger", + "girth", + "giving", + "glass", + "gleeful", + "glide", + "gnaw", + "gnome", + "goat", + "goblet", + "godfather", + "goes", + "goggles", + "going", + "goldfish", + "gone", + "goodbye", + "gopher", + "gorilla", + "gossip", + "gotten", + "gourmet", + "governing", + "gown", + "greater", + "grunt", + "guarded", + "guest", + "guide", + "gulp", + "gumball", + "guru", + "gusts", + "gutter", + "guys", + "gymnast", + "gypsy", + "gyrate", + "habitat", + "hacksaw", + "haggled", + "hairy", + "hamburger", + "happens", + "hashing", + "hatchet", + "haunted", + "having", + "hawk", + "haystack", + "hazard", + "hectare", + "hedgehog", + "heels", + "hefty", + "height", + "hemlock", + "hence", + "heron", + "hesitate", + "hexagon", + "hickory", + "hiding", + "highway", + "hijack", + "hiker", + "hills", + "himself", + "hinder", + "hippo", + "hire", + "history", + "hitched", + "hive", + "hoax", + "hobby", + "hockey", + "hoisting", + "hold", + "honked", + "hookup", + "hope", + "hornet", + "hospital", + "hotel", + "hounded", + "hover", + "howls", + "hubcaps", + "huddle", + "huge", + "hull", + "humid", + "hunter", + "hurried", + "husband", + "huts", + "hybrid", + "hydrogen", + "hyper", + "iceberg", + "icing", + "icon", + "identity", + "idiom", + "idled", + "idols", + "igloo", + "ignore", + "iguana", + "illness", + "imagine", + "imbalance", + "imitate", + "impel", + "inactive", + "inbound", + "incur", + "industrial", + "inexact", + "inflamed", + "ingested", + "initiate", + "injury", + "inkling", + "inline", + "inmate", + "innocent", + "inorganic", + "input", + "inquest", + "inroads", + "insult", + "intended", + "inundate", + "invoke", + "inwardly", + "ionic", + "irate", + "iris", + "irony", + "irritate", + "island", + "isolated", + "issued", + "italics", + "itches", + "items", + "itinerary", + "itself", + "ivory", + "jabbed", + "jackets", + "jaded", + "jagged", + "jailed", + "jamming", + "january", + "jargon", + "jaunt", + "javelin", + "jaws", + "jazz", + "jeans", + "jeers", + "jellyfish", + "jeopardy", + "jerseys", + "jester", + "jetting", + "jewels", + "jigsaw", + "jingle", + "jittery", + "jive", + "jobs", + "jockey", + "jogger", + "joining", + "joking", + "jolted", + "jostle", + "journal", + "joyous", + "jubilee", + "judge", + "juggled", + "juicy", + "jukebox", + "july", + "jump", + "junk", + "jury", + "justice", + "juvenile", + "kangaroo", + "karate", + "keep", + "kennel", + "kept", + "kernels", + "kettle", + "keyboard", + "kickoff", + "kidneys", + "king", + "kiosk", + "kisses", + "kitchens", + "kiwi", + "knapsack", + "knee", + "knife", + "knowledge", + "knuckle", + "koala", + "laboratory", + "ladder", + "lagoon", + "lair", + "lakes", + "lamb", + "language", + "laptop", + "large", + "last", + "later", + "launching", + "lava", + "lawsuit", + "layout", + "lazy", + "lectures", + "ledge", + "leech", + "left", + "legion", + "leisure", + "lemon", + "lending", + "leopard", + "lesson", + "lettuce", + "lexicon", + "liar", + "library", + "licks", + "lids", + "lied", + "lifestyle", + "light", + "likewise", + "lilac", + "limits", + "linen", + "lion", + "lipstick", + "liquid", + "listen", + "lively", + "loaded", + "lobster", + "locker", + "lodge", + "lofty", + "logic", + "loincloth", + "long", + "looking", + "lopped", + "lordship", + "losing", + "lottery", + "loudly", + "love", + "lower", + "loyal", + "lucky", + "luggage", + "lukewarm", + "lullaby", + "lumber", + "lunar", + "lurk", + "lush", + "luxury", + "lymph", + "lynx", + "lyrics", + "macro", + "madness", + "magically", + "mailed", + "major", + "makeup", + "malady", + "mammal", + "maps", + "masterful", + "match", + "maul", + "maverick", + "maximum", + "mayor", + "maze", + "meant", + "mechanic", + "medicate", + "meeting", + "megabyte", + "melting", + "memoir", + "menu", + "merger", + "mesh", + "metro", + "mews", + "mice", + "midst", + "mighty", + "mime", + "mirror", + "misery", + "mittens", + "mixture", + "moat", + "mobile", + "mocked", + "mohawk", + "moisture", + "molten", + "moment", + "money", + "moon", + "mops", + "morsel", + "mostly", + "motherly", + "mouth", + "movement", + "mowing", + "much", + "muddy", + "muffin", + "mugged", + "mullet", + "mumble", + "mundane", + "muppet", + "mural", + "musical", + "muzzle", + "myriad", + "mystery", + "myth", + "nabbing", + "nagged", + "nail", + "names", + "nanny", + "napkin", + "narrate", + "nasty", + "natural", + "nautical", + "navy", + "nearby", + "necklace", + "needed", + "negative", + "neither", + "neon", + "nephew", + "nerves", + "nestle", + "network", + "neutral", + "never", + "newt", + "nexus", + "nibs", + "niche", + "niece", + "nifty", + "nightly", + "nimbly", + "nineteen", + "nirvana", + "nitrogen", + "nobody", + "nocturnal", + "nodes", + "noises", + "nomad", + "noodles", + "northern", + "nostril", + "noted", + "nouns", + "novelty", + "nowhere", + "nozzle", + "nuance", + "nucleus", + "nudged", + "nugget", + "nuisance", + "null", + "number", + "nuns", + "nurse", + "nutshell", + "nylon", + "oaks", + "oars", + "oasis", + "oatmeal", + "obedient", + "object", + "obliged", + "obnoxious", + "observant", + "obtains", + "obvious", + "occur", + "ocean", + "october", + "odds", + "odometer", + "offend", + "often", + "oilfield", + "ointment", + "okay", + "older", + "olive", + "olympics", + "omega", + "omission", + "omnibus", + "onboard", + "oncoming", + "oneself", + "ongoing", + "onion", + "online", + "onslaught", + "onto", + "onward", + "oozed", + "opacity", + "opened", + "opposite", + "optical", + "opus", + "orange", + "orbit", + "orchid", + "orders", + "organs", + "origin", + "ornament", + "orphans", + "oscar", + "ostrich", + "otherwise", + "otter", + "ouch", + "ought", + "ounce", + "ourselves", + "oust", + "outbreak", + "oval", + "oven", + "owed", + "owls", + "owner", + "oxidant", + "oxygen", + "oyster", + "ozone", + "pact", + "paddles", + "pager", + "pairing", + "palace", + "pamphlet", + "pancakes", + "paper", + "paradise", + "pastry", + "patio", + "pause", + "pavements", + "pawnshop", + "payment", + "peaches", + "pebbles", + "peculiar", + "pedantic", + "peeled", + "pegs", + "pelican", + "pencil", + "people", + "pepper", + "perfect", + "pests", + "petals", + "phase", + "pheasants", + "phone", + "phrases", + "physics", + "piano", + "picked", + "pierce", + "pigment", + "piloted", + "pimple", + "pinched", + "pioneer", + "pipeline", + "pirate", + "pistons", + "pitched", + "pivot", + "pixels", + "pizza", + "playful", + "pledge", + "pliers", + "plotting", + "plus", + "plywood", + "poaching", + "pockets", + "podcast", + "poetry", + "point", + "poker", + "polar", + "ponies", + "pool", + "popular", + "portents", + "possible", + "potato", + "pouch", + "poverty", + "powder", + "pram", + "present", + "pride", + "problems", + "pruned", + "prying", + "psychic", + "public", + "puck", + "puddle", + "puffin", + "pulp", + "pumpkins", + "punch", + "puppy", + "purged", + "push", + "putty", + "puzzled", + "pylons", + "pyramid", + "python", + "queen", + "quick", + "quote", + "rabbits", + "racetrack", + "radar", + "rafts", + "rage", + "railway", + "raking", + "rally", + "ramped", + "randomly", + "rapid", + "rarest", + "rash", + "rated", + "ravine", + "rays", + "razor", + "react", + "rebel", + "recipe", + "reduce", + "reef", + "refer", + "regular", + "reheat", + "reinvest", + "rejoices", + "rekindle", + "relic", + "remedy", + "renting", + "reorder", + "repent", + "request", + "reruns", + "rest", + "return", + "reunion", + "revamp", + "rewind", + "rhino", + "rhythm", + "ribbon", + "richly", + "ridges", + "rift", + "rigid", + "rims", + "ringing", + "riots", + "ripped", + "rising", + "ritual", + "river", + "roared", + "robot", + "rockets", + "rodent", + "rogue", + "roles", + "romance", + "roomy", + "roped", + "roster", + "rotate", + "rounded", + "rover", + "rowboat", + "royal", + "ruby", + "rudely", + "ruffled", + "rugged", + "ruined", + "ruling", + "rumble", + "runway", + "rural", + "rustled", + "ruthless", + "sabotage", + "sack", + "sadness", + "safety", + "saga", + "sailor", + "sake", + "salads", + "sample", + "sanity", + "sapling", + "sarcasm", + "sash", + "satin", + "saucepan", + "saved", + "sawmill", + "saxophone", + "sayings", + "scamper", + "scenic", + "school", + "science", + "scoop", + "scrub", + "scuba", + "seasons", + "second", + "sedan", + "seeded", + "segments", + "seismic", + "selfish", + "semifinal", + "sensible", + "september", + "sequence", + "serving", + "session", + "setup", + "seventh", + "sewage", + "shackles", + "shelter", + "shipped", + "shocking", + "shrugged", + "shuffled", + "shyness", + "siblings", + "sickness", + "sidekick", + "sieve", + "sifting", + "sighting", + "silk", + "simplest", + "sincerely", + "sipped", + "siren", + "situated", + "sixteen", + "sizes", + "skater", + "skew", + "skirting", + "skulls", + "skydive", + "slackens", + "sleepless", + "slid", + "slower", + "slug", + "smash", + "smelting", + "smidgen", + "smog", + "smuggled", + "snake", + "sneeze", + "sniff", + "snout", + "snug", + "soapy", + "sober", + "soccer", + "soda", + "software", + "soggy", + "soil", + "solved", + "somewhere", + "sonic", + "soothe", + "soprano", + "sorry", + "southern", + "sovereign", + "sowed", + "soya", + "space", + "speedy", + "sphere", + "spiders", + "splendid", + "spout", + "sprig", + "spud", + "spying", + "square", + "stacking", + "stellar", + "stick", + "stockpile", + "strained", + "stunning", + "stylishly", + "subtly", + "succeed", + "suddenly", + "suede", + "suffice", + "sugar", + "suitcase", + "sulking", + "summon", + "sunken", + "superior", + "surfer", + "sushi", + "suture", + "swagger", + "swept", + "swiftly", + "sword", + "swung", + "syllabus", + "symptoms", + "syndrome", + "syringe", + "system", + "taboo", + "tacit", + "tadpoles", + "tagged", + "tail", + "taken", + "talent", + "tamper", + "tanks", + "tapestry", + "tarnished", + "tasked", + "tattoo", + "taunts", + "tavern", + "tawny", + "taxi", + "teardrop", + "technical", + "tedious", + "teeming", + "tell", + "template", + "tender", + "tepid", + "tequila", + "terminal", + "testing", + "tether", + "textbook", + "thaw", + "theatrics", + "thirsty", + "thorn", + "threaten", + "thumbs", + "thwart", + "ticket", + "tidy", + "tiers", + "tiger", + "tilt", + "timber", + "tinted", + "tipsy", + "tirade", + "tissue", + "titans", + "toaster", + "tobacco", + "today", + "toenail", + "toffee", + "together", + "toilet", + "token", + "tolerant", + "tomorrow", + "tonic", + "toolbox", + "topic", + "torch", + "tossed", + "total", + "touchy", + "towel", + "toxic", + "toyed", + "trash", + "trendy", + "tribal", + "trolling", + "truth", + "trying", + "tsunami", + "tubes", + "tucks", + "tudor", + "tuesday", + "tufts", + "tugs", + "tuition", + "tulips", + "tumbling", + "tunnel", + "turnip", + "tusks", + "tutor", + "tuxedo", + "twang", + "tweezers", + "twice", + "twofold", + "tycoon", + "typist", + "tyrant", + "ugly", + "ulcers", + "ultimate", + "umbrella", + "umpire", + "unafraid", + "unbending", + "uncle", + "under", + "uneven", + "unfit", + "ungainly", + "unhappy", + "union", + "unjustly", + "unknown", + "unlikely", + "unmask", + "unnoticed", + "unopened", + "unplugs", + "unquoted", + "unrest", + "unsafe", + "until", + "unusual", + "unveil", + "unwind", + "unzip", + "upbeat", + "upcoming", + "update", + "upgrade", + "uphill", + "upkeep", + "upload", + "upon", + "upper", + "upright", + "upstairs", + "uptight", + "upwards", + "urban", + "urchins", + "urgent", + "usage", + "useful", + "usher", + "using", + "usual", + "utensils", + "utility", + "utmost", + "utopia", + "uttered", + "vacation", + "vague", + "vain", + "value", + "vampire", + "vane", + "vapidly", + "vary", + "vastness", + "vats", + "vaults", + "vector", + "veered", + "vegan", + "vehicle", + "vein", + "velvet", + "venomous", + "verification", + "vessel", + "veteran", + "vexed", + "vials", + "vibrate", + "victim", + "video", + "viewpoint", + "vigilant", + "viking", + "village", + "vinegar", + "violin", + "vipers", + "virtual", + "visited", + "vitals", + "vivid", + "vixen", + "vocal", + "vogue", + "voice", + "volcano", + "vortex", + "voted", + "voucher", + "vowels", + "voyage", + "vulture", + "wade", + "waffle", + "wagtail", + "waist", + "waking", + "wallets", + "wanted", + "warped", + "washing", + "water", + "waveform", + "waxing", + "wayside", + "weavers", + "website", + "wedge", + "weekday", + "weird", + "welders", + "went", + "wept", + "were", + "western", + "wetsuit", + "whale", + "when", + "whipped", + "whole", + "wickets", + "width", + "wield", + "wife", + "wiggle", + "wildly", + "winter", + "wipeout", + "wiring", + "wise", + "withdrawn", + "wives", + "wizard", + "wobbly", + "woes", + "woken", + "wolf", + "womanly", + "wonders", + "woozy", + "worry", + "wounded", + "woven", + "wrap", + "wrist", + "wrong", + "yacht", + "yahoo", + "yanks", + "yard", + "yawning", + "yearbook", + "yellow", + "yesterday", + "yeti", + "yields", + "yodel", + "yoga", + "younger", + "yoyo", + "zapped", + "zeal", + "zebra", + "zero", + "zesty", + "zigzags", + "zinger", + "zippers", + "zodiac", + "zombie", + "zones", + "zoom" +]; diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock index c90340800..b0347c023 100644 --- a/cw_wownero/pubspec.lock +++ b/cw_wownero/pubspec.lock @@ -41,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + bluez: + dependency: transitive + description: + name: bluez + sha256: "203a1924e818a9dd74af2b2c7a8f375ab8e5edf0e486bba8f90a0d8a17ed9fce" + url: "https://pub.dev" + source: hosted + version: "0.8.2" boolean_selector: dependency: transitive description: @@ -209,6 +217,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.4" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" encrypt: dependency: "direct main" description: @@ -267,6 +283,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_bluetooth: + dependency: transitive + description: + name: flutter_web_bluetooth + sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02" + url: "https://pub.dev" + source: hosted + version: "0.2.3" frontend_server_client: dependency: transitive description: @@ -403,6 +427,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + ledger_flutter_plus: + dependency: transitive + description: + name: ledger_flutter_plus + sha256: ea3ed586e1697776dacf42ac979095f1ca3bd143bf007cbe5c78e09cb6943f42 + url: "https://pub.dev" + source: hosted + version: "1.2.5" + ledger_usb_plus: + dependency: transitive + description: + name: ledger_usb_plus + sha256: "21cc5d976cf7edb3518bd2a0c4164139cbb0817d2e4f2054707fc4edfdf9ce87" + url: "https://pub.dev" + source: hosted + version: "1.0.4" logging: dependency: transitive description: @@ -463,8 +503,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b" - resolved-ref: "6eb571ea498ed7b854934785f00fabfd0dadf75b" + ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b + resolved-ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" @@ -540,6 +580,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" platform: dependency: transitive description: @@ -552,10 +600,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.8" pointycastle: dependency: transitive description: @@ -596,6 +644,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" shelf: dependency: transitive description: @@ -721,6 +777,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + universal_ble: + dependency: transitive + description: + name: universal_ble + sha256: "0dfbd6b64bff3ad61ed7a895c232530d9614e9b01ab261a74433a43267edb7f3" + url: "https://pub.dev" + source: hosted + version: "0.12.0" + universal_platform: + dependency: transitive + description: + name: universal_platform + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" + url: "https://pub.dev" + source: hosted + version: "1.1.0" unorm_dart: dependency: transitive description: @@ -777,6 +849,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" yaml: dependency: transitive description: @@ -786,5 +866,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=3.7.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml index 6943e60c3..582c15447 100644 --- a/cw_wownero/pubspec.yaml +++ b/cw_wownero/pubspec.yaml @@ -25,7 +25,8 @@ dependencies: monero: git: url: https://github.com/mrcyjanek/monero_c - ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash + ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b +# ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash path: impls/monero.dart mutex: ^3.1.0 diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart index e58e14652..10e438e0c 100644 --- a/lib/core/wallet_loading_service.dart +++ b/lib/core/wallet_loading_service.dart @@ -14,7 +14,11 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class WalletLoadingService { - WalletLoadingService(this.sharedPreferences, this.keyService, this.walletServiceFactory); + WalletLoadingService( + this.sharedPreferences, + this.keyService, + this.walletServiceFactory, + ); final SharedPreferences sharedPreferences; final KeyService keyService; @@ -77,7 +81,8 @@ class WalletLoadingService { await updateMoneroWalletPassword(wallet); } - await sharedPreferences.setString(PreferencesKey.currentWalletName, wallet.name); + await sharedPreferences.setString( + PreferencesKey.currentWalletName, wallet.name); await sharedPreferences.setInt( PreferencesKey.currentWalletType, serializeToInt(wallet.type)); @@ -129,4 +134,9 @@ class WalletLoadingService { return "\n\n$type ($name): ${await walletService.getSeeds(name, password, type)}"; } + + bool requireHardwareWalletConnection(WalletType type, String name) { + final walletService = walletServiceFactory.call(type); + return walletService.requireHardwareWalletConnection(name); + } } diff --git a/lib/di.dart b/lib/di.dart index 8dd1029a9..facdec912 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -32,12 +32,14 @@ import 'package:cake_wallet/entities/biometric_auth.dart'; import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart'; +import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_connection.dart'; import 'package:cake_wallet/entities/parse_address_from_domain.dart'; import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart'; import 'package:cake_wallet/entities/wallet_manager.dart'; import 'package:cake_wallet/src/screens/buy/buy_sell_options_page.dart'; import 'package:cake_wallet/src/screens/buy/payment_method_options_page.dart'; import 'package:cake_wallet/src/screens/receive/address_list_page.dart'; +import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart'; import 'package:cake_wallet/src/screens/settings/mweb_logs_page.dart'; import 'package:cake_wallet/src/screens/settings/mweb_node_page.dart'; import 'package:cake_wallet/view_model/link_view_model.dart'; @@ -184,7 +186,6 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_ import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart'; import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart'; -import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; @@ -586,7 +587,7 @@ Future setup({ ); } else { // wallet is already loaded: - if (appStore.wallet != null) { + if (appStore.wallet != null || requireHardwareWalletConnection()) { // goes to the dashboard: authStore.allowed(); // trigger any deep links: @@ -780,10 +781,12 @@ Future setup({ ); } - getIt.registerFactory(() => WalletListPage( - walletListViewModel: getIt.get(), - authService: getIt.get(), - )); + getIt.registerFactoryParam( + (Function(BuildContext)? onWalletLoaded, _) => WalletListPage( + walletListViewModel: getIt.get(), + authService: getIt.get(), + onWalletLoaded: onWalletLoaded, + )); getIt.registerFactoryParam( (WalletListViewModel walletListViewModel, _) => WalletEditViewModel( diff --git a/lib/entities/hardware_wallet/require_hardware_wallet_connection.dart b/lib/entities/hardware_wallet/require_hardware_wallet_connection.dart new file mode 100644 index 000000000..a64fa5873 --- /dev/null +++ b/lib/entities/hardware_wallet/require_hardware_wallet_connection.dart @@ -0,0 +1,25 @@ +import 'package:cake_wallet/core/wallet_loading_service.dart'; +import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/entities/preferences_key.dart'; +import 'package:cw_core/wallet_type.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +bool requireHardwareWalletConnection() { + final name = getIt + .get() + .getString(PreferencesKey.currentWalletName); + final typeRaw = + getIt.get().getInt(PreferencesKey.currentWalletType); + + if (typeRaw == null) { + return false; + } + + if (name == null) { + throw Exception('Incorrect current wallet name: $name'); + } + + final type = deserializeFromInt(typeRaw); + final walletLoadingService = getIt.get(); + return walletLoadingService.requireHardwareWalletConnection(type, name); +} diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart index dfda4d600..09d9889c5 100644 --- a/lib/monero/cw_monero.dart +++ b/lib/monero/cw_monero.dart @@ -225,6 +225,19 @@ class CWMonero extends Monero { language: language, height: height); + @override + WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({ + required String name, + required String password, + required int height, + required ledger.LedgerConnection ledgerConnection, + }) => + MoneroRestoreWalletFromHardwareCredentials( + name: name, + password: password, + height: height, + ledgerConnection: ledgerConnection); + @override WalletCredentials createMoneroRestoreWalletFromSeedCredentials( {required String name, @@ -383,6 +396,18 @@ class CWMonero extends Monero { checkIfMoneroCIsFine(); } + @override + void setLedgerConnection(Object wallet, ledger.LedgerConnection connection) { + final moneroWallet = wallet as MoneroWallet; + moneroWallet.setLedgerConnection(connection); + } + + @override + void setGlobalLedgerConnection(ledger.LedgerConnection connection) { + gLedger = connection; + keepAlive(connection); + } + bool isViewOnly() { return isViewOnlyBySpendKey(); } diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart index 1aa0a12c6..b411c5a15 100644 --- a/lib/reactions/on_authentication_state_change.dart +++ b/lib/reactions/on_authentication_state_change.dart @@ -1,18 +1,28 @@ import 'dart:async'; +import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart'; +import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_connection.dart'; +import 'package:cake_wallet/entities/load_current_wallet.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/utils/exception_handler.dart'; +import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart'; +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/utils/exception_handler.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:cw_core/wallet_type.dart'; import 'package:flutter/widgets.dart'; import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/entities/load_current_wallet.dart'; -import 'package:cake_wallet/store/authentication_store.dart'; import 'package:rxdart/subjects.dart'; ReactionDisposer? _onAuthenticationStateChange; dynamic loginError; -StreamController authenticatedErrorStreamController = BehaviorSubject(); +StreamController authenticatedErrorStreamController = + BehaviorSubject(); void startAuthenticationStateChange( AuthenticationStore authenticationStore, @@ -27,18 +37,49 @@ void startAuthenticationStateChange( _onAuthenticationStateChange ??= autorun((_) async { final state = authenticationStore.state; - if (state == AuthenticationState.installed && !SettingsStoreBase.walletPasswordDirectInput) { + if (state == AuthenticationState.installed && + !SettingsStoreBase.walletPasswordDirectInput) { try { - await loadCurrentWallet(); + if (!requireHardwareWalletConnection()) await loadCurrentWallet(); } catch (error, stack) { loginError = error; - ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); + ExceptionHandler.onError( + FlutterErrorDetails(exception: error, stack: stack)); } return; } if (state == AuthenticationState.allowed) { - await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false); + if (requireHardwareWalletConnection()) { + await navigatorKey.currentState!.pushNamedAndRemoveUntil( + Routes.connectDevices, + (route) => false, + arguments: ConnectDevicePageParams( + walletType: WalletType.monero, + onConnectDevice: (context, ledgerVM) async { + monero!.setGlobalLedgerConnection(ledgerVM.connection); + showPopUp( + context: context, + builder: (BuildContext context) => AlertWithOneAction( + alertTitle: S.of(context).proceed_on_device, + alertContent: S.of(context).proceed_on_device_description, + buttonText: S.of(context).cancel, + buttonAction: () => Navigator.of(context).pop()), + ); + await loadCurrentWallet(); + getIt.get().resetCurrentSheet(); + await navigatorKey.currentState! + .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false); + }, + allowChangeWallet: true, + ), + ); + + // await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.connectDevices, (route) => false, arguments: ConnectDevicePageParams(walletType: walletType, onConnectDevice: onConnectDevice)); + } else { + await navigatorKey.currentState! + .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false); + } if (!(await authenticatedErrorStreamController.stream.isEmpty)) { ExceptionHandler.showError( (await authenticatedErrorStreamController.stream.first).toString()); diff --git a/lib/router.dart b/lib/router.dart index 781a6e057..1382da28f 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -24,6 +24,7 @@ import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart'; import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart'; import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart'; +import 'package:cake_wallet/src/screens/connect_device/monero_hardware_wallet_options_page.dart'; import 'package:cake_wallet/src/screens/connect_device/select_hardware_wallet_account_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart'; @@ -212,6 +213,9 @@ Route createRoute(RouteSettings settings) { final type = arguments[0] as WalletType; final walletVM = getIt.get(param1: type); + if (type == WalletType.monero) + return CupertinoPageRoute(builder: (_) => MoneroHardwareWalletOptionsPage(walletVM)); + return CupertinoPageRoute(builder: (_) => SelectHardwareWalletAccountPage(walletVM)); case Routes.setupPin: @@ -403,8 +407,11 @@ Route createRoute(RouteSettings settings) { return CupertinoPageRoute(builder: (_) => getIt.get()); case Routes.walletList: + final onWalletLoaded = settings.arguments as Function(BuildContext)?; return MaterialPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get()); + fullscreenDialog: true, + builder: (_) => getIt.get(param1: onWalletLoaded), + ); case Routes.walletEdit: return MaterialPageRoute( diff --git a/lib/src/screens/connect_device/connect_device_page.dart b/lib/src/screens/connect_device/connect_device_page.dart index 9e331e818..c2cc40229 100644 --- a/lib/src/screens/connect_device/connect_device_page.dart +++ b/lib/src/screens/connect_device/connect_device_page.dart @@ -2,9 +2,12 @@ import 'dart:async'; import 'dart:io'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/connect_device/widgets/device_tile.dart'; +import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; +import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; import 'package:cw_core/wallet_type.dart'; @@ -17,35 +20,46 @@ typedef OnConnectDevice = void Function(BuildContext, LedgerViewModel); class ConnectDevicePageParams { final WalletType walletType; final OnConnectDevice onConnectDevice; + final bool allowChangeWallet; - ConnectDevicePageParams( - {required this.walletType, required this.onConnectDevice}); + ConnectDevicePageParams({ + required this.walletType, + required this.onConnectDevice, + this.allowChangeWallet = false, + }); } class ConnectDevicePage extends BasePage { final WalletType walletType; final OnConnectDevice onConnectDevice; + final bool allowChangeWallet; final LedgerViewModel ledgerVM; ConnectDevicePage(ConnectDevicePageParams params, this.ledgerVM) : walletType = params.walletType, - onConnectDevice = params.onConnectDevice; + onConnectDevice = params.onConnectDevice, + allowChangeWallet = params.allowChangeWallet; @override String get title => S.current.restore_title_from_hardware_wallet; @override - Widget body(BuildContext context) => - ConnectDevicePageBody(walletType, onConnectDevice, ledgerVM); + Widget body(BuildContext context) => ConnectDevicePageBody( + walletType, onConnectDevice, allowChangeWallet, ledgerVM); } class ConnectDevicePageBody extends StatefulWidget { final WalletType walletType; final OnConnectDevice onConnectDevice; + final bool allowChangeWallet; final LedgerViewModel ledgerVM; const ConnectDevicePageBody( - this.walletType, this.onConnectDevice, this.ledgerVM); + this.walletType, + this.onConnectDevice, + this.allowChangeWallet, + this.ledgerVM, + ); @override ConnectDevicePageBodyState createState() => ConnectDevicePageBodyState(); @@ -102,14 +116,16 @@ class ConnectDevicePageBodyState extends State { Future _refreshBleDevices() async { try { - _bleRefresh = widget.ledgerVM - .scanForBleDevices() - .listen((device) => setState(() => bleDevices.add(device))) - ..onError((e) { - throw e.toString(); - }); - _bleRefreshTimer?.cancel(); - _bleRefreshTimer = null; + if (widget.ledgerVM.bleIsEnabled) { + _bleRefresh = widget.ledgerVM + .scanForBleDevices() + .listen((device) => setState(() => bleDevices.add(device))) + ..onError((e) { + throw e.toString(); + }); + _bleRefreshTimer?.cancel(); + _bleRefreshTimer = null; + } } catch (e) { print(e); } @@ -227,9 +243,7 @@ class ConnectDevicePageBodyState extends State { style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, - color: Theme.of(context) - .extension()! - .titleColor, + color: Theme.of(context).extension()!.titleColor, ), ), ), @@ -247,11 +261,27 @@ class ConnectDevicePageBodyState extends State { ), ) .toList(), - ] + ], + if (widget.allowChangeWallet) ...[ + PrimaryButton( + text: S.of(context).wallets, + color: Theme.of(context).extension()!.createNewWalletButtonBackgroundColor, + textColor: Theme.of(context).extension()!.restoreWalletButtonTextColor, + onPressed: _onChangeWallet, + ) + ], ], ), ), ), ); } + + void _onChangeWallet() { + Navigator.of(context).pushNamed( + Routes.walletList, + arguments: (BuildContext context) => Navigator.of(context) + .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false), + ); + } } diff --git a/lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart b/lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart new file mode 100644 index 000000000..f8ace97bc --- /dev/null +++ b/lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart @@ -0,0 +1,230 @@ +import 'package:cake_wallet/core/wallet_name_validator.dart'; +import 'package:cake_wallet/entities/generate_name.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart'; +import 'package:cake_wallet/src/widgets/primary_button.dart'; +import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; +import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart'; +import 'package:cake_wallet/themes/extensions/send_page_theme.dart'; +import 'package:cake_wallet/utils/responsive_layout_util.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:cake_wallet/view_model/wallet_hardware_restore_view_model.dart'; +import 'package:cw_core/wallet_type.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:mobx/mobx.dart'; + +class MoneroHardwareWalletOptionsPage extends BasePage { + MoneroHardwareWalletOptionsPage(this._walletHardwareRestoreVM); + + final WalletHardwareRestoreViewModel _walletHardwareRestoreVM; + + @override + String get title => S.current.restore_title_from_hardware_wallet; + + @override + Widget body(BuildContext context) => + _MoneroHardwareWalletOptionsForm(_walletHardwareRestoreVM); +} + +class _MoneroHardwareWalletOptionsForm extends StatefulWidget { + const _MoneroHardwareWalletOptionsForm(this._walletHardwareRestoreVM); + + final WalletHardwareRestoreViewModel _walletHardwareRestoreVM; + + @override + _MoneroHardwareWalletOptionsFormState createState() => + _MoneroHardwareWalletOptionsFormState(_walletHardwareRestoreVM); +} + +class _MoneroHardwareWalletOptionsFormState + extends State<_MoneroHardwareWalletOptionsForm> { + _MoneroHardwareWalletOptionsFormState(this._walletHardwareRestoreVM) + : _formKey = GlobalKey(), + _blockchainHeightKey = GlobalKey(), + _blockHeightFocusNode = FocusNode(), + _controller = TextEditingController(); + + final GlobalKey _formKey; + final GlobalKey _blockchainHeightKey; + final FocusNode _blockHeightFocusNode; + final WalletHardwareRestoreViewModel _walletHardwareRestoreVM; + final TextEditingController _controller; + + @override + void initState() { + super.initState(); + _setEffects(context); + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only(top: 24), + child: ScrollableWithBottomSection( + contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), + content: Center( + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(top: 0), + child: Form( + key: _formKey, + child: Stack( + alignment: Alignment.centerRight, + children: [ + TextFormField( + onChanged: (value) => + _walletHardwareRestoreVM.name = value, + controller: _controller, + style: TextStyle( + fontSize: 20.0, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .extension()! + .titleColor, + ), + decoration: InputDecoration( + hintStyle: TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.w500, + color: Theme.of(context) + .extension()! + .hintTextColor, + ), + hintText: S.of(context).wallet_name, + focusedBorder: UnderlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context) + .extension()! + .underlineColor, + width: 1.0, + ), + ), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context) + .extension()! + .underlineColor, + width: 1.0, + ), + ), + suffixIcon: Semantics( + label: S.of(context).generate_name, + child: IconButton( + onPressed: _onGenerateName, + icon: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.0), + color: Theme.of(context).hintColor, + ), + width: 34, + height: 34, + child: Image.asset( + 'assets/images/refresh_icon.png', + color: Theme.of(context) + .extension()! + .textFieldButtonIconColor, + ), + ), + ), + ), + ), + validator: WalletNameValidator(), + ), + ], + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 20), + child: BlockchainHeightWidget( + focusNode: _blockHeightFocusNode, + key: _blockchainHeightKey, + hasDatePicker: true, + walletType: WalletType.monero, + ), + ), + ], + ), + ), + ), + bottomSectionPadding: EdgeInsets.all(24), + bottomSection: Observer( + builder: (context) => LoadingPrimaryButton( + onPressed: _confirmForm, + text: S.of(context).seed_language_next, + color: Colors.green, + textColor: Colors.white, + isDisabled: _walletHardwareRestoreVM.name.isEmpty, + ), + ), + ), + ); + } + + Future _onGenerateName() async { + final rName = await generateName(); + FocusManager.instance.primaryFocus?.unfocus(); + + setState(() { + _controller.text = rName; + _walletHardwareRestoreVM.name = rName; + _controller.selection = TextSelection.fromPosition( + TextPosition(offset: _controller.text.length)); + }); + } + + Future _confirmForm() async { + showPopUp( + context: context, + builder: (BuildContext context) => AlertWithOneAction( + alertTitle: S.of(context).proceed_on_device, + alertContent: S.of(context).proceed_on_device_description, + buttonText: S.of(context).cancel, + buttonAction: () => Navigator.of(context).pop(), + ), + ); + + final options = {'height': _blockchainHeightKey.currentState?.height ?? -1}; + await _walletHardwareRestoreVM.create(options: options); + } + + bool _effectsInstalled = false; + + void _setEffects(BuildContext context) { + if (_effectsInstalled) return; + + reaction((_) => _walletHardwareRestoreVM.error, (String? error) { + if (error != null) { + if (error == S.current.ledger_connection_error) + Navigator.of(context).pop(); + + WidgetsBinding.instance.addPostFrameCallback((_) { + showPopUp( + context: context, + builder: (BuildContext context) => AlertWithOneAction( + alertTitle: S.of(context).error, + alertContent: error, + buttonText: S.of(context).ok, + buttonAction: () { + _walletHardwareRestoreVM.error = null; + Navigator.of(context).pop(); + }, + ), + ); + }); + } + }); + + _effectsInstalled = true; + } +} diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index a9a9d9413..46eaa6143 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -1,44 +1,56 @@ +import 'package:another_flushbar/flushbar.dart'; +import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/new_wallet_arguments.dart'; import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart'; import 'package:cake_wallet/entities/wallet_list_order_types.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/monero/monero.dart'; +import 'package:cake_wallet/routes.dart'; +import 'package:cake_wallet/src/screens/auth/auth_page.dart'; +import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/filter_list_widget.dart'; import 'package:cake_wallet/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart'; import 'package:cake_wallet/src/screens/wallet_list/edit_wallet_button_widget.dart'; import 'package:cake_wallet/src/screens/wallet_list/filtered_list.dart'; import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart'; +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; -import 'package:cake_wallet/src/screens/auth/auth_page.dart'; -import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart'; -import 'package:another_flushbar/flushbar.dart'; +import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart'; +import 'package:cake_wallet/wallet_type_utils.dart'; +import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/wallet_type_utils.dart'; class WalletListPage extends BasePage { - WalletListPage({required this.walletListViewModel, required this.authService}); + WalletListPage({ + required this.walletListViewModel, + required this.authService, + this.onWalletLoaded, + }); final WalletListViewModel walletListViewModel; final AuthService authService; + final Function(BuildContext)? onWalletLoaded; @override String get title => S.current.wallets; @override - Widget body(BuildContext context) => - WalletListBody(walletListViewModel: walletListViewModel, authService: authService); + Widget body(BuildContext context) => WalletListBody( + walletListViewModel: walletListViewModel, + authService: authService, + onWalletLoaded: + onWalletLoaded ?? (context) => Navigator.of(context).pop(), + ); @override Widget trailing(BuildContext context) { @@ -89,10 +101,15 @@ class WalletListPage extends BasePage { } class WalletListBody extends StatefulWidget { - WalletListBody({required this.walletListViewModel, required this.authService}); + WalletListBody({ + required this.walletListViewModel, + required this.authService, + required this.onWalletLoaded, + }); final WalletListViewModel walletListViewModel; final AuthService authService; + final Function(BuildContext) onWalletLoaded; @override WalletListBodyState createState() => WalletListBodyState(); @@ -118,8 +135,8 @@ class WalletListBodyState extends State { @override Widget build(BuildContext context) { - final newWalletImage = - Image.asset('assets/images/new_wallet.png', height: 12, width: 12, color: Colors.white); + final newWalletImage = Image.asset('assets/images/new_wallet.png', + height: 12, width: 12, color: Colors.white); final restoreWalletImage = Image.asset('assets/images/restore_wallet.png', height: 12, width: 12, @@ -180,8 +197,7 @@ class WalletListBodyState extends State { trailingWidget: EditWalletButtonWidget( width: 74, isGroup: true, - isExpanded: - widget.walletListViewModel.expansionTileStateTrack[index]!, + isExpanded: widget.walletListViewModel.expansionTileStateTrack[index]!, onTap: () { final wallet = widget.walletListViewModel .convertWalletInfoToWalletListItem(group.wallets.first); @@ -198,8 +214,7 @@ class WalletListBodyState extends State { }, ), childWallets: group.wallets.map((walletInfo) { - return widget.walletListViewModel - .convertWalletInfoToWalletListItem(walletInfo); + return widget.walletListViewModel.convertWalletInfoToWalletListItem(walletInfo); }).toList(), isSelected: false, onChildItemTapped: (wallet) => @@ -329,8 +344,7 @@ class WalletListBodyState extends State { arguments: NewWalletArguments( type: widget.walletListViewModel.currentWalletType, ), - conditionToDetermineIfToUse2FA: - widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, + conditionToDetermineIfToUse2FA: widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, ); } else { Navigator.of(context).pushNamed( @@ -345,8 +359,7 @@ class WalletListBodyState extends State { widget.authService.authenticateAction( context, route: Routes.newWalletType, - conditionToDetermineIfToUse2FA: - widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, + conditionToDetermineIfToUse2FA: widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, ); } else { Navigator.of(context).pushNamed(Routes.newWalletType); @@ -367,8 +380,7 @@ class WalletListBodyState extends State { context, route: Routes.restoreOptions, arguments: false, - conditionToDetermineIfToUse2FA: - widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, + conditionToDetermineIfToUse2FA: widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets, ); } else { Navigator.of(context).pushNamed(Routes.restoreOptions, arguments: false); @@ -387,39 +399,6 @@ class WalletListBodyState extends State { ); } - Image _imageFor({required WalletType type, bool? isTestnet}) { - switch (type) { - case WalletType.bitcoin: - if (isTestnet == true) { - return tBitcoinIcon; - } - return bitcoinIcon; - case WalletType.monero: - return moneroIcon; - case WalletType.litecoin: - return litecoinIcon; - case WalletType.haven: - return havenIcon; - case WalletType.ethereum: - return ethereumIcon; - case WalletType.bitcoinCash: - return bitcoinCashIcon; - case WalletType.nano: - case WalletType.banano: - return nanoIcon; - case WalletType.polygon: - return polygonIcon; - case WalletType.solana: - return solanaIcon; - case WalletType.tron: - return tronIcon; - case WalletType.wownero: - return wowneroIcon; - case WalletType.none: - return nonWalletTypeIcon; - } - } - Future _loadWallet(WalletListItem wallet) async { if (SettingsStoreBase.walletPasswordDirectInput) { Navigator.of(context).pushNamed(Routes.walletUnlockLoadable, @@ -438,12 +417,36 @@ class WalletListBodyState extends State { await widget.authService.authenticateAction( context, onAuthSuccess: (isAuthenticatedSuccessfully) async { - if (!isAuthenticatedSuccessfully) { - return; - } + if (!isAuthenticatedSuccessfully) return; try { - changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name)); + if (widget.walletListViewModel + .requireHardwareWalletConnection(wallet)) { + await Navigator.of(context).pushNamed( + Routes.connectDevices, + arguments: ConnectDevicePageParams( + walletType: WalletType.monero, + onConnectDevice: (context, ledgerVM) async { + monero!.setGlobalLedgerConnection(ledgerVM.connection); + Navigator.of(context).pop(); + }, + ), + ); + + showPopUp( + context: context, + builder: (BuildContext context) => AlertWithOneAction( + alertTitle: S.of(context).proceed_on_device, + alertContent: S.of(context).proceed_on_device_description, + buttonText: S.of(context).cancel, + buttonAction: () => Navigator.of(context).pop()), + ); + } + + + + changeProcessText( + S.of(context).wallet_list_loading_wallet(wallet.name)); await widget.walletListViewModel.loadWallet(wallet); await hideProgressText(); // only pop the wallets route in mobile as it will go back to dashboard page @@ -451,13 +454,15 @@ class WalletListBodyState extends State { if (responsiveLayoutUtil.shouldRenderMobileUI) { WidgetsBinding.instance.addPostFrameCallback((_) { if (this.mounted) { - Navigator.of(context).pop(); + widget.onWalletLoaded.call(context); } }); } } catch (e) { if (this.mounted) { - changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString())); + changeProcessText(S + .of(context) + .wallet_list_failed_to_load(wallet.name, e.toString())); } } }, diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index a78012ae9..808657f66 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -428,7 +428,7 @@ abstract class DashboardViewModelBase with Store { // to not cause work duplication, this will do the job as well, it will be slightly less precise // about what happened - but still enough. // if (keys['privateSpendKey'] == List.generate(64, (index) => "0").join("")) "Private spend key is 0", - if (keys['privateViewKey'] == List.generate(64, (index) => "0").join("")) + if (keys['privateViewKey'] == List.generate(64, (index) => "0").join("") && !wallet.isHardwareWallet) "private view key is 0", // if (keys['publicSpendKey'] == List.generate(64, (index) => "0").join("")) "public spend key is 0", if (keys['publicViewKey'] == List.generate(64, (index) => "0").join("")) diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart index 19b190fe3..96f5930c0 100644 --- a/lib/view_model/hardware_wallet/ledger_view_model.dart +++ b/lib/view_model/hardware_wallet/ledger_view_model.dart @@ -4,6 +4,7 @@ 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/monero/monero.dart'; import 'package:cake_wallet/polygon/polygon.dart'; import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; @@ -114,6 +115,8 @@ abstract class LedgerViewModelBase with Store { void setLedger(WalletBase wallet) { switch (wallet.type) { + case WalletType.monero: + return monero!.setLedgerConnection(wallet, connection); case WalletType.bitcoin: case WalletType.litecoin: return bitcoin!.setLedgerConnection(wallet, connection); diff --git a/lib/view_model/wallet_hardware_restore_view_model.dart b/lib/view_model/wallet_hardware_restore_view_model.dart index 91e0de685..0971622a5 100644 --- a/lib/view_model/wallet_hardware_restore_view_model.dart +++ b/lib/view_model/wallet_hardware_restore_view_model.dart @@ -1,7 +1,9 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/core/generate_wallet_password.dart'; import 'package:cake_wallet/core/wallet_creation_service.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/polygon/polygon.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; @@ -56,8 +58,8 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with List accounts; switch (type) { case WalletType.bitcoin: - accounts = await bitcoin! - .getHardwareWalletBitcoinAccounts(ledgerViewModel, index: _nextIndex, limit: limit); + accounts = await bitcoin! + .getHardwareWalletBitcoinAccounts(ledgerViewModel, index: _nextIndex, limit: limit); break; case WalletType.litecoin: accounts = await bitcoin! @@ -104,6 +106,15 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with case WalletType.polygon: credentials = polygon!.createPolygonHardwareWalletCredentials(name: name, hwAccountData: selectedAccount!); break; + case WalletType.monero: + final password = walletPassword ?? generateWalletPassword(); + + credentials = monero!.createMoneroRestoreWalletFromHardwareCredentials( + name: name, + ledgerConnection: ledgerViewModel.connection, + password: password, + height: _options['height'] as int? ?? 0, + ); default: throw Exception('Unexpected type: ${type.toString()}'); } diff --git a/lib/view_model/wallet_list/wallet_list_view_model.dart b/lib/view_model/wallet_list/wallet_list_view_model.dart index 725af843f..c903b535f 100644 --- a/lib/view_model/wallet_list/wallet_list_view_model.dart +++ b/lib/view_model/wallet_list/wallet_list_view_model.dart @@ -68,6 +68,10 @@ abstract class WalletListViewModelBase with Store { WalletType get currentWalletType => _appStore.wallet!.type; + bool requireHardwareWalletConnection(WalletListItem walletItem) => + _walletLoadingService.requireHardwareWalletConnection( + walletItem.type, walletItem.name); + @action Future loadWallet(WalletListItem walletItem) async { // bool switchingToSameWalletType = walletItem.type == _appStore.wallet?.type; @@ -87,7 +91,8 @@ abstract class WalletListViewModelBase with Store { singleWalletsList.clear(); wallets.addAll( - _walletInfoSource.values.map((info) => convertWalletInfoToWalletListItem(info)), + _walletInfoSource.values + .map((info) => convertWalletInfoToWalletListItem(info)), ); //========== Split into shared seed groups and single wallets list @@ -95,7 +100,8 @@ abstract class WalletListViewModelBase with Store { for (var group in _walletManager.walletGroups) { if (group.wallets.length == 1) { - singleWalletsList.add(convertWalletInfoToWalletListItem(group.wallets.first)); + singleWalletsList + .add(convertWalletInfoToWalletListItem(group.wallets.first)); } else { multiWalletGroups.add(group); } @@ -148,9 +154,11 @@ abstract class WalletListViewModelBase with Store { List walletInfoSourceCopy = _walletInfoSource.values.toList(); await _walletInfoSource.clear(); if (ascending) { - walletInfoSourceCopy.sort((a, b) => a.type.toString().compareTo(b.type.toString())); + walletInfoSourceCopy + .sort((a, b) => a.type.toString().compareTo(b.type.toString())); } else { - walletInfoSourceCopy.sort((a, b) => b.type.toString().compareTo(a.type.toString())); + walletInfoSourceCopy + .sort((a, b) => b.type.toString().compareTo(a.type.toString())); } await _walletInfoSource.addAll(walletInfoSourceCopy); updateList(); @@ -213,7 +221,8 @@ abstract class WalletListViewModelBase with Store { name: info.name, type: info.type, key: info.key, - isCurrent: info.name == _appStore.wallet?.name && info.type == _appStore.wallet?.type, + isCurrent: info.name == _appStore.wallet?.name && + info.type == _appStore.wallet?.type, isEnabled: availableWalletTypes.contains(info.type), isTestnet: info.network?.toLowerCase().contains('testnet') ?? false, ); diff --git a/scripts/prepare_moneroc.sh b/scripts/prepare_moneroc.sh index 24f4d201c..0d90e431a 100755 --- a/scripts/prepare_moneroc.sh +++ b/scripts/prepare_moneroc.sh @@ -6,9 +6,9 @@ cd "$(dirname "$0")" if [[ ! -d "monero_c" ]]; then - git clone https://github.com/mrcyjanek/monero_c --branch rewrite-wip + git clone https://github.com/mrcyjanek/monero_c --branch master cd monero_c - git checkout 6eb571ea498ed7b854934785f00fabfd0dadf75b + git checkout 1d8e0fb30b53c28756f23676d5a3e1a99a9b3051 git reset --hard git submodule update --init --force --recursive ./apply_patches.sh monero diff --git a/tool/configure.dart b/tool/configure.dart index c5d4a6863..fb8291385 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -270,20 +270,22 @@ import 'package:cw_core/output_info.dart'; import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cw_core/wallet_service.dart'; import 'package:hive/hive.dart'; +import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger; import 'package:polyseed/polyseed.dart';"""; const moneroCWHeaders = """ +import 'package:cw_core/account.dart' as monero_account; import 'package:cw_core/get_height_by_date.dart'; import 'package:cw_core/monero_amount_format.dart'; import 'package:cw_core/monero_transaction_priority.dart'; +import 'package:cw_monero/api/wallet_manager.dart'; +import 'package:cw_monero/api/wallet.dart' as monero_wallet_api; +import 'package:cw_monero/ledger.dart'; import 'package:cw_monero/monero_unspent.dart'; import 'package:cw_monero/api/account_list.dart'; import 'package:cw_monero/monero_wallet_service.dart'; -import 'package:cw_monero/api/wallet_manager.dart'; import 'package:cw_monero/monero_wallet.dart'; import 'package:cw_monero/monero_transaction_info.dart'; import 'package:cw_monero/monero_transaction_creation_credentials.dart'; -import 'package:cw_core/account.dart' as monero_account; -import 'package:cw_monero/api/wallet.dart' as monero_wallet_api; import 'package:cw_monero/mnemonics/english.dart'; import 'package:cw_monero/mnemonics/chinese_simplified.dart'; import 'package:cw_monero/mnemonics/dutch.dart'; @@ -395,6 +397,7 @@ abstract class Monero { required String language, required int height}); WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic}); + WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required ledger.LedgerConnection ledgerConnection}); WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password}); Map getKeys(Object wallet); int? getRestoreHeight(Object wallet); @@ -411,6 +414,8 @@ abstract class Monero { int getTransactionInfoAccountId(TransactionInfo tx); WalletService createMoneroWalletService(Box walletInfoSource, Box unspentCoinSource); Map pendingTransactionInfo(Object transaction); + void setLedgerConnection(Object wallet, ledger.LedgerConnection connection); + void setGlobalLedgerConnection(ledger.LedgerConnection connection); } abstract class MoneroSubaddressList { From 96db38c0aa3b2628118302e137e7b1969b5367d0 Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 12 Nov 2024 05:29:32 +0200 Subject: [PATCH 02/41] Cw 744 improve address book (#1771) * add sort function to contact list * fix UI * prevent duplicate contact names * dispose contact source subscription * fix custom order issue * update the address book UI * fix saving custom order * fix merge conflict issue * fix the address book filter by the selected currency * add dropdown for wallets with multiple address types * minor fixes * add dropdown for wallets with multiple address types * Update lib/entities/contact.dart [skip ci] * Update lib/src/screens/contact/contact_list_page.dart [skip ci] * Update lib/src/screens/contact/contact_list_page.dart [skip ci] --------- Co-authored-by: Omar Hatem --- .../screens/contact/contact_list_page.dart | 62 ++++++++++++++++--- .../contact_list/contact_list_view_model.dart | 35 +++++++---- 2 files changed, 75 insertions(+), 22 deletions(-) diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart index 130380b09..f71747953 100644 --- a/lib/src/screens/contact/contact_list_page.dart +++ b/lib/src/screens/contact/contact_list_page.dart @@ -11,6 +11,7 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart'; +import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; @@ -160,25 +161,60 @@ class _ContactPageBodyState extends State with SingleTickerProv Widget _buildWalletContacts(BuildContext context) { final walletContacts = widget.contactListViewModel.walletContactsToShow; + final groupedContacts = >{}; + for (var contact in walletContacts) { + final baseName = _extractBaseName(contact.name); + groupedContacts.putIfAbsent(baseName, () => []).add(contact); + } + return ListView.builder( - shrinkWrap: true, - itemCount: walletContacts.length * 2, + itemCount: groupedContacts.length * 2, itemBuilder: (context, index) { if (index.isOdd) { return StandardListSeparator(); } else { - final walletInfo = walletContacts[index ~/ 2]; - return generateRaw(context, walletInfo); + final groupIndex = index ~/ 2; + final groupName = groupedContacts.keys.elementAt(groupIndex); + final groupContacts = groupedContacts[groupName]!; + + if (groupContacts.length == 1) { + final contact = groupContacts[0]; + return generateRaw(context, contact); + } else { + final activeContact = groupContacts.firstWhere( + (contact) => contact.name.contains('Active'), + orElse: () => groupContacts[0], + ); + + return ExpansionTile( + title: Text( + groupName, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Theme.of(context).extension()!.titleColor, + ), + ), + leading: _buildCurrencyIcon(activeContact), + tilePadding: EdgeInsets.zero, + childrenPadding: const EdgeInsets.only(left: 16), + expandedCrossAxisAlignment: CrossAxisAlignment.start, + expandedAlignment: Alignment.topLeft, + children: groupContacts.map((contact) => generateRaw(context, contact)).toList(), + ); + } } }, ); } + String _extractBaseName(String name) { + final bracketIndex = name.indexOf('('); + return (bracketIndex != -1) ? name.substring(0, bracketIndex).trim() : name; + } + Widget generateRaw(BuildContext context, ContactBase contact) { - final image = contact.type.iconPath; - final currencyIcon = image != null - ? Image.asset(image, height: 24, width: 24) - : const SizedBox(height: 24, width: 24); + final currencyIcon = _buildCurrencyIcon(contact); return GestureDetector( onTap: () async { @@ -219,6 +255,13 @@ class _ContactPageBodyState extends State with SingleTickerProv ); } + Widget _buildCurrencyIcon(ContactBase contact) { + final image = contact.type.iconPath; + return image != null + ? Image.asset(image, height: 24, width: 24) + : const SizedBox(height: 24, width: 24); + } + Future showNameAndAddressDialog(BuildContext context, String name, String address) async { return await showPopUp( context: context, @@ -263,12 +306,13 @@ class _ContactListBodyState extends State { @override void dispose() { widget.tabController.removeListener(_handleTabChange); + widget.contactListViewModel.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - final contacts = widget.contactListViewModel.contacts; + final contacts = widget.contactListViewModel.contactsToShow; return Scaffold( body: Container( child: FilteredList( diff --git a/lib/view_model/contact_list/contact_list_view_model.dart b/lib/view_model/contact_list/contact_list_view_model.dart index 0015463a5..25f222891 100644 --- a/lib/view_model/contact_list/contact_list_view_model.dart +++ b/lib/view_model/contact_list/contact_list_view_model.dart @@ -28,7 +28,8 @@ abstract class ContactListViewModelBase with Store { isAutoGenerateEnabled = settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.enabled { walletInfoSource.values.forEach((info) { - if ([WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) && info.addressInfos != null) { + if ([WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) && + info.addressInfos != null) { for (var key in info.addressInfos!.keys) { final value = info.addressInfos![key]; final address = value?.first; @@ -60,15 +61,19 @@ abstract class ContactListViewModelBase with Store { address, name, walletTypeToCryptoCurrency(info.type, - isTestnet: - info.network == null ? false : info.network!.toLowerCase().contains("testnet")), + isTestnet: info.network == null + ? false + : info.network!.toLowerCase().contains("testnet")), )); }); } } else { walletContacts.add(WalletContact( info.address, - _createName(info.name, "", key: [WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) ? 0 : null), + _createName(info.name, "", + key: [WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) + ? 0 + : null), walletTypeToCryptoCurrency(info.type), )); } @@ -82,8 +87,11 @@ abstract class ContactListViewModelBase with Store { } String _createName(String walletName, String label, {int? key = null}) { - final actualLabel = label.replaceAll(RegExp(r'active', caseSensitive: false), S.current.active).replaceAll(RegExp(r'silent payments', caseSensitive: false), S.current.silent_payments); - return '$walletName${key == null ? "" : " [#${key}]"} ${actualLabel.isNotEmpty ? "($actualLabel)" : ""}'.trim(); + final actualLabel = label + .replaceAll(RegExp(r'active', caseSensitive: false), S.current.active) + .replaceAll(RegExp(r'silent payments', caseSensitive: false), S.current.silent_payments); + return '$walletName${key == null ? "" : " [#${key}]"} ${actualLabel.isNotEmpty ? "($actualLabel)" : ""}' + .trim(); } final bool isAutoGenerateEnabled; @@ -108,18 +116,19 @@ abstract class ContactListViewModelBase with Store { Future delete(ContactRecord contact) async => contact.original.delete(); ObservableList get contactsToShow => - ObservableList.of(contacts.where((element) => _isValidForCurrency(element))); + ObservableList.of(contacts.where((element) => _isValidForCurrency(element, false))); @computed List get walletContactsToShow => - walletContacts.where((element) => _isValidForCurrency(element)).toList(); + walletContacts.where((element) => _isValidForCurrency(element, true)).toList(); - bool _isValidForCurrency(ContactBase element) { - if (element.name.contains('Silent Payments')) return false; - if (element.name.contains('MWEB')) return false; + bool _isValidForCurrency(ContactBase element, bool isWalletContact) { + if (_currency == null) return true; + if (!element.name.contains('Active') && + isWalletContact && + (element.type == CryptoCurrency.btc || element.type == CryptoCurrency.ltc)) return false; - return _currency == null || - element.type == _currency || + return element.type == _currency || (element.type.tag != null && _currency?.tag != null && element.type.tag == _currency?.tag) || From c4698576a3fc8c2d1da51ebdb82267e456b9d014 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Wed, 13 Nov 2024 01:19:50 +0200 Subject: [PATCH 03/41] add xmr to unstoppable domain (#1800) --- lib/entities/parse_address_from_domain.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 481db5620..11ba4724c 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -41,7 +41,8 @@ class AddressResolver { 'kresus', 'anime', 'manga', - 'binanceus' + 'binanceus', + 'xmr', ]; static String? extractAddressByType({required String raw, required CryptoCurrency type}) { From 0adb69d095a80526c02101877b2141ac20e133ab Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Wed, 13 Nov 2024 10:44:43 +0100 Subject: [PATCH 04/41] Better Ledger Connection handling (#1802) --- cw_monero/lib/ledger.dart | 6 +----- cw_monero/lib/monero_wallet_service.dart | 5 +++++ lib/monero/cw_monero.dart | 4 ++++ lib/view_model/hardware_wallet/ledger_view_model.dart | 4 +++- tool/configure.dart | 1 + 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cw_monero/lib/ledger.dart b/cw_monero/lib/ledger.dart index 074975df3..c947d0944 100644 --- a/cw_monero/lib/ledger.dart +++ b/cw_monero/lib/ledger.dart @@ -47,10 +47,6 @@ void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) { void keepAlive(LedgerConnection connection) { if (connection.connectionType == ConnectionType.ble) { - UniversalBle.onConnectionChange = (String deviceId, bool isConnected) { - print("[Monero] Ledger Disconnected"); - _ledgerKeepAlive?.cancel(); - }; _ledgerKeepAlive = Timer.periodic(Duration(seconds: 10), (_) async { try { UniversalBle.setNotifiable( @@ -59,7 +55,7 @@ void keepAlive(LedgerConnection connection) { connection.device.deviceInfo.notifyCharacteristicKey, BleInputProperty.notification, ); - } catch (_){} + } catch (_) {} }); } } diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart index b2089dfc7..6f49640be 100644 --- a/cw_monero/lib/monero_wallet_service.dart +++ b/cw_monero/lib/monero_wallet_service.dart @@ -146,6 +146,11 @@ class MoneroWalletService extends WalletService< password: password); final isValid = wallet.walletAddresses.validate(); + if (wallet.isHardwareWallet) { + wallet.setLedgerConnection(gLedger!); + gLedger = null; + } + if (!isValid) { await restoreOrResetWalletFiles(name); wallet.close(shouldCleanup: false); diff --git a/lib/monero/cw_monero.dart b/lib/monero/cw_monero.dart index 09d9889c5..89b1579fc 100644 --- a/lib/monero/cw_monero.dart +++ b/lib/monero/cw_monero.dart @@ -402,6 +402,10 @@ class CWMonero extends Monero { moneroWallet.setLedgerConnection(connection); } + void resetLedgerConnection() { + disableLedgerExchange(); + } + @override void setGlobalLedgerConnection(ledger.LedgerConnection connection) { gLedger = connection; diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart index 96f5930c0..3cd131efa 100644 --- a/lib/view_model/hardware_wallet/ledger_view_model.dart +++ b/lib/view_model/hardware_wallet/ledger_view_model.dart @@ -98,7 +98,9 @@ abstract class LedgerViewModelBase with Store { print('Ledger Device State Changed: $event'); if (event == sdk.BleConnectionState.disconnected) { _connection = null; - _connectionChangeListener?.cancel(); + if (type == WalletType.monero) { + monero!.resetLedgerConnection(); + } } }); } diff --git a/tool/configure.dart b/tool/configure.dart index fb8291385..f0f79cfb1 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -415,6 +415,7 @@ abstract class Monero { WalletService createMoneroWalletService(Box walletInfoSource, Box unspentCoinSource); Map pendingTransactionInfo(Object transaction); void setLedgerConnection(Object wallet, ledger.LedgerConnection connection); + void resetLedgerConnection(); void setGlobalLedgerConnection(ledger.LedgerConnection connection); } From ed5e701d801cd88d4905a06a6f9e2b3aa6dca510 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Wed, 13 Nov 2024 11:55:46 +0200 Subject: [PATCH 05/41] Potential fix for the race condition of loading a wallet while the name in the shared prefs hasn't updated yet (#1801) --- lib/reactions/on_current_wallet_change.dart | 7 ------- lib/store/app_store.dart | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/reactions/on_current_wallet_change.dart b/lib/reactions/on_current_wallet_change.dart index 6630f1dfc..d7e6f90c0 100644 --- a/lib/reactions/on_current_wallet_change.dart +++ b/lib/reactions/on_current_wallet_change.dart @@ -10,9 +10,6 @@ import 'package:cw_core/transaction_history.dart'; import 'package:cw_core/balance.dart'; import 'package:cw_core/transaction_info.dart'; import 'package:mobx/mobx.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/reactions/check_connection.dart'; import 'package:cake_wallet/reactions/on_wallet_sync_status_change.dart'; import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; @@ -65,10 +62,6 @@ void startCurrentWalletChangeReaction( startWalletSyncStatusChangeReaction(wallet, fiatConversionStore); startCheckConnectionReaction(wallet, settingsStore); - await getIt.get().setString(PreferencesKey.currentWalletName, wallet.name); - await getIt - .get() - .setInt(PreferencesKey.currentWalletType, serializeToInt(wallet.type)); if (wallet.type == WalletType.monero || wallet.type == WalletType.wownero || diff --git a/lib/store/app_store.dart b/lib/store/app_store.dart index cd8881633..24d5dc6a4 100644 --- a/lib/store/app_store.dart +++ b/lib/store/app_store.dart @@ -1,8 +1,10 @@ import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart'; import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/reactions/wallet_connect.dart'; import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cw_core/transaction_info.dart'; +import 'package:cw_core/wallet_type.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/balance.dart'; import 'package:cw_core/wallet_base.dart'; @@ -11,6 +13,7 @@ import 'package:cake_wallet/store/wallet_list_store.dart'; import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/node_list_store.dart'; +import 'package:shared_preferences/shared_preferences.dart'; part 'app_store.g.dart'; @@ -47,5 +50,9 @@ abstract class AppStoreBase with Store { getIt.get().create(); await getIt.get().init(); } + await getIt.get().setString(PreferencesKey.currentWalletName, wallet.name); + await getIt + .get() + .setInt(PreferencesKey.currentWalletType, serializeToInt(wallet.type)); } } From cf7f019a925bec52086a63f6785e4c4dfa329298 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 14 Nov 2024 03:20:08 +0200 Subject: [PATCH 06/41] fix the UI issue with address book (#1803) --- .../screens/contact/contact_list_page.dart | 19 +++++++++++++------ .../contact_list/contact_list_view_model.dart | 7 ++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart index f71747953..878a8bb54 100644 --- a/lib/src/screens/contact/contact_list_page.dart +++ b/lib/src/screens/contact/contact_list_page.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/core/auth_service.dart'; +import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/contact_base.dart'; import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/entities/wallet_list_order_types.dart'; @@ -11,14 +12,12 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart'; -import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; class ContactListPage extends BasePage { @@ -92,16 +91,19 @@ class ContactPageBody extends StatefulWidget { class _ContactPageBodyState extends State with SingleTickerProviderStateMixin { late TabController _tabController; + late ContactListViewModel contactListViewModel; @override void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); + contactListViewModel = widget.contactListViewModel; } @override void dispose() { _tabController.dispose(); + contactListViewModel.dispose(); super.dispose(); } @@ -306,13 +308,17 @@ class _ContactListBodyState extends State { @override void dispose() { widget.tabController.removeListener(_handleTabChange); - widget.contactListViewModel.dispose(); + if (widget.contactListViewModel.settingsStore.contactListOrder == FilterListOrderType.Custom) { + widget.contactListViewModel.saveCustomOrder(); + } super.dispose(); } @override Widget build(BuildContext context) { - final contacts = widget.contactListViewModel.contactsToShow; + final contacts = widget.contactListViewModel.isEditable + ? widget.contactListViewModel.contacts + : widget.contactListViewModel.contactsToShow; return Scaffold( body: Container( child: FilteredList( @@ -351,8 +357,9 @@ class _ContactListBodyState extends State { }, ), ), - floatingActionButton: - _isContactsTabActive ? filterButtonWidget(context, widget.contactListViewModel) : null, + floatingActionButton: _isContactsTabActive && widget.contactListViewModel.isEditable + ? filterButtonWidget(context, widget.contactListViewModel) + : null, ); } diff --git a/lib/view_model/contact_list/contact_list_view_model.dart b/lib/view_model/contact_list/contact_list_view_model.dart index 25f222891..eb3fb837e 100644 --- a/lib/view_model/contact_list/contact_list_view_model.dart +++ b/lib/view_model/contact_list/contact_list_view_model.dart @@ -136,10 +136,11 @@ abstract class ContactListViewModelBase with Store { _currency?.tag == element.type.toString(); } - void dispose() async { - _subscription?.cancel(); + void dispose() => _subscription?.cancel(); + + void saveCustomOrder() { final List contactsSourceCopy = contacts.map((e) => e.original).toList(); - await reorderContacts(contactsSourceCopy); + reorderContacts(contactsSourceCopy); } void reorderAccordingToContactList() => From 9be990a3c094b76a22e55e89c4144ecbfeee9ca6 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Sat, 16 Nov 2024 11:06:49 -0600 Subject: [PATCH 07/41] Move the api key of trocador to the headers (#1808) --- .../provider/trocador_exchange_provider.dart | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/exchange/provider/trocador_exchange_provider.dart b/lib/exchange/provider/trocador_exchange_provider.dart index 652543607..5529d824a 100644 --- a/lib/exchange/provider/trocador_exchange_provider.dart +++ b/lib/exchange/provider/trocador_exchange_provider.dart @@ -89,13 +89,12 @@ class TrocadorExchangeProvider extends ExchangeProvider { required CryptoCurrency to, required bool isFixedRateMode}) async { final params = { - 'api_key': apiKey, 'ticker': _normalizeCurrency(from), 'name': from.name, }; final uri = await _getUri(coinPath, params); - final response = await get(uri); + final response = await get(uri, headers: {'API-Key': apiKey}); if (response.statusCode != 200) throw Exception('Unexpected http status: ${response.statusCode}'); @@ -123,7 +122,6 @@ class TrocadorExchangeProvider extends ExchangeProvider { if (amount == 0) return 0.0; final params = { - 'api_key': apiKey, 'ticker_from': _normalizeCurrency(from), 'ticker_to': _normalizeCurrency(to), 'network_from': _networkFor(from), @@ -136,7 +134,8 @@ class TrocadorExchangeProvider extends ExchangeProvider { }; final uri = await _getUri(newRatePath, params); - final response = await get(uri); + final response = await get(uri, headers: {'API-Key': apiKey}); + final responseJSON = json.decode(response.body) as Map; final fromAmount = double.parse(responseJSON['amount_from'].toString()); final toAmount = double.parse(responseJSON['amount_to'].toString()); @@ -161,7 +160,6 @@ class TrocadorExchangeProvider extends ExchangeProvider { required bool isSendAll, }) async { final params = { - 'api_key': apiKey, 'ticker_from': _normalizeCurrency(request.fromCurrency), 'ticker_to': _normalizeCurrency(request.toCurrency), 'network_from': _networkFor(request.fromCurrency), @@ -202,7 +200,7 @@ class TrocadorExchangeProvider extends ExchangeProvider { params['provider'] = firstAvailableProvider; final uri = await _getUri(createTradePath, params); - final response = await get(uri); + final response = await get(uri, headers: {'API-Key': apiKey}); if (response.statusCode == 400) { final responseJSON = json.decode(response.body) as Map; @@ -248,8 +246,8 @@ class TrocadorExchangeProvider extends ExchangeProvider { @override Future findTradeById({required String id}) async { - final uri = await _getUri(tradePath, {'api_key': apiKey, 'id': id}); - return get(uri).then((response) { + final uri = await _getUri(tradePath, {'id': id}); + return get(uri, headers: {'API-Key': apiKey}).then((response) { if (response.statusCode != 200) throw Exception('Unexpected http status: ${response.statusCode}'); From ff5fbd794649619085568e6ff572227a83fff23e Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Sat, 16 Nov 2024 16:23:54 -0600 Subject: [PATCH 08/41] v4.21.0 Release Candidate (#1795) * new versions * minor fix of cache key * fix cache hit * - potential improvement for sync status - update with latest main * disable thorchain by default [skip ci] * update monero_c commit hash * minor fixes update versions * remove monero ledger * increase macos build number [skip ci] --- assets/text/Monerocom_Release_Notes.txt | 4 +- assets/text/Release_Notes.txt | 10 +-- cw_bitcoin/lib/electrum_wallet.dart | 9 +- cw_bitcoin/pubspec.lock | 4 +- .../lib/hardware/device_connection_type.dart | 2 +- cw_monero/pubspec.lock | 4 +- cw_monero/pubspec.yaml | 2 +- cw_wownero/pubspec.lock | 88 +------------------ cw_wownero/pubspec.yaml | 2 +- ios/Podfile.lock | 38 +++----- ios/Runner.xcodeproj/project.pbxproj | 18 ++++ lib/buy/meld/meld_buy_provider.dart | 4 - lib/entities/default_settings_migration.dart | 8 +- .../screens/contact/contact_list_page.dart | 18 ++-- .../screens/restore/restore_options_page.dart | 5 +- linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + scripts/android/app_env.sh | 8 +- scripts/ios/app_env.sh | 8 +- scripts/linux/app_env.sh | 4 +- scripts/macos/app_env.sh | 8 +- scripts/prepare_moneroc.sh | 2 +- scripts/windows/build_exe_installer.iss | 2 +- windows/flutter/generated_plugins.cmake | 1 + 24 files changed, 92 insertions(+), 160 deletions(-) diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt index 613ea4281..46f21e172 100644 --- a/assets/text/Monerocom_Release_Notes.txt +++ b/assets/text/Monerocom_Release_Notes.txt @@ -1,3 +1,3 @@ -Monero enhancements -Introducing StealthEx and LetxExchange +Add airgapped Monero wallet support (best used with our new offline app Cupcake) +New Buy & Sell flow Bug fixes \ No newline at end of file diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index 61aafb6e4..6764826a7 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1,7 +1,5 @@ -Added Litecoin MWEB -Added wallet groups -Silent Payment enhancements for speed & reliability -Monero enhancements -Introducing StealthEx and LetxExchange -Additional ERC20 tokens scam detection +Add Litecoin Ledger support +Add airgapped Monero wallet support (best used with our new offline app Cupcake) +MWEB fixes and enhancements +New Buy & Sell flow Bug fixes \ No newline at end of file diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 6245aa787..e58fad00f 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -574,6 +574,8 @@ abstract class ElectrumWalletBase Future connectToNode({required Node node}) async { this.node = node; + if (syncStatus is ConnectingSyncStatus) return; + try { syncStatus = ConnectingSyncStatus(); @@ -2216,13 +2218,14 @@ abstract class ElectrumWalletBase if (syncStatus is NotConnectedSyncStatus || syncStatus is LostConnectionSyncStatus || syncStatus is ConnectingSyncStatus) { - syncStatus = AttemptingSyncStatus(); - startSync(); + syncStatus = ConnectedSyncStatus(); } break; case ConnectionStatus.disconnected: - if (syncStatus is! NotConnectedSyncStatus) { + if (syncStatus is! NotConnectedSyncStatus && + syncStatus is! ConnectingSyncStatus && + syncStatus is! SyncronizingSyncStatus) { syncStatus = NotConnectedSyncStatus(); } break; diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index 8eafb2a44..c8a83f90c 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -87,8 +87,8 @@ packages: dependency: "direct overridden" description: path: "." - ref: cake-update-v8 - resolved-ref: fc045a11db3d85d806ca67f75e8b916c706745a2 + ref: cake-update-v9 + resolved-ref: "86969a14e337383e14965f5fb45a72a63e5009bc" url: "https://github.com/cake-tech/bitcoin_base" source: git version: "4.7.0" diff --git a/cw_core/lib/hardware/device_connection_type.dart b/cw_core/lib/hardware/device_connection_type.dart index 76a501af1..466d58e2a 100644 --- a/cw_core/lib/hardware/device_connection_type.dart +++ b/cw_core/lib/hardware/device_connection_type.dart @@ -7,7 +7,7 @@ enum DeviceConnectionType { static List supportedConnectionTypes(WalletType walletType, [bool isIOS = false]) { switch (walletType) { - case WalletType.monero: + // case WalletType.monero: case WalletType.bitcoin: case WalletType.litecoin: case WalletType.ethereum: diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index a6a03dce5..31d44ac63 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -503,8 +503,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b - resolved-ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b + ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 + resolved-ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml index 6fa235ee4..71cbfa243 100644 --- a/cw_monero/pubspec.yaml +++ b/cw_monero/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: monero: git: url: https://github.com/mrcyjanek/monero_c - ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b + ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 # ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash path: impls/monero.dart mutex: ^3.1.0 diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock index b0347c023..a861c6bac 100644 --- a/cw_wownero/pubspec.lock +++ b/cw_wownero/pubspec.lock @@ -41,14 +41,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" - bluez: - dependency: transitive - description: - name: bluez - sha256: "203a1924e818a9dd74af2b2c7a8f375ab8e5edf0e486bba8f90a0d8a17ed9fce" - url: "https://pub.dev" - source: hosted - version: "0.8.2" boolean_selector: dependency: transitive description: @@ -217,14 +209,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.4" - dbus: - dependency: transitive - description: - name: dbus - sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" - url: "https://pub.dev" - source: hosted - version: "0.7.10" encrypt: dependency: "direct main" description: @@ -283,14 +267,6 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_web_bluetooth: - dependency: transitive - description: - name: flutter_web_bluetooth - sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02" - url: "https://pub.dev" - source: hosted - version: "0.2.3" frontend_server_client: dependency: transitive description: @@ -427,22 +403,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" - ledger_flutter_plus: - dependency: transitive - description: - name: ledger_flutter_plus - sha256: ea3ed586e1697776dacf42ac979095f1ca3bd143bf007cbe5c78e09cb6943f42 - url: "https://pub.dev" - source: hosted - version: "1.2.5" - ledger_usb_plus: - dependency: transitive - description: - name: ledger_usb_plus - sha256: "21cc5d976cf7edb3518bd2a0c4164139cbb0817d2e4f2054707fc4edfdf9ce87" - url: "https://pub.dev" - source: hosted - version: "1.0.4" logging: dependency: transitive description: @@ -503,8 +463,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b - resolved-ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b + ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 + resolved-ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" @@ -580,14 +540,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 - url: "https://pub.dev" - source: hosted - version: "6.0.2" platform: dependency: transitive description: @@ -644,14 +596,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" - rxdart: - dependency: transitive - description: - name: rxdart - sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" - url: "https://pub.dev" - source: hosted - version: "0.28.0" shelf: dependency: transitive description: @@ -777,22 +721,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" - universal_ble: - dependency: transitive - description: - name: universal_ble - sha256: "0dfbd6b64bff3ad61ed7a895c232530d9614e9b01ab261a74433a43267edb7f3" - url: "https://pub.dev" - source: hosted - version: "0.12.0" - universal_platform: - dependency: transitive - description: - name: universal_platform - sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" - url: "https://pub.dev" - source: hosted - version: "1.1.0" unorm_dart: dependency: transitive description: @@ -849,14 +777,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" - xml: - dependency: transitive - description: - name: xml - sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 - url: "https://pub.dev" - source: hosted - version: "6.5.0" yaml: dependency: transitive description: @@ -866,5 +786,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.2.0-0 <4.0.0" + flutter: ">=3.7.0" diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml index 582c15447..28ece82ef 100644 --- a/cw_wownero/pubspec.yaml +++ b/cw_wownero/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: monero: git: url: https://github.com/mrcyjanek/monero_c - ref: caaf1e56b1d2a254b332fdf848926fb963af4a3b + ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 # ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash path: impls/monero.dart mutex: ^3.1.0 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 470bdf4e7..abcac01fb 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,8 +1,4 @@ PODS: - - barcode_scan2 (0.0.1): - - Flutter - - MTBBarcodeScanner - - SwiftProtobuf - connectivity_plus (0.0.1): - Flutter - ReachabilitySwift @@ -76,6 +72,8 @@ PODS: - DKPhotoGallery/Resource (0.0.19): - SDWebImage - SwiftyGif + - fast_scanner (5.1.1): + - Flutter - file_picker (0.0.1): - DKImagePickerController/PhotoGallery - Flutter @@ -100,7 +98,6 @@ PODS: - Flutter - integration_test (0.0.1): - Flutter - - MTBBarcodeScanner (5.0.11) - OrderedSet (5.0.0) - package_info_plus (0.4.5): - Flutter @@ -109,12 +106,7 @@ PODS: - FlutterMacOS - permission_handler_apple (9.1.1): - Flutter - - Protobuf (3.28.2) - ReachabilitySwift (5.2.3) - - reactive_ble_mobile (0.0.1): - - Flutter - - Protobuf (~> 3.5) - - SwiftProtobuf (~> 1.0) - SDWebImage (5.19.7): - SDWebImage/Core (= 5.19.7) - SDWebImage/Core (5.19.7) @@ -127,11 +119,13 @@ PODS: - FlutterMacOS - sp_scanner (0.0.1): - Flutter - - SwiftProtobuf (1.27.1) - SwiftyGif (5.4.5) - Toast (4.1.1) - uni_links (0.0.1): - Flutter + - universal_ble (0.0.1): + - Flutter + - FlutterMacOS - url_launcher_ios (0.0.1): - Flutter - wakelock_plus (0.0.1): @@ -140,7 +134,6 @@ PODS: - Flutter DEPENDENCIES: - - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - CryptoSwift - cw_haven (from `.symlinks/plugins/cw_haven/ios`) @@ -149,6 +142,7 @@ DEPENDENCIES: - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`) + - fast_scanner (from `.symlinks/plugins/fast_scanner/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) @@ -161,12 +155,12 @@ DEPENDENCIES: - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - - reactive_ble_mobile (from `.symlinks/plugins/reactive_ble_mobile/ios`) - sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - sp_scanner (from `.symlinks/plugins/sp_scanner/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`) + - universal_ble (from `.symlinks/plugins/universal_ble/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) - workmanager (from `.symlinks/plugins/workmanager/ios`) @@ -176,18 +170,13 @@ SPEC REPOS: - CryptoSwift - DKImagePickerController - DKPhotoGallery - - MTBBarcodeScanner - OrderedSet - - Protobuf - ReachabilitySwift - SDWebImage - - SwiftProtobuf - SwiftyGif - Toast EXTERNAL SOURCES: - barcode_scan2: - :path: ".symlinks/plugins/barcode_scan2/ios" connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" cw_haven: @@ -202,6 +191,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/device_info_plus/ios" devicelocale: :path: ".symlinks/plugins/devicelocale/ios" + fast_scanner: + :path: ".symlinks/plugins/fast_scanner/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" Flutter: @@ -226,8 +217,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" - reactive_ble_mobile: - :path: ".symlinks/plugins/reactive_ble_mobile/ios" sensitive_clipboard: :path: ".symlinks/plugins/sensitive_clipboard/ios" share_plus: @@ -238,6 +227,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sp_scanner/ios" uni_links: :path: ".symlinks/plugins/uni_links/ios" + universal_ble: + :path: ".symlinks/plugins/universal_ble/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" wakelock_plus: @@ -246,7 +237,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/workmanager/ios" SPEC CHECKSUMS: - barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a @@ -257,6 +247,7 @@ SPEC CHECKSUMS: devicelocale: b22617f40038496deffba44747101255cee005b0 DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 + fast_scanner: 44c00940355a51258cd6c2085734193cd23d95bc file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0 @@ -266,23 +257,20 @@ SPEC CHECKSUMS: fluttertoast: 48c57db1b71b0ce9e6bba9f31c940ff4b001293c in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d integration_test: 13825b8a9334a850581300559b8839134b124670 - MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 - Protobuf: 28c89b24435762f60244e691544ed80f50d82701 ReachabilitySwift: 7f151ff156cea1481a8411701195ac6a984f4979 - reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3 sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986 share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12 - SwiftProtobuf: b109bd17979d7993a84da14b1e1fdd8b0ded934a SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e uni_links: d97da20c7701486ba192624d99bffaaffcfc298a + universal_ble: cf52a7b3fd2e7c14d6d7262e9fdadb72ab6b88a6 url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 09c75feee..85d39167a 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -230,6 +230,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, F6F67323547956BC4F7B67F1 /* [CP] Embed Pods Frameworks */, + 777FE2B16F25A3E820834145 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -343,6 +344,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; }; + 777FE2B16F25A3E820834145 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; diff --git a/lib/buy/meld/meld_buy_provider.dart b/lib/buy/meld/meld_buy_provider.dart index 696301f2e..1ac3931d1 100644 --- a/lib/buy/meld/meld_buy_provider.dart +++ b/lib/buy/meld/meld_buy_provider.dart @@ -5,14 +5,10 @@ import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_quote.dart'; import 'package:cake_wallet/buy/payment_method.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; -import 'package:cake_wallet/entities/provider_types.dart'; import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/currency.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:flutter/material.dart'; import 'dart:developer'; diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index d863b136e..f873314c0 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -252,7 +252,7 @@ Future defaultSettingsMigration( await removeMoneroWorld(sharedPreferences: sharedPreferences, nodes: nodes); break; case 41: - _deselectQuantex(sharedPreferences); + _deselectExchangeProvider(sharedPreferences, "Quantex"); await _addSethNode(nodes, sharedPreferences); await updateTronNodesWithNowNodes(sharedPreferences: sharedPreferences, nodes: nodes); break; @@ -261,6 +261,8 @@ Future defaultSettingsMigration( break; case 43: _updateCakeXmrNode(nodes); + _deselectExchangeProvider(sharedPreferences, "THORChain"); + _deselectExchangeProvider(sharedPreferences, "SimpleSwap"); break; default: @@ -295,12 +297,12 @@ void updateBtcElectrumNodeToUseSSL(Box nodes, SharedPreferences sharedPref } } -void _deselectQuantex(SharedPreferences sharedPreferences) { +void _deselectExchangeProvider(SharedPreferences sharedPreferences, String providerName) { final Map exchangeProvidersSelection = json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") as Map; - exchangeProvidersSelection['Quantex'] = false; + exchangeProvidersSelection[providerName] = false; sharedPreferences.setString( PreferencesKey.exchangeProvidersSelection, diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart index 878a8bb54..166288135 100644 --- a/lib/src/screens/contact/contact_list_page.dart +++ b/lib/src/screens/contact/contact_list_page.dart @@ -240,14 +240,16 @@ class _ContactPageBodyState extends State with SingleTickerProv mainAxisAlignment: MainAxisAlignment.start, children: [ currencyIcon, - Padding( - padding: EdgeInsets.only(left: 12), - child: Text( - contact.name, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.normal, - color: Theme.of(context).extension()!.titleColor, + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 12), + child: Text( + contact.name, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Theme.of(context).extension()!.titleColor, + ), ), ), ), diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart index 299846a72..d1d419d60 100644 --- a/lib/src/screens/restore/restore_options_page.dart +++ b/lib/src/screens/restore/restore_options_page.dart @@ -56,8 +56,9 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> { } if (isMoneroOnly) { - return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS) - .isNotEmpty; + // return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS) + // .isNotEmpty; + return false; } return true; diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 4b9eb3b2d..f52be7481 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 52b44e53e..42b9fa84c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import connectivity_plus +import cw_mweb import device_info_plus import devicelocale import fast_scanner @@ -23,6 +24,7 @@ import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + CwMwebPlugin.register(with: registry.registrar(forPlugin: "CwMwebPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 8beffbcc2..7eee6d6ae 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.17.0" -MONERO_COM_BUILD_NUMBER=103 +MONERO_COM_VERSION="1.18.0" +MONERO_COM_BUILD_NUMBER=105 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.20.1" -CAKEWALLET_BUILD_NUMBER=233 +CAKEWALLET_VERSION="4.21.0" +CAKEWALLET_BUILD_NUMBER=236 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 bc3b39747..fe18758c8 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.17.0" -MONERO_COM_BUILD_NUMBER=101 +MONERO_COM_VERSION="1.18.0" +MONERO_COM_BUILD_NUMBER=103 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.20.1" -CAKEWALLET_BUILD_NUMBER=277 +CAKEWALLET_VERSION="4.21.0" +CAKEWALLET_BUILD_NUMBER=281 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh index 2dabf083b..1cdb43ced 100755 --- a/scripts/linux/app_env.sh +++ b/scripts/linux/app_env.sh @@ -14,8 +14,8 @@ if [ -n "$1" ]; then fi CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.10.1" -CAKEWALLET_BUILD_NUMBER=37 +CAKEWALLET_VERSION="1.11.0" +CAKEWALLET_BUILD_NUMBER=38 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then echo "Wrong app type." diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index 026ea034b..8f3b68ab5 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.7.0" -MONERO_COM_BUILD_NUMBER=34 +MONERO_COM_VERSION="1.8.0" +MONERO_COM_BUILD_NUMBER=36 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.13.1" -CAKEWALLET_BUILD_NUMBER=93 +CAKEWALLET_VERSION="1.14.0" +CAKEWALLET_BUILD_NUMBER=95 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then diff --git a/scripts/prepare_moneroc.sh b/scripts/prepare_moneroc.sh index 0d90e431a..3596bd18b 100755 --- a/scripts/prepare_moneroc.sh +++ b/scripts/prepare_moneroc.sh @@ -8,7 +8,7 @@ if [[ ! -d "monero_c" ]]; then git clone https://github.com/mrcyjanek/monero_c --branch master cd monero_c - git checkout 1d8e0fb30b53c28756f23676d5a3e1a99a9b3051 + git checkout d72c15f4339791a7bbdf17e9d827b7b56ca144e4 git reset --hard git submodule update --init --force --recursive ./apply_patches.sh monero diff --git a/scripts/windows/build_exe_installer.iss b/scripts/windows/build_exe_installer.iss index f65900cca..25f94cb1f 100644 --- a/scripts/windows/build_exe_installer.iss +++ b/scripts/windows/build_exe_installer.iss @@ -1,5 +1,5 @@ #define MyAppName "Cake Wallet" -#define MyAppVersion "0.1.1" +#define MyAppVersion "0.2.0" #define MyAppPublisher "Cake Labs LLC" #define MyAppURL "https://cakewallet.com/" #define MyAppExeName "CakeWallet.exe" diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 26d481f85..92431a6fb 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -13,6 +13,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) From 29b659e748e800921e7c1c2127c006d1cb11c649 Mon Sep 17 00:00:00 2001 From: XD22 Date: Thu, 21 Nov 2024 22:04:46 +0200 Subject: [PATCH 09/41] Fix Whitespace in secret_key.dart (#1812) --- tool/utils/secret_key.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index affe4017c..d67ab7605 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -62,7 +62,7 @@ class SecretKey { SecretKey('bitcoinTestWalletReceiveAddress', () => ''), SecretKey('ethereumTestWalletReceiveAddress', () => ''), SecretKey('litecoinTestWalletReceiveAddress', () => ''), - SecretKey('bitco inCashTestWalletReceiveAddress', () => ''), + SecretKey('bitcoinCashTestWalletReceiveAddress', () => ''), SecretKey('polygonTestWalletReceiveAddress', () => ''), SecretKey('solanaTestWalletReceiveAddress', () => ''), SecretKey('tronTestWalletReceiveAddress', () => ''), From cfe78d4e5f9f838ae1be6a7d2d3397dc2771bd4a Mon Sep 17 00:00:00 2001 From: cyan Date: Sun, 24 Nov 2024 09:49:42 +0100 Subject: [PATCH 10/41] Fix error reporting in transaction creation (#1821) --- cw_monero/lib/api/transaction_history.dart | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index 7748a16af..f55545801 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -192,14 +192,23 @@ String? commitTransaction({required monero.PendingTransaction transactionPointer ? monero.PendingTransaction_commitUR(transactionPointer, 120) : monero.PendingTransaction_commit(transactionPointer, filename: '', overwrite: false); - final String? error = (() { + String? error = (() { final status = monero.PendingTransaction_status(transactionPointer.cast()); if (status == 0) { return null; } - return monero.Wallet_errorString(wptr!); + return monero.PendingTransaction_errorString(transactionPointer.cast()); })(); + if (error == null) { + error = (() { + final status = monero.Wallet_status(wptr!); + if (status == 0) { + return null; + } + return monero.Wallet_errorString(wptr!); + })(); + } if (error != null) { throw CreationTransactionException(message: error); } From 505ea265337148c921d271518626265eca07bc91 Mon Sep 17 00:00:00 2001 From: cyan Date: Mon, 25 Nov 2024 15:08:30 +0100 Subject: [PATCH 11/41] CW-798 Fix macos 15 issues (#1775) * update flutter to 3.24.3 * bump flutter to 3.24.4, fix all android issues (i hope) * update uni_links path * update sensitive_clipboard * update dependencies * update fast_scanner * update the ref * Update how_to_add_new_wallet_type.md [skip ci] * Update how_to_add_new_wallet_type.md [skip ci] * Update how_to_add_new_wallet_type.md [skip ci] * Update how_to_add_new_wallet_type.md [skip ci] --------- Co-authored-by: Omar Hatem --- .github/workflows/cache_dependencies.yml | 2 +- .github/workflows/pr_test_build_android.yml | 6 +- .github/workflows/pr_test_build_linux.yml | 4 +- android/app/build.gradle | 5 +- android/build.gradle | 4 +- android/gradle.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- build-guide-linux.md | 4 +- configure_cake_wallet.sh | 6 +- cw_bitcoin/pubspec.lock | 118 +++++---- cw_bitcoin/pubspec.yaml | 2 +- cw_core/pubspec.lock | 225 +++++++++------- cw_core/pubspec.yaml | 2 +- cw_haven/pubspec.lock | 248 ++++++++++-------- cw_haven/pubspec.yaml | 2 +- .../.plugin_symlinks/path_provider_linux | 1 + cw_monero/pubspec.lock | 108 ++++---- cw_monero/pubspec.yaml | 2 +- cw_mweb/android/build.gradle | 16 +- cw_mweb/android/settings.gradle | 2 + cw_nano/pubspec.lock | 236 +++++++++-------- cw_wownero/pubspec.lock | 248 ++++++++++-------- cw_wownero/pubspec.yaml | 2 +- how_to_add_new_wallet_type.md | 10 +- howto-build-android.md | 12 +- howto-build-ios.md | 8 +- howto-build-macos.md | 8 +- howto-build-windows.md | 4 +- ios/Podfile.lock | 75 ++---- ios/Runner/AppDelegate.swift | 2 +- lib/locales/hausa_intl.dart | 8 + lib/locales/yoruba_intl.dart | 8 + linux/flutter/generated_plugins.cmake | 1 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 - model_generator.sh | 25 +- pubspec_base.yaml | 48 ++-- pubspec_description.yaml | 2 +- run-android.sh | 7 +- scripts/android/inject_app_details.sh | 12 +- scripts/android/pubspec_gen.sh | 4 +- scripts/ios/app_config.sh | 10 +- scripts/linux/app_config.sh | 8 +- scripts/macos/app_config.sh | 15 +- scripts/macos/gen_common.sh | 6 +- scripts/universal_sed.sh | 23 ++ tool/append_translation.dart | 2 +- tool/configure.dart | 3 +- .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 2 +- 49 files changed, 841 insertions(+), 714 deletions(-) create mode 120000 cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux create mode 100644 scripts/universal_sed.sh diff --git a/.github/workflows/cache_dependencies.yml b/.github/workflows/cache_dependencies.yml index ce098b7f1..938027e81 100644 --- a/.github/workflows/cache_dependencies.yml +++ b/.github/workflows/cache_dependencies.yml @@ -34,7 +34,7 @@ jobs: - name: Flutter action uses: subosito/flutter-action@v1 with: - flutter-version: "3.19.6" + flutter-version: "3.24.4" channel: stable - name: Install package dependencies diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index 774404e3b..e3617f81e 100644 --- a/.github/workflows/pr_test_build_android.yml +++ b/.github/workflows/pr_test_build_android.yml @@ -53,7 +53,7 @@ jobs: - name: Flutter action uses: subosito/flutter-action@v1 with: - flutter-version: "3.19.6" + flutter-version: "3.24.4" channel: stable - name: Install package dependencies @@ -131,12 +131,12 @@ jobs: - name: Generate key properties run: | cd /opt/android/cake_wallet - flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS + dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS - name: Generate localization run: | cd /opt/android/cake_wallet - flutter packages pub run tool/generate_localization.dart + dart run tool/generate_localization.dart - name: Build generated code run: | diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml index f3ce1045d..9e25f9f7a 100644 --- a/.github/workflows/pr_test_build_linux.yml +++ b/.github/workflows/pr_test_build_linux.yml @@ -38,7 +38,7 @@ jobs: - name: Flutter action uses: subosito/flutter-action@v1 with: - flutter-version: "3.19.6" + flutter-version: "3.24.4" channel: stable - name: Install package dependencies @@ -111,7 +111,7 @@ jobs: - name: Generate localization run: | cd /opt/android/cake_wallet - flutter packages pub run tool/generate_localization.dart + dart run tool/generate_localization.dart - name: Build generated code run: | diff --git a/android/app/build.gradle b/android/app/build.gradle index 5005a8bab..628e2ffe6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -38,11 +38,14 @@ if (appPropertiesFile.exists()) { android { compileSdkVersion 34 + buildToolsVersion "34.0.0" lintOptions { disable 'InvalidPackage' } + namespace 'com.cakewallet.cake_wallet' + defaultConfig { applicationId appProperties['id'] minSdkVersion 24 @@ -80,7 +83,7 @@ android { } } - ndkVersion "25.1.8937393" + ndkVersion "27.0.12077973" } flutter { diff --git a/android/build.gradle b/android/build.gradle index 7ddb75179..66de0bdca 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.8.21' + ext.kotlin_version = '2.0.21' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.7.1' classpath 'com.google.gms:google-services:4.3.8' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } diff --git a/android/gradle.properties b/android/gradle.properties index 66dd09454..d130e538a 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx3072M +org.gradle.jvmargs=-Xmx4096M android.enableR8=true android.useAndroidX=true android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 733c691d3..0cc4e42b9 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip diff --git a/build-guide-linux.md b/build-guide-linux.md index 55264fbfa..99c2ed0c8 100644 --- a/build-guide-linux.md +++ b/build-guide-linux.md @@ -120,7 +120,7 @@ Install Flutter package dependencies with this command: Your CakeWallet binary will be built with some specific keys for iterate with 3rd party services. You may generate these secret keys placeholders with the following command: -`$ flutter packages pub run tool/generate_new_secrets.dart` +`$ dart run tool/generate_new_secrets.dart` We will generate mobx models for the project. @@ -128,7 +128,7 @@ We will generate mobx models for the project. Then we need to generate localization files. -`$ flutter packages pub run tool/generate_localization.dart` +`$ dart run tool/generate_localization.dart` ### 5. Build! diff --git a/configure_cake_wallet.sh b/configure_cake_wallet.sh index 90ce1c446..a083ec7ff 100755 --- a/configure_cake_wallet.sh +++ b/configure_cake_wallet.sh @@ -1,5 +1,5 @@ #!/bin/bash - +set -x -e IOS="ios" ANDROID="android" MACOS="macos" @@ -36,6 +36,6 @@ fi source ./app_env.sh cakewallet ./app_config.sh cd ../.. && flutter pub get -flutter packages pub run tool/generate_localization.dart -./model_generator.sh +dart run tool/generate_localization.dart +#./model_generator.sh #cd macos && pod install diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index c8a83f90c..aa9f3ba05 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -29,10 +29,10 @@ packages: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" asn1lib: dependency: transitive description: @@ -145,10 +145,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" build_resolvers: dependency: "direct dev" description: @@ -161,10 +161,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.13" build_runner_core: dependency: transitive description: @@ -250,18 +250,18 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.6" cryptography: dependency: "direct main" description: @@ -360,10 +360,10 @@ packages: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -431,10 +431,10 @@ packages: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" grpc: dependency: "direct main" description: @@ -503,10 +503,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -535,26 +535,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" ledger_bitcoin: dependency: "direct main" description: @@ -577,7 +577,7 @@ packages: description: path: "packages/ledger-litecoin" ref: HEAD - resolved-ref: "07cd61ef76a2a017b6d5ef233396740163265457" + resolved-ref: "3dee36713e6ebec9dceb59b9ccae7f243a53ea9e" url: "https://github.com/cake-tech/ledger-flutter-plus-plugins" source: git version: "0.0.2" @@ -593,10 +593,10 @@ packages: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" matcher: dependency: transitive description: @@ -609,26 +609,26 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" mime: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "2.0.0" mobx: dependency: "direct main" description: @@ -681,10 +681,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.12" path_provider_foundation: dependency: transitive description: @@ -729,10 +729,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -809,18 +809,18 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 + sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2" + sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.3" shared_preferences_foundation: dependency: transitive description: @@ -849,10 +849,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "59dc807b94d29d52ddbb1b3c0d3b9d0a67fc535a64e62a5542c8db0513fcb6c2" + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: @@ -873,10 +873,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -967,10 +967,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.2" timing: dependency: transitive description: @@ -991,10 +991,10 @@ packages: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" universal_ble: dependency: transitive description: @@ -1031,10 +1031,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.5" watcher: dependency: "direct overridden" description: @@ -1047,18 +1047,26 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "3.0.1" xdg_directories: dependency: transitive description: @@ -1092,5 +1100,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml index bff6104ac..522199c82 100644 --- a/cw_bitcoin/pubspec.yaml +++ b/cw_bitcoin/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: http: ^1.1.0 mobx: ^2.0.7+4 flutter_mobx: ^2.0.6+1 - intl: ^0.18.0 + intl: ^0.19.0 shared_preferences: ^2.0.15 cw_core: path: ../cw_core diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock index c2bdda5f1..44ef15a41 100644 --- a/cw_core/pubspec.lock +++ b/cw_core/pubspec.lock @@ -5,34 +5,39 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "64.0.0" + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.7.0" args: dependency: transitive description: name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.6.0" asn1lib: dependency: transitive description: name: asn1lib - sha256: "21afe4333076c02877d14f4a89df111e658a6d466cbfc802eb705eb91bd5adfd" + sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.5.5" async: dependency: transitive description: @@ -69,10 +74,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" build_resolvers: dependency: "direct dev" description: @@ -85,18 +90,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.4.8" + version: "2.4.13" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 url: "https://pub.dev" source: hosted - version: "7.2.11" + version: "7.3.2" built_collection: dependency: transitive description: @@ -109,10 +114,10 @@ packages: dependency: transitive description: name: built_value - sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309 + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted - version: "8.8.1" + version: "8.9.2" cake_backup: dependency: "direct main" description: @@ -166,42 +171,42 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.6" cryptography: dependency: transitive description: name: cryptography - sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.7.0" cupertino_icons: dependency: transitive description: name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.8" dart_style: dependency: transitive description: name: dart_style - sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.7" encrypt: dependency: "direct main" description: @@ -222,26 +227,26 @@ packages: dependency: transitive description: name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.3" file: dependency: "direct main" description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -251,10 +256,10 @@ packages: dependency: "direct main" description: name: flutter_mobx - sha256: "4a5d062ff85ed3759f4aac6410ff0ffae32e324b2e71ca722ae1b37b32e865f4" + sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e" url: "https://pub.dev" source: hosted - version: "2.2.0+2" + version: "2.2.1+1" flutter_test: dependency: "direct dev" description: flutter @@ -264,10 +269,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" glob: dependency: transitive description: @@ -280,10 +285,10 @@ packages: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" hive: dependency: transitive description: @@ -304,10 +309,10 @@ packages: dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -328,10 +333,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -352,42 +357,50 @@ packages: dependency: transitive description: name: json_annotation - sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.8.1" + version: "4.9.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" logging: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -400,42 +413,42 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" mime: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" mobx: dependency: "direct main" description: name: mobx - sha256: "74ee54012dc7c1b3276eaa960a600a7418ef5f9997565deb8fca1fd88fb36b78" + sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e" url: "https://pub.dev" source: hosted - version: "2.3.0+1" + version: "2.3.3+2" mobx_codegen: dependency: "direct dev" description: name: mobx_codegen - sha256: b26c7f9c20b38f0ea572c1ed3f29d8e027cb265538bbd1aed3ec198642cfca42 + sha256: "8e0d8653a0c720ad933cd8358f6f89f740ce89203657c13f25bea772ef1fff7c" url: "https://pub.dev" source: hosted - version: "2.6.0+1" + version: "2.6.1" nested: dependency: transitive description: @@ -464,26 +477,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.12" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -504,18 +517,18 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" platform: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -528,10 +541,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" url: "https://pub.dev" source: hosted - version: "3.7.4" + version: "3.9.1" pool: dependency: transitive description: @@ -544,10 +557,10 @@ packages: dependency: transitive description: name: provider - sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c url: "https://pub.dev" source: hosted - version: "6.1.1" + version: "6.1.2" pub_semver: dependency: transitive description: @@ -560,10 +573,10 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.2.3" + version: "1.3.0" shelf: dependency: transitive description: @@ -576,10 +589,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -589,10 +602,10 @@ packages: dependency: "direct main" description: name: socks5_proxy - sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a" + sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.6" source_gen: dependency: transitive description: @@ -661,10 +674,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.2" timing: dependency: transitive description: @@ -685,10 +698,10 @@ packages: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" unorm_dart: dependency: "direct main" description: @@ -709,10 +722,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.5" watcher: dependency: "direct overridden" description: @@ -721,30 +734,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.0" - win32: - dependency: transitive - description: - name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" - url: "https://pub.dev" - source: hosted - version: "5.0.9" + version: "3.0.1" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" yaml: dependency: transitive description: @@ -754,5 +775,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml index 6e32c2ba1..19eda51e0 100644 --- a/cw_core/pubspec.yaml +++ b/cw_core/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: path_provider: ^2.0.11 mobx: ^2.0.7+4 flutter_mobx: ^2.0.6+1 - intl: ^0.18.0 + intl: ^0.19.0 encrypt: ^5.0.1 cake_backup: git: diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock index 1369675f5..cb5d3e2c3 100644 --- a/cw_haven/pubspec.lock +++ b/cw_haven/pubspec.lock @@ -21,18 +21,18 @@ packages: dependency: transitive description: name: args - sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.6.0" asn1lib: dependency: transitive description: name: asn1lib - sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039 + sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.5.5" async: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.1" build_config: dependency: transitive description: @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.2" build_resolvers: dependency: "direct dev" description: @@ -85,18 +85,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.13" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292" + sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41" url: "https://pub.dev" source: hosted - version: "7.2.7" + version: "7.2.10" built_collection: dependency: transitive description: @@ -109,10 +109,10 @@ packages: dependency: transitive description: name: built_value - sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725" + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted - version: "8.4.3" + version: "8.9.2" cake_backup: dependency: transitive description: @@ -134,10 +134,10 @@ packages: dependency: transitive description: name: checked_yaml - sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" clock: dependency: transitive description: @@ -150,10 +150,10 @@ packages: dependency: transitive description: name: code_builder - sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.10.0" collection: dependency: transitive description: @@ -166,34 +166,34 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.6" cryptography: dependency: transitive description: name: cryptography - sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.7.0" cupertino_icons: dependency: transitive description: name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.8" cw_core: dependency: "direct main" description: @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: encrypt - sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb" + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "5.0.3" fake_async: dependency: transitive description: @@ -229,26 +229,26 @@ packages: dependency: "direct main" description: name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.3" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -258,10 +258,10 @@ packages: dependency: "direct main" description: name: flutter_mobx - sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e" + sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e" url: "https://pub.dev" source: hosted - version: "2.0.6+5" + version: "2.2.1+1" flutter_test: dependency: "direct dev" description: flutter @@ -271,10 +271,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" glob: dependency: transitive description: @@ -287,10 +287,10 @@ packages: dependency: transitive description: name: graphs - sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.2" hive: dependency: transitive description: @@ -311,10 +311,10 @@ packages: dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -335,10 +335,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -359,42 +359,42 @@ packages: dependency: transitive description: name: json_annotation - sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.9.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" logging: dependency: transitive description: name: logging - sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.3.0" matcher: dependency: transitive description: @@ -407,42 +407,50 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" mime: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" mobx: dependency: "direct main" description: name: mobx - sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a + sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e" url: "https://pub.dev" source: hosted - version: "2.1.3+1" + version: "2.3.3+2" mobx_codegen: dependency: "direct dev" description: name: mobx_codegen - sha256: "86122e410d8ea24dda0c69adb5c2a6ccadd5ce02ad46e144764e0d0184a06181" + sha256: d4beb9cea4b7b014321235f8fdc7c2193ee0fe1d1198e9da7403f8bc85c4407c url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.3.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" package_config: dependency: transitive description: @@ -463,26 +471,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.12" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -495,42 +503,42 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.8" pointycastle: dependency: transitive description: name: pointycastle - sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" url: "https://pub.dev" source: hosted - version: "3.6.2" + version: "3.9.1" pool: dependency: transitive description: @@ -539,38 +547,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + provider: + dependency: transitive + description: + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + url: "https://pub.dev" + source: hosted + version: "6.1.2" pub_semver: dependency: transitive description: name: pub_semver - sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" shelf: dependency: transitive description: name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -580,10 +596,10 @@ packages: dependency: transitive description: name: socks5_proxy - sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a" + sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.6" source_gen: dependency: transitive description: @@ -652,10 +668,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.2" timing: dependency: transitive description: @@ -676,10 +692,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" unorm_dart: dependency: transitive description: @@ -700,10 +716,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.5" watcher: dependency: "direct overridden" description: @@ -712,38 +728,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.3.0" - win32: - dependency: transitive - description: - name: win32 - sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 - url: "https://pub.dev" - source: hosted - version: "3.1.3" + version: "3.0.1" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" yaml: dependency: transitive description: name: yaml - sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=3.7.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/cw_haven/pubspec.yaml b/cw_haven/pubspec.yaml index d868c986d..452fed93a 100644 --- a/cw_haven/pubspec.yaml +++ b/cw_haven/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: path_provider: ^2.0.11 mobx: ^2.0.7+4 flutter_mobx: ^2.0.6+1 - intl: ^0.18.0 + intl: ^0.19.0 cw_core: path: ../cw_core diff --git a/cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux b/cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux new file mode 120000 index 000000000..a2b4915e7 --- /dev/null +++ b/cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux @@ -0,0 +1 @@ +/Users/user/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/ \ No newline at end of file diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index 31d44ac63..551108adc 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" asn1lib: dependency: transitive description: @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" build_resolvers: dependency: "direct dev" description: @@ -93,10 +93,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.13" build_runner_core: dependency: transitive description: @@ -174,18 +174,18 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.6" cryptography: dependency: transitive description: @@ -253,18 +253,18 @@ packages: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -311,10 +311,10 @@ packages: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" hashlib: dependency: transitive description: @@ -375,10 +375,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -407,26 +407,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" ledger_flutter_plus: dependency: "direct main" description: @@ -447,10 +447,10 @@ packages: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" matcher: dependency: transitive description: @@ -463,26 +463,26 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" mime: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "2.0.0" mobx: dependency: "direct main" description: @@ -552,10 +552,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.12" path_provider_foundation: dependency: transitive description: @@ -600,10 +600,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -680,10 +680,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -765,10 +765,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.2" timing: dependency: transitive description: @@ -789,10 +789,10 @@ packages: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" universal_ble: dependency: transitive description: @@ -829,10 +829,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.5" watcher: dependency: "direct overridden" description: @@ -845,18 +845,26 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "3.0.1" xdg_directories: dependency: transitive description: @@ -882,5 +890,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml index 71cbfa243..d8e506f58 100644 --- a/cw_monero/pubspec.yaml +++ b/cw_monero/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: path_provider: ^2.0.11 mobx: ^2.0.7+4 flutter_mobx: ^2.0.6+1 - intl: ^0.18.0 + intl: ^0.19.0 encrypt: ^5.0.1 polyseed: ^0.0.6 cw_core: diff --git a/cw_mweb/android/build.gradle b/cw_mweb/android/build.gradle index 7e67b98ad..0d17a47ec 100644 --- a/cw_mweb/android/build.gradle +++ b/cw_mweb/android/build.gradle @@ -2,14 +2,14 @@ group 'com.cakewallet.mweb' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '2.0.21' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.7.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -33,15 +33,19 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 31 + compileSdkVersion 33 + + if (project.android.hasProperty("namespace")) { + namespace 'com.cakewallet.mweb' + } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } sourceSets { diff --git a/cw_mweb/android/settings.gradle b/cw_mweb/android/settings.gradle index 88fbd66fb..4a0c212c0 100644 --- a/cw_mweb/android/settings.gradle +++ b/cw_mweb/android/settings.gradle @@ -1 +1,3 @@ rootProject.name = 'cw_mweb' +id "com.android.application" version "8.3.2" apply false +id "org.jetbrains.kotlin.android" version "2.0.20" apply false diff --git a/cw_nano/pubspec.lock b/cw_nano/pubspec.lock index dd955e344..f4d5c00f8 100644 --- a/cw_nano/pubspec.lock +++ b/cw_nano/pubspec.lock @@ -21,18 +21,18 @@ packages: dependency: transitive description: name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.6.0" asn1lib: dependency: transitive description: name: asn1lib - sha256: "58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda" + sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70" url: "https://pub.dev" source: hosted - version: "1.5.3" + version: "1.5.5" async: dependency: transitive description: @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.1" build_config: dependency: transitive description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.0.2" build_resolvers: dependency: transitive description: @@ -109,10 +109,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.13" build_runner_core: dependency: "direct overridden" description: @@ -190,18 +190,18 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.6" cryptography: dependency: transitive description: @@ -245,18 +245,18 @@ packages: dependency: "direct main" description: name: ed25519_hd_key - sha256: c5c9f11a03f5789bf9dcd9ae88d641571c802640851f1cacdb13123f171b3a26 + sha256: "31e191ec97492873067e46dc9cc0c7d55170559c83a478400feffa0627acaccf" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" encrypt: dependency: transitive description: name: encrypt - sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb" + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "5.0.3" fake_async: dependency: transitive description: @@ -269,26 +269,26 @@ packages: dependency: transitive description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" fixnum_nanodart: dependency: transitive description: @@ -306,10 +306,10 @@ packages: dependency: transitive description: name: flutter_mobx - sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e" + sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e" url: "https://pub.dev" source: hosted - version: "2.0.6+5" + version: "2.2.1+1" flutter_test: dependency: "direct dev" description: flutter @@ -324,10 +324,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" glob: dependency: transitive description: @@ -340,10 +340,10 @@ packages: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" hex: dependency: "direct main" description: @@ -372,10 +372,10 @@ packages: dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -396,10 +396,10 @@ packages: dependency: transitive description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -420,34 +420,34 @@ packages: dependency: transitive description: name: json_annotation - sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.8.1" + version: "4.9.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" libcrypto: dependency: "direct main" description: @@ -460,10 +460,10 @@ packages: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" matcher: dependency: transitive description: @@ -476,26 +476,26 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" mime: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" mobx: dependency: "direct main" description: @@ -529,6 +529,14 @@ packages: url: "https://github.com/perishllc/nanoutil.git" source: git version: "1.0.3" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" package_config: dependency: transitive description: @@ -549,26 +557,26 @@ packages: dependency: transitive description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.12" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -581,34 +589,34 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" pinenacl: dependency: transitive description: name: pinenacl - sha256: "3a5503637587d635647c93ea9a8fecf48a420cc7deebe6f1fc85c2a5637ab327" + sha256: "57e907beaacbc3c024a098910b6240758e899674de07d6949a67b52fd984cbdf" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.0" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -621,10 +629,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.9.1" pool: dependency: transitive description: @@ -633,6 +641,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + provider: + dependency: transitive + description: + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + url: "https://pub.dev" + source: hosted + version: "6.1.2" pub_semver: dependency: transitive description: @@ -645,50 +661,50 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.2.3" + version: "1.3.0" rational: dependency: transitive description: name: rational - sha256: ba58e9e18df9abde280e8b10051e4bce85091e41e8e7e411b6cde2e738d357cf + sha256: cb808fb6f1a839e6fc5f7d8cb3b0a10e1db48b3be102de73938c627f0b636336 url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.3" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" + sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.3" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "671e7a931f55a08aa45be2a13fe7247f2a41237897df434b30d2012388191833" + sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d" url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.5.3" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shared_preferences_platform_interface: dependency: transitive description: @@ -701,18 +717,18 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shelf: dependency: transitive description: @@ -725,10 +741,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -738,10 +754,10 @@ packages: dependency: transitive description: name: socks5_proxy - sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a" + sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.6" source_gen: dependency: transitive description: @@ -810,10 +826,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.2" timing: dependency: transitive description: @@ -834,10 +850,10 @@ packages: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" unorm_dart: dependency: transitive description: @@ -858,10 +874,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.5" watcher: dependency: "direct overridden" description: @@ -870,30 +886,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.0" - win32: - dependency: transitive - description: - name: win32 - sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb" - url: "https://pub.dev" - source: hosted - version: "5.5.0" + version: "3.0.1" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" yaml: dependency: transitive description: @@ -903,5 +927,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.16.6" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock index a861c6bac..7e2c3c76f 100644 --- a/cw_wownero/pubspec.lock +++ b/cw_wownero/pubspec.lock @@ -21,18 +21,18 @@ packages: dependency: transitive description: name: args - sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.6.0" asn1lib: dependency: transitive description: name: asn1lib - sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039 + sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.5.5" async: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.1" build_config: dependency: transitive description: @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: build_daemon - sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.2" build_resolvers: dependency: "direct dev" description: @@ -85,18 +85,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.13" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292" + sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41" url: "https://pub.dev" source: hosted - version: "7.2.7" + version: "7.2.10" built_collection: dependency: transitive description: @@ -109,10 +109,10 @@ packages: dependency: transitive description: name: built_value - sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725" + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted - version: "8.4.3" + version: "8.9.2" cake_backup: dependency: transitive description: @@ -134,10 +134,10 @@ packages: dependency: transitive description: name: checked_yaml - sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" clock: dependency: transitive description: @@ -150,10 +150,10 @@ packages: dependency: transitive description: name: code_builder - sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.10.0" collection: dependency: transitive description: @@ -166,26 +166,26 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.6" cryptography: dependency: transitive description: name: cryptography - sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.7.0" cupertino_icons: dependency: transitive description: @@ -213,10 +213,10 @@ packages: dependency: "direct main" description: name: encrypt - sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb" + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "5.0.3" fake_async: dependency: transitive description: @@ -229,26 +229,26 @@ packages: dependency: "direct main" description: name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.3" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -258,10 +258,10 @@ packages: dependency: "direct main" description: name: flutter_mobx - sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e" + sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e" url: "https://pub.dev" source: hosted - version: "2.0.6+5" + version: "2.2.1+1" flutter_test: dependency: "direct dev" description: flutter @@ -271,10 +271,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" glob: dependency: transitive description: @@ -287,26 +287,26 @@ packages: dependency: transitive description: name: graphs - sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.2" hashlib: dependency: transitive description: name: hashlib - sha256: d41795742c10947930630118c6836608deeb9047cd05aee32d2baeb697afd66a + sha256: f572f2abce09fc7aee53f15927052b9732ea1053e540af8cae211111ee0b99b1 url: "https://pub.dev" source: hosted - version: "1.19.2" + version: "1.21.0" hashlib_codecs: dependency: transitive description: name: hashlib_codecs - sha256: "2b570061f5a4b378425be28a576c1e11783450355ad4345a19f606ff3d96db0f" + sha256: "8cea9ccafcfeaa7324d2ae52c61c69f7ff71f4237507a018caab31b9e416e3b1" url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" hive: dependency: transitive description: @@ -327,10 +327,10 @@ packages: dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -351,10 +351,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" io: dependency: transitive description: @@ -375,42 +375,42 @@ packages: dependency: transitive description: name: json_annotation - sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.9.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" logging: dependency: transitive description: name: logging - sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.3.0" matcher: dependency: transitive description: @@ -423,42 +423,42 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" mime: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" mobx: dependency: "direct main" description: name: mobx - sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a + sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e" url: "https://pub.dev" source: hosted - version: "2.1.3+1" + version: "2.3.3+2" mobx_codegen: dependency: "direct dev" description: name: mobx_codegen - sha256: "86122e410d8ea24dda0c69adb5c2a6ccadd5ce02ad46e144764e0d0184a06181" + sha256: d4beb9cea4b7b014321235f8fdc7c2193ee0fe1d1198e9da7403f8bc85c4407c url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.3.0" monero: dependency: "direct main" description: @@ -476,6 +476,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" package_config: dependency: transitive description: @@ -496,26 +504,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.12" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -528,26 +536,26 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -560,10 +568,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.9.1" polyseed: dependency: "direct main" description: @@ -580,38 +588,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + provider: + dependency: transitive + description: + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + url: "https://pub.dev" + source: hosted + version: "6.1.2" pub_semver: dependency: transitive description: name: pub_semver - sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" shelf: dependency: transitive description: name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -621,10 +637,10 @@ packages: dependency: transitive description: name: socks5_proxy - sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a" + sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.6" source_gen: dependency: transitive description: @@ -693,10 +709,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.2" timing: dependency: transitive description: @@ -717,10 +733,10 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" unorm_dart: dependency: transitive description: @@ -741,10 +757,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.5" watcher: dependency: "direct overridden" description: @@ -753,38 +769,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.3.0" - win32: - dependency: transitive - description: - name: win32 - sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 - url: "https://pub.dev" - source: hosted - version: "3.1.3" + version: "3.0.1" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" yaml: dependency: transitive description: name: yaml - sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" sdks: - dart: ">=3.2.0-0 <4.0.0" - flutter: ">=3.7.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml index 28ece82ef..48e65453a 100644 --- a/cw_wownero/pubspec.yaml +++ b/cw_wownero/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: path_provider: ^2.0.11 mobx: ^2.0.7+4 flutter_mobx: ^2.0.6+1 - intl: ^0.18.0 + intl: ^0.19.0 encrypt: ^5.0.1 polyseed: ^0.0.6 cw_core: diff --git a/how_to_add_new_wallet_type.md b/how_to_add_new_wallet_type.md index d71e181e0..74350e5d8 100644 --- a/how_to_add_new_wallet_type.md +++ b/how_to_add_new_wallet_type.md @@ -23,7 +23,7 @@ - Add the code to run the code generation needed for the files in the `cw_walletx` package to the `model_generator.sh` script - cd cw_walletx && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_walletx && flutter pub get && dart run build_runner build --delete-conflicting-outputs && cd .. - Add the relevant dev_dependencies for generating the files also - build_runner @@ -78,9 +78,9 @@ A `Proxy` class is used to communicate with the specific wallet package we have. ./app_config.sh - cd cw_walletx && flutter pub get && flutter packages pub run build_runner build + cd cw_walletx && flutter pub get && dart run build_runner build - flutter packages pub run build_runner build --delete-conflicting-outputs + dart run build_runner build --delete-conflicting-outputs Moving forward, our interactions with the cw_walletx package would be through the proxy class and its methods. @@ -191,9 +191,9 @@ You can add as many node entries as desired. - Run the following commands after to generate modified files in cw_core and lib - cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_core && flutter pub get && dart run build_runner build --delete-conflicting-outputs && cd .. - flutter packages pub run build_runner build --delete-conflicting-outputs + dart run build_runner build --delete-conflicting-outputs - Lastly, before we run the app to test what we’ve done so far, - Go to `lib/src/dashboard/widgets/menu_widget.dart` and add an icon for walletX to be used within the app. diff --git a/howto-build-android.md b/howto-build-android.md index 57d29f459..5afecfba3 100644 --- a/howto-build-android.md +++ b/howto-build-android.md @@ -8,7 +8,7 @@ The following are the system requirements to build Cake Wallet for your Android Ubuntu >= 20.04 Android SDK 29 or higher (better to have the latest one 33) Android NDK 17c -Flutter 3.19.x +Flutter 3.24.4 ``` ### 1. Installing Package Dependencies @@ -51,7 +51,7 @@ You may download and install the latest version of Android Studio [here](https:/ ### 3. Installing Flutter -Install Flutter with version `3.19.x`. For this please check section [Install Flutter manually](https://docs.flutter.dev/get-started/install/linux#install-flutter-manually). +Install Flutter with version `3.24.4`. For this please check section [Install Flutter manually](https://docs.flutter.dev/get-started/install/linux#install-flutter-manually). ### 4. Installing rustup @@ -66,7 +66,7 @@ Verify that the Android toolchain, Flutter, and Android Studio have been correct The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. ``` Doctor summary (to see all details, run flutter doctor -v): -[✓] Flutter (Channel stable, 3.19.x, on Linux, locale en_US.UTF-8) +[✓] Flutter (Channel stable, 3.24.4, on Linux, locale en_US.UTF-8) [✓] Android toolchain - develop for Android devices (Android SDK version 29 or higher) [✓] Android Studio (version 4.0 or higher) ``` @@ -126,17 +126,17 @@ Install Flutter package dependencies with this command: Your Cake Wallet binary will be built with cryptographic salts, which are used for secure encryption of your data. You may generate these secret salts with the following command: -`$ flutter packages pub run tool/generate_new_secrets.dart` +`$ dart run tool/generate_new_secrets.dart` Next, we must generate key properties based on the secure keystore you generated for Android (in step 5). **MODIFY THE FOLLOWING COMMAND** with the "store password" and "key password" you assigned when creating your keystore (in step 5). -`$ flutter packages pub run tool/generate_android_key_properties.dart keyAlias=key storeFile=$HOME/key.jks storePassword= keyPassword=` +`$ dart run tool/generate_android_key_properties.dart keyAlias=key storeFile=$HOME/key.jks storePassword= keyPassword=` **REMINDER:** The *above* command will **not** succeed unless you replaced the `storePassword` and `keyPassword` variables with the correct passwords for your keystore. Then we need to generate localization files. -`$ flutter packages pub run tool/generate_localization.dart` +`$ dart run tool/generate_localization.dart` Finally build mobx models for the app: diff --git a/howto-build-ios.md b/howto-build-ios.md index 544d4359e..753e17e93 100644 --- a/howto-build-ios.md +++ b/howto-build-ios.md @@ -7,7 +7,7 @@ The following are the system requirements to build Cake Wallet for your iOS devi ``` macOS >= 14.0 Xcode 15.3 -Flutter 3.19.x +Flutter 3.24.4 ``` ### 1. Installing Package Dependencies @@ -26,7 +26,7 @@ You may download and install the latest version of [Xcode](https://developer.app ### 3. Installing Flutter -Need to install flutter with version `3.19.x`. For this please check section [Install Flutter](https://docs.flutter.dev/get-started/install/macos/mobile-ios?tab=download). +Need to install flutter with version `3.24.4`. For this please check section [Install Flutter](https://docs.flutter.dev/get-started/install/macos/mobile-ios?tab=download). ### 4. Installing rustup @@ -41,7 +41,7 @@ Verify that the Flutter and Xcode have been correctly installed on your system w The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. ``` Doctor summary (to see all details, run flutter doctor -v): -[✓] Flutter (Channel stable, 3.19.x, on macOS 14.x.x) +[✓] Flutter (Channel stable, 3.24.4, on macOS 14.x.x) [✓] Xcode - develop for iOS and macOS (Xcode 15.3) ``` @@ -82,7 +82,7 @@ Install Flutter package dependencies with this command: Your Cake Wallet binary will be built with cryptographic salts, which are used for secure encryption of your data. You may generate these secret salts with the following command: -`$ flutter packages pub run tool/generate_new_secrets.dart` +`$ dart run tool/generate_new_secrets.dart` Then we need to generate localization files and mobx models. diff --git a/howto-build-macos.md b/howto-build-macos.md index 2e535e5be..a497e1ffa 100644 --- a/howto-build-macos.md +++ b/howto-build-macos.md @@ -7,7 +7,7 @@ The following are the system requirements to build Cake Wallet for your macOS de ``` macOS >= 14.0 Xcode 15.3 -Flutter 3.19.x +Flutter 3.24.4 ``` ### 1. Installing Package Dependencies @@ -28,7 +28,7 @@ You may download and install the latest version of [Xcode](https://developer.app ### 3. Installing Flutter -Need to install flutter with version `3.19.x`. For this please check section [Install Flutter](https://docs.flutter.dev/get-started/install/macos/desktop?tab=download). +Need to install flutter with version `3.24.4`. For this please check section [Install Flutter](https://docs.flutter.dev/get-started/install/macos/desktop?tab=download). ### 4. Installing rustup @@ -43,7 +43,7 @@ Verify that Flutter and Xcode have been correctly installed on your system with The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. ``` Doctor summary (to see all details, run flutter doctor -v): -[✓] Flutter (Channel stable, 3.19.x, on macOS 14.x.x) +[✓] Flutter (Channel stable, 3.24.4, on macOS 14.x.x) [✓] Xcode - develop for iOS and macOS (Xcode 15.3) ``` @@ -93,7 +93,7 @@ Install Flutter package dependencies with this command: Your Cake Wallet binary will be built with cryptographic salts, which are used for secure encryption of your data. You may generate these secret salts with the following command: -`$ flutter packages pub run tool/generate_new_secrets.dart` +`$ dart run tool/generate_new_secrets.dart` Then we need to generate localization files and mobx models. diff --git a/howto-build-windows.md b/howto-build-windows.md index 504f8f785..3ebecaa61 100644 --- a/howto-build-windows.md +++ b/howto-build-windows.md @@ -6,12 +6,12 @@ The following are the system requirements to build CakeWallet for your Windows P ``` Windows 10 or later (64-bit), x86-64 based -Flutter 3.19.x +Flutter 3.24.4 ``` ### 1. Installing Flutter -Install Flutter with version `3.19.x`. Follow the Flutter [installation guide](https://docs.flutter.dev/get-started/install/windows). +Install Flutter with version `3.24.4`. Follow the Flutter [installation guide](https://docs.flutter.dev/get-started/install/windows). ### 2. Install Development Tools diff --git a/ios/Podfile.lock b/ios/Podfile.lock index abcac01fb..bb55b01c6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,39 +2,7 @@ PODS: - connectivity_plus (0.0.1): - Flutter - ReachabilitySwift - - CryptoSwift (1.8.2) - - cw_haven (0.0.1): - - cw_haven/Boost (= 0.0.1) - - cw_haven/Haven (= 0.0.1) - - cw_haven/OpenSSL (= 0.0.1) - - cw_haven/Sodium (= 0.0.1) - - cw_shared_external - - Flutter - - cw_haven/Boost (0.0.1): - - cw_shared_external - - Flutter - - cw_haven/Haven (0.0.1): - - cw_shared_external - - Flutter - - cw_haven/OpenSSL (0.0.1): - - cw_shared_external - - Flutter - - cw_haven/Sodium (0.0.1): - - cw_shared_external - - Flutter - - cw_mweb (0.0.1): - - Flutter - - cw_shared_external (0.0.1): - - cw_shared_external/Boost (= 0.0.1) - - cw_shared_external/OpenSSL (= 0.0.1) - - cw_shared_external/Sodium (= 0.0.1) - - Flutter - - cw_shared_external/Boost (0.0.1): - - Flutter - - cw_shared_external/OpenSSL (0.0.1): - - Flutter - - cw_shared_external/Sodium (0.0.1): - - Flutter + - CryptoSwift (1.8.3) - device_display_brightness (0.0.1): - Flutter - device_info_plus (0.0.1): @@ -81,10 +49,10 @@ PODS: - flutter_inappwebview_ios (0.0.1): - Flutter - flutter_inappwebview_ios/Core (= 0.0.1) - - OrderedSet (~> 5.0) + - OrderedSet (~> 6.0.3) - flutter_inappwebview_ios/Core (0.0.1): - Flutter - - OrderedSet (~> 5.0) + - OrderedSet (~> 6.0.3) - flutter_local_authentication (1.2.0): - Flutter - flutter_mailer (0.0.1): @@ -98,7 +66,8 @@ PODS: - Flutter - integration_test (0.0.1): - Flutter - - OrderedSet (5.0.0) + - MTBBarcodeScanner (5.0.11) + - OrderedSet (6.0.3) - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): @@ -106,7 +75,7 @@ PODS: - FlutterMacOS - permission_handler_apple (9.1.1): - Flutter - - ReachabilitySwift (5.2.3) + - ReachabilitySwift (5.2.4) - SDWebImage (5.19.7): - SDWebImage/Core (= 5.19.7) - SDWebImage/Core (5.19.7) @@ -117,6 +86,7 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS + - SwiftProtobuf (1.28.2) - sp_scanner (0.0.1): - Flutter - SwiftyGif (5.4.5) @@ -136,9 +106,6 @@ PODS: DEPENDENCIES: - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - CryptoSwift - - cw_haven (from `.symlinks/plugins/cw_haven/ios`) - - cw_mweb (from `.symlinks/plugins/cw_mweb/ios`) - - cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`) - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`) @@ -158,7 +125,6 @@ DEPENDENCIES: - sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - - sp_scanner (from `.symlinks/plugins/sp_scanner/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`) - universal_ble (from `.symlinks/plugins/universal_ble/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) @@ -179,12 +145,6 @@ SPEC REPOS: EXTERNAL SOURCES: connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" - cw_haven: - :path: ".symlinks/plugins/cw_haven/ios" - cw_mweb: - :path: ".symlinks/plugins/cw_mweb/ios" - cw_shared_external: - :path: ".symlinks/plugins/cw_shared_external/ios" device_display_brightness: :path: ".symlinks/plugins/device_display_brightness/ios" device_info_plus: @@ -223,8 +183,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" - sp_scanner: - :path: ".symlinks/plugins/sp_scanner/ios" uni_links: :path: ".symlinks/plugins/uni_links/ios" universal_ble: @@ -238,10 +196,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d - CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea - cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a - cw_mweb: 87af74f9659fed0c1a2cbfb44413f1070e79e3ae - cw_shared_external: 2972d872b8917603478117c9957dfca611845a92 + CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483 device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7 device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 devicelocale: b22617f40038496deffba44747101255cee005b0 @@ -250,22 +205,24 @@ SPEC CHECKSUMS: fast_scanner: 44c00940355a51258cd6c2085734193cd23d95bc file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0 + flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83 flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be fluttertoast: 48c57db1b71b0ce9e6bba9f31c940ff4b001293c in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d - integration_test: 13825b8a9334a850581300559b8839134b124670 - OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c - package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c + integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 + MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb + OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 + package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 - ReachabilitySwift: 7f151ff156cea1481a8411701195ac6a984f4979 + ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3 sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986 - share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad + share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 + SwiftProtobuf: 4dbaffec76a39a8dc5da23b40af1a5dc01a4c02d sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 477d47f7b..0a4db4ddd 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,7 +2,7 @@ import UIKit import Flutter import workmanager -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/lib/locales/hausa_intl.dart b/lib/locales/hausa_intl.dart index 6cf757b60..99e47d7da 100644 --- a/lib/locales/hausa_intl.dart +++ b/lib/locales/hausa_intl.dart @@ -795,6 +795,14 @@ class HaMaterialLocalizations extends GlobalMaterialLocalizations { @override // TODO: implement shareButtonLabel String get shareButtonLabel => "shareButtonLabel"; + + @override + // TODO: implement clearButtonTooltip + String get clearButtonTooltip => "clearButtonTooltip"; + + @override + // TODO: implement selectedDateLabel + String get selectedDateLabel => "selectedDateLabel"; } /// Cupertino Support diff --git a/lib/locales/yoruba_intl.dart b/lib/locales/yoruba_intl.dart index 3c720b80e..bb2385274 100644 --- a/lib/locales/yoruba_intl.dart +++ b/lib/locales/yoruba_intl.dart @@ -794,6 +794,14 @@ class YoMaterialLocalizations extends GlobalMaterialLocalizations { @override // TODO: implement shareButtonLabel String get shareButtonLabel => "shareButtonLabel"; + + @override + // TODO: implement clearButtonTooltip + String get clearButtonTooltip => "clearButtonTooltip"; + + @override + // TODO: implement selectedDateLabel + String get selectedDateLabel => "selectedDateLabel"; } /// Cupertino Support diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index f52be7481..4b9eb3b2d 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 42b9fa84c..52b44e53e 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,6 @@ import FlutterMacOS import Foundation import connectivity_plus -import cw_mweb import device_info_plus import devicelocale import fast_scanner @@ -24,7 +23,6 @@ import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) - CwMwebPlugin.register(with: registry.registrar(forPlugin: "CwMwebPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) diff --git a/model_generator.sh b/model_generator.sh index 293923d1e..730817c24 100755 --- a/model_generator.sh +++ b/model_generator.sh @@ -1,15 +1,18 @@ #!/bin/bash -cd cw_core; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_evm; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_monero; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_bitcoin; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_haven; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_nano; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_bitcoin_cash; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_solana; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_tron; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. -cd cw_wownero; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd .. +set -x -e + +cd cw_core; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_evm; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_monero; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_bitcoin; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_haven; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_nano; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_bitcoin_cash; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_solana; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_tron; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. +cd cw_wownero; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .. cd cw_polygon; flutter pub get; cd .. cd cw_ethereum; flutter pub get; cd .. cd cw_mweb && flutter pub get && cd .. -flutter packages pub run build_runner build --delete-conflicting-outputs +dart run build_runner build --delete-conflicting-outputs + diff --git a/pubspec_base.yaml b/pubspec_base.yaml index fa70b5837..39fe953d0 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -3,21 +3,21 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - intl: ^0.18.0 - url_launcher: ^6.1.4 + intl: ^0.19.0 + url_launcher: 6.3.1 qr_flutter: git: url: https://github.com/cake-tech/qr.flutter.git ref: cake-4.0.2 version: 4.0.2 - shared_preferences: ^2.0.15 + shared_preferences: 2.3.2 # provider: ^6.0.3 rxdart: ^0.28.0 yaml: ^3.1.1 fast_scanner: git: url: https://github.com/MrCyjaneK/fast_scanner - ref: c8311b46cc67dd02250970a54d2a4526168187f3 + ref: c5a08720216a508bf1fe3d062ad19d2836545a42 http: ^1.1.0 path_provider: ^2.0.11 mobx: ^2.1.4 @@ -29,20 +29,22 @@ dependencies: dio: ^4.0.6 hive: ^2.2.3 hive_flutter: ^1.1.0 - local_auth_android: 1.0.21 + local_auth_android: ^1.0.46 flutter_local_authentication: git: url: https://github.com/cake-tech/flutter_local_authentication package_info_plus: ^8.0.1 - devicelocale: - git: - url: https://github.com/cake-tech/flutter-devicelocale + devicelocale: 0.8.1 auto_size_text: ^3.0.0 dotted_border: ^2.0.0+2 smooth_page_indicator: ^1.0.0+2 - flutter_inappwebview: ^6.0.0 + flutter_inappwebview: ^6.1.5 flutter_spinkit: ^5.1.0 - uni_links: ^0.5.1 + uni_links: + git: + url: https://github.com/MrCyjaneK/uni_links + ref: 8e9efa4d9beb19e4ac44009576337f1ce51c22e2 + path: uni_links lottie: ^1.3.0 animate_do: ^2.1.0 cupertino_icons: ^1.0.5 @@ -63,12 +65,15 @@ dependencies: ref: master permission_handler: ^10.0.0 device_display_brightness: - git: - url: https://github.com/cake-tech/device_display_brightness.git - ref: master - workmanager: ^0.5.1 + git: + url: https://github.com/MrCyjaneK/device_display_brightness.git + ref: 4cac18c446ce686f3d75b1565badbd7da439bbd9 + workmanager: ^0.5.2 wakelock_plus: ^1.2.5 - flutter_mailer: ^2.0.2 + flutter_mailer: + git: + url: https://github.com/taljacobson/flutter_mailer + ref: 2a7d04d61f56e1ca166ab42e91e0daf1bfddfaf2 device_info_plus: ^9.1.0 base32: 2.1.3 in_app_review: ^2.0.6 @@ -77,19 +82,22 @@ dependencies: url: https://github.com/cake-tech/cake_backup.git ref: main version: 1.0.0 - flutter_plugin_android_lifecycle: 2.0.9 + flutter_plugin_android_lifecycle: 2.0.23 path_provider_android: ^2.2.1 - shared_preferences_android: 2.0.17 - url_launcher_android: 6.0.24 + shared_preferences_android: 2.3.3 + url_launcher_android: 6.3.14 url_launcher_linux: 3.1.1 # https://github.com/flutter/flutter/issues/153083 - sensitive_clipboard: ^1.0.0 + sensitive_clipboard: + git: + url: https://github.com/MrCyjaneK/sensitive_clipboard + ref: 288c7ee2d63b459bc735f7dc89321b29a1f12fae walletconnect_flutter_v2: ^2.1.4 eth_sig_util: ^0.0.9 ens_dart: git: url: https://github.com/cake-tech/ens_dart.git ref: main - fluttertoast: 8.1.4 + fluttertoast: 8.2.8 # tor: # git: # url: https://github.com/cake-tech/tor.git diff --git a/pubspec_description.yaml b/pubspec_description.yaml index b51fe96d6..928bc4f1f 100644 --- a/pubspec_description.yaml +++ b/pubspec_description.yaml @@ -4,4 +4,4 @@ version: 0.0.0 publish_to: none environment: - sdk: ">=3.1.0 <4.0.0" \ No newline at end of file + sdk: ^3.5.0 \ No newline at end of file diff --git a/run-android.sh b/run-android.sh index 880d86b6f..cb0c34038 100755 --- a/run-android.sh +++ b/run-android.sh @@ -1,5 +1,5 @@ #!/bin/bash - +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/universal_sed.sh" # Get the current git branch get_current_branch() { if git rev-parse --git-dir > /dev/null 2>&1; then @@ -15,9 +15,8 @@ get_current_branch() { update_app_properties() { local branch=$1 local file_path="./android/app.properties" - - sed -i "s/^id=.*/id=com.cakewallet.$branch/" "$file_path" - sed -i "s/^name=.*/name=$branch-Cake Wallet/" "$file_path" + universal_sed "s/^id=.*/id=com.cakewallet.$branch/" "$file_path" + universal_sed "s/^name=.*/name=$branch-Cake Wallet/" "$file_path" } # only update app.properties if getting the current branch was successful diff --git a/scripts/android/inject_app_details.sh b/scripts/android/inject_app_details.sh index 2957b91e3..737ebbb88 100755 --- a/scripts/android/inject_app_details.sh +++ b/scripts/android/inject_app_details.sh @@ -1,5 +1,5 @@ #!/bin/bash - +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/universal_sed.sh" if [ -z "$APP_ANDROID_TYPE" ]; then echo "Please set APP_ANDROID_TYPE" exit 1 @@ -7,9 +7,9 @@ fi cd ../.. set -x -sed -i "0,/version:/{s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/}" ./pubspec.yaml -sed -i "0,/version:/{s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/}" ./android/app/src/main/AndroidManifest.xml -sed -i "0,/__APP_SCHEME__/s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/" ./android/app/src/main/AndroidManifest.xml -sed -i "0,/version:/{s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/}" ./android/app/src/main/AndroidManifest.xml -sed -i "0,/version:/{s/__versionName__/${APP_ANDROID_VERSION}/}" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/version:/{s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/}" ./pubspec.yaml +universal_sed "0,/version:/{s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/}" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/__APP_SCHEME__/s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/version:/{s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/}" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/version:/{s/__versionName__/${APP_ANDROID_VERSION}/}" ./android/app/src/main/AndroidManifest.xml cd scripts/android diff --git a/scripts/android/pubspec_gen.sh b/scripts/android/pubspec_gen.sh index 468f548f3..febc4f9e9 100755 --- a/scripts/android/pubspec_gen.sh +++ b/scripts/android/pubspec_gen.sh @@ -23,7 +23,7 @@ esac cd ../.. cp -rf pubspec_description.yaml pubspec.yaml flutter pub get -flutter pub run tool/generate_pubspec.dart +dart run tool/generate_pubspec.dart flutter pub get -flutter packages pub run tool/configure.dart $CONFIG_ARGS +dart run tool/configure.dart $CONFIG_ARGS cd scripts/android \ No newline at end of file diff --git a/scripts/ios/app_config.sh b/scripts/ios/app_config.sh index 2232491a6..8b217dc54 100755 --- a/scripts/ios/app_config.sh +++ b/scripts/ios/app_config.sh @@ -1,5 +1,6 @@ #!/bin/bash - +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/universal_sed.sh" +set -x -e MONERO_COM="monero.com" CAKEWALLET="cakewallet" HAVEN="haven" @@ -22,7 +23,7 @@ cp -rf ./ios/Runner/InfoBase.plist ./ios/Runner/Info.plist /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:1:CFBundleURLName string ${APP_IOS_TYPE}" ./ios/Runner/Info.plist /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:1:CFBundleURLSchemes array" ./ios/Runner/Info.plist /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:1:CFBundleURLSchemes: string ${APP_IOS_TYPE}" ./ios/Runner/Info.plist -sed -i '' "s/PRODUCT_BUNDLE_IDENTIFIER = .*;/PRODUCT_BUNDLE_IDENTIFIER = $APP_IOS_BUNDLE_ID;/g" ./ios/Runner.xcodeproj/project.pbxproj +universal_sed "s/PRODUCT_BUNDLE_IDENTIFIER = .*;/PRODUCT_BUNDLE_IDENTIFIER = $APP_IOS_BUNDLE_ID;/g" ./ios/Runner.xcodeproj/project.pbxproj CONFIG_ARGS="" @@ -42,11 +43,12 @@ case $APP_IOS_TYPE in CONFIG_ARGS="--haven" ;; esac +CONFIG_ARGS="--monero --ethereum --polygon --nano --solana --tron --wownero" cp -rf pubspec_description.yaml pubspec.yaml flutter pub get -flutter pub run tool/generate_pubspec.dart +dart run tool/generate_pubspec.dart flutter pub get -flutter packages pub run tool/configure.dart $CONFIG_ARGS +dart run tool/configure.dart $CONFIG_ARGS cd $DIR $DIR/app_icon.sh diff --git a/scripts/linux/app_config.sh b/scripts/linux/app_config.sh index b4ca1423c..0fc41bd0f 100755 --- a/scripts/linux/app_config.sh +++ b/scripts/linux/app_config.sh @@ -1,5 +1,5 @@ #!/bin/bash - +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/universal_sed.sh" CAKEWALLET="cakewallet" DIR=`pwd` @@ -18,8 +18,8 @@ esac cp -rf pubspec_description.yaml pubspec.yaml flutter pub get -flutter pub run tool/generate_pubspec.dart +dart run tool/generate_pubspec.dart flutter pub get -flutter packages pub run tool/configure.dart $CONFIG_ARGS -sed -i '0,/version: 0.0.0/s//version: '"${APP_LINUX_VERSION}"'+'"${APP_LINUX_BUILD_NUMBER}"'/' pubspec.yaml +dart run tool/configure.dart $CONFIG_ARGS +universal_sed '0,/version: 0.0.0/s//version: '"${APP_LINUX_VERSION}"'+'"${APP_LINUX_BUILD_NUMBER}"'/' pubspec.yaml cd $DIR diff --git a/scripts/macos/app_config.sh b/scripts/macos/app_config.sh index 92a8636bd..452205dd9 100755 --- a/scripts/macos/app_config.sh +++ b/scripts/macos/app_config.sh @@ -1,4 +1,5 @@ #!/bin/bash +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/universal_sed.sh" MONERO_COM="monero.com" CAKEWALLET="cakewallet" @@ -24,11 +25,11 @@ cp -rf ./macos/Runner/DebugProfileBase.entitlements ./macos/Runner/DebugProfile. cp -rf ./macos/Runner/ReleaseBase.entitlements ./macos/Runner/Release.entitlements cp -rf ./macos/Runner/RunnerBase.entitlements ./macos/Runner/Runner.entitlements cp -rf ./macos/Runner/Configs/AppInfoBase.xcconfig ./macos/Runner/Configs/AppInfo.xcconfig -sed -i '' "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/DebugProfile.entitlements -sed -i '' "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/Release.entitlements -sed -i '' "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/Runner.entitlements -sed -i '' "s/\${PRODUCT_NAME}/${APP_MACOS_NAME}/g" ./macos/Runner/Configs/AppInfo.xcconfig -sed -i '' "s/PRODUCT_BUNDLE_IDENTIFIER = .*;/PRODUCT_BUNDLE_IDENTIFIER = $APP_MACOS_BUNDLE_ID;/g" ./macos/Runner/Configs/AppInfo.xcconfig +universal_sed "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/DebugProfile.entitlements +universal_sed "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/Release.entitlements +universal_sed "s/\${BUNDLE_ID}/${APP_MACOS_BUNDLE_ID}/g" ./macos/Runner/Runner.entitlements +universal_sed "s/\${PRODUCT_NAME}/${APP_MACOS_NAME}/g" ./macos/Runner/Configs/AppInfo.xcconfig +universal_sed "s/PRODUCT_BUNDLE_IDENTIFIER = .*;/PRODUCT_BUNDLE_IDENTIFIER = $APP_MACOS_BUNDLE_ID;/g" ./macos/Runner/Configs/AppInfo.xcconfig CONFIG_ARGS="" case $APP_MACOS_TYPE in @@ -40,8 +41,8 @@ esac cp -rf pubspec_description.yaml pubspec.yaml flutter pub get -flutter pub run tool/generate_pubspec.dart +dart run tool/generate_pubspec.dart flutter pub get -flutter packages pub run tool/configure.dart $CONFIG_ARGS +dart run tool/configure.dart $CONFIG_ARGS cd $DIR $DIR/app_icon.sh diff --git a/scripts/macos/gen_common.sh b/scripts/macos/gen_common.sh index d75ac919e..d1d40edc9 100755 --- a/scripts/macos/gen_common.sh +++ b/scripts/macos/gen_common.sh @@ -1,5 +1,5 @@ #!/bin/sh - +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/universal_sed.sh" gen_podspec() { ARCH=$1 CW_PLUGIN_DIR="`pwd`/../../cw_monero/macos" @@ -9,7 +9,7 @@ gen_podspec() { DEFAULT_FILE_PATH="${CW_PLUGIN_DIR}/${DEFAULT_FILENAME}" rm -f $DEFAULT_FILE_PATH cp $BASE_FILE_PATH $DEFAULT_FILE_PATH - gsed -i "s/#___VALID_ARCHS___#/${ARCH}/g" $DEFAULT_FILE_PATH + universal_sed "s/#___VALID_ARCHS___#/${ARCH}/g" $DEFAULT_FILE_PATH } gen_project() { @@ -17,7 +17,7 @@ gen_project() { CW_DIR="`pwd`/../../macos/Runner.xcodeproj" DEFAULT_FILENAME="project.pbxproj" DEFAULT_FILE_PATH="${CW_DIR}/${DEFAULT_FILENAME}" - gsed -i "s/ARCHS =.*/ARCHS = \"${ARCH}\";/g" $DEFAULT_FILE_PATH + universal_sed "s/ARCHS =.*/ARCHS = \"${ARCH}\";/g" $DEFAULT_FILE_PATH } gen() { diff --git a/scripts/universal_sed.sh b/scripts/universal_sed.sh new file mode 100644 index 000000000..8c0e3d9a4 --- /dev/null +++ b/scripts/universal_sed.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +detect_sed() { + if sed --version 2>/dev/null | grep -q "GNU"; then + SED_TYPE="GNU" + else + SED_TYPE="BSD" + fi +} + +universal_sed() { + local expression=$1 + local file=$2 + + if [[ "$SED_TYPE" == "GNU" ]]; then + pwd + sed -i "$expression" "$file" + else + sed -i '' "$expression" "$file" + fi +} + +detect_sed diff --git a/tool/append_translation.dart b/tool/append_translation.dart index d196421e9..5a3658cd0 100644 --- a/tool/append_translation.dart +++ b/tool/append_translation.dart @@ -2,7 +2,7 @@ import 'utils/translation/arb_file_utils.dart'; import 'utils/translation/translation_constants.dart'; import 'utils/translation/translation_utils.dart'; -/// flutter packages pub run tool/append_translation.dart "hello_world" "Hello World!" +/// dart run tool/append_translation.dart "hello_world" "Hello World!" void main(List args) async { if (args.length < 2) { diff --git a/tool/configure.dart b/tool/configure.dart index f0f79cfb1..7199b8a82 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -1424,8 +1424,7 @@ Future generatePubspec({ git: url: https://github.com/cake-tech/flutter_secure_storage.git path: flutter_secure_storage - ref: cake-8.1.0 - version: 8.1.0 + ref: ca897a08677edb443b366352dd7412735e098e7b """; const cwEthereum = """ cw_ethereum: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index ad540a359..4deae3420 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -17,6 +18,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); + FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi")); FlutterLocalAuthenticationPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterLocalAuthenticationPluginCApi")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 92431a6fb..f8f89611c 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST connectivity_plus + flutter_inappwebview_windows flutter_local_authentication flutter_secure_storage_windows permission_handler_windows @@ -13,7 +14,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) From 367c36b4d5c2d57d98c9ec058854274517846bb3 Mon Sep 17 00:00:00 2001 From: cyan Date: Mon, 25 Nov 2024 17:00:37 +0100 Subject: [PATCH 12/41] fix sed (#1829) --- scripts/android/inject_app_details.sh | 12 ++++++------ scripts/universal_sed.sh | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/scripts/android/inject_app_details.sh b/scripts/android/inject_app_details.sh index 737ebbb88..9a8b12d9c 100755 --- a/scripts/android/inject_app_details.sh +++ b/scripts/android/inject_app_details.sh @@ -6,10 +6,10 @@ if [ -z "$APP_ANDROID_TYPE" ]; then fi cd ../.. -set -x -universal_sed "0,/version:/{s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/}" ./pubspec.yaml -universal_sed "0,/version:/{s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/}" ./android/app/src/main/AndroidManifest.xml -universal_sed "0,/__APP_SCHEME__/s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/" ./android/app/src/main/AndroidManifest.xml -universal_sed "0,/version:/{s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/}" ./android/app/src/main/AndroidManifest.xml -universal_sed "0,/version:/{s/__versionName__/${APP_ANDROID_VERSION}/}" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/version:/ {s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/;}" ./pubspec.yaml +universal_sed "0,/version:/ {s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/;}" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/__APP_SCHEME__/ {s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/;}" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/version:/ {s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/;}" ./android/app/src/main/AndroidManifest.xml +universal_sed "0,/version:/ {s/__versionName__/${APP_ANDROID_VERSION}/;}" ./android/app/src/main/AndroidManifest.xml + cd scripts/android diff --git a/scripts/universal_sed.sh b/scripts/universal_sed.sh index 8c0e3d9a4..d8a95684e 100644 --- a/scripts/universal_sed.sh +++ b/scripts/universal_sed.sh @@ -13,7 +13,6 @@ universal_sed() { local file=$2 if [[ "$SED_TYPE" == "GNU" ]]; then - pwd sed -i "$expression" "$file" else sed -i '' "$expression" "$file" From 59e8550e4e194b54dd828ff7064fede3b4224c84 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Mon, 25 Nov 2024 18:26:41 +0200 Subject: [PATCH 13/41] Generic fixes (#1823) * add timeout for mempool fee api and make it only in bitcoin * disable Monero Ledger for desktop * handle onramper tag issue * better handle main actions UI * make service status scrollable with a better UI * fix stupid race condition * minor handling * update btc fee api update our xmr node to use ssl * manually add supported unstoppable domains for now * change bitcoin default node code enhancement * revert debugging code [skip ci] * minor enhancements [skip ci] * increase sync indicator size [skip ci] * fix selecting USA country not triggering the reaction * fix scrolling on cake features page [skip ci] --- assets/bitcoin_electrum_server_list.yml | 3 - assets/node_list.yml | 1 + cw_bitcoin/lib/electrum_wallet.dart | 7 +- cw_monero/lib/api/wallet_manager.dart | 14 +- lib/buy/onramper/onramper_buy_provider.dart | 8 +- lib/entities/default_settings_migration.dart | 70 ++++++++-- lib/entities/main_actions.dart | 4 +- lib/entities/parse_address_from_domain.dart | 91 +++++++++--- lib/main.dart | 3 +- lib/reactions/on_current_wallet_change.dart | 2 + lib/src/screens/dashboard/dashboard_page.dart | 46 ++++--- .../dashboard/pages/cake_features_page.dart | 130 ++++++++---------- .../widgets/sync_indicator_icon.dart | 2 +- lib/src/widgets/blockchain_height_widget.dart | 12 +- lib/src/widgets/services_updates_widget.dart | 10 +- lib/store/app_store.dart | 4 +- .../cake_pay_cards_list_view_model.dart | 6 +- res/values/strings_fr.arb | 2 +- scripts/macos/app_env.sh | 8 +- 19 files changed, 271 insertions(+), 152 deletions(-) diff --git a/assets/bitcoin_electrum_server_list.yml b/assets/bitcoin_electrum_server_list.yml index 20a28cd24..83da6a0b2 100644 --- a/assets/bitcoin_electrum_server_list.yml +++ b/assets/bitcoin_electrum_server_list.yml @@ -1,6 +1,3 @@ -- - uri: electrum.cakewallet.com:50002 - useSSL: true - uri: btc-electrum.cakewallet.com:50002 useSSL: true diff --git a/assets/node_list.yml b/assets/node_list.yml index 6191129b3..49cc00a94 100644 --- a/assets/node_list.yml +++ b/assets/node_list.yml @@ -2,6 +2,7 @@ uri: xmr-node.cakewallet.com:18081 is_default: true trusted: true + useSSL: true - uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081 is_default: false diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index e58fad00f..73f7e09f5 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -486,10 +486,11 @@ abstract class ElectrumWalletBase @action Future updateFeeRates() async { - if (await checkIfMempoolAPIIsEnabled()) { + if (await checkIfMempoolAPIIsEnabled() && type == WalletType.bitcoin) { try { - final response = - await http.get(Uri.parse("http://mempool.cakewallet.com:8999/api/v1/fees/recommended")); + final response = await http + .get(Uri.parse("https://mempool.cakewallet.com/api/v1/fees/recommended")) + .timeout(Duration(seconds: 5)); final result = json.decode(response.body) as Map; final slowFee = (result['economyFee'] as num?)?.toInt() ?? 0; diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart index 7f9dbd8fa..d10f7e25a 100644 --- a/cw_monero/lib/api/wallet_manager.dart +++ b/cw_monero/lib/api/wallet_manager.dart @@ -286,8 +286,18 @@ Future loadWallet( /// 0: Software Wallet /// 1: Ledger /// 2: Trezor - final deviceType = monero.WalletManager_queryWalletDevice(wmPtr, - keysFileName: "$path.keys", password: password, kdfRounds: 1); + late final deviceType; + + if (Platform.isAndroid || Platform.isIOS) { + deviceType = monero.WalletManager_queryWalletDevice( + wmPtr, + keysFileName: "$path.keys", + password: password, + kdfRounds: 1, + ); + } else { + deviceType = 0; + } if (deviceType == 1) { final dummyWPtr = wptr ?? diff --git a/lib/buy/onramper/onramper_buy_provider.dart b/lib/buy/onramper/onramper_buy_provider.dart index dade41d43..e4bf38275 100644 --- a/lib/buy/onramper/onramper_buy_provider.dart +++ b/lib/buy/onramper/onramper_buy_provider.dart @@ -251,8 +251,12 @@ class OnRamperBuyProvider extends BuyProvider { return tag; case 'POL': return 'POLYGON'; - default: - return CryptoCurrency.fromString(tag).fullName ?? tag; + default: + try { + return CryptoCurrency.fromString(tag).fullName!; + } catch (_) { + return tag; + } } } diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index f873314c0..9e0e3457d 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -260,10 +260,22 @@ Future defaultSettingsMigration( updateBtcElectrumNodeToUseSSL(nodes, sharedPreferences); break; case 43: - _updateCakeXmrNode(nodes); + await _updateCakeXmrNode(nodes); _deselectExchangeProvider(sharedPreferences, "THORChain"); _deselectExchangeProvider(sharedPreferences, "SimpleSwap"); break; + case 44: + await _updateCakeXmrNode(nodes); + await _changeDefaultNode( + nodes: nodes, + sharedPreferences: sharedPreferences, + type: WalletType.bitcoin, + newDefaultUri: newCakeWalletBitcoinUri, + currentNodePreferenceKey: PreferencesKey.currentBitcoinElectrumSererIdKey, + useSSL: true, + oldUri: 'cakewallet.com', + ); + break; default: break; @@ -279,17 +291,54 @@ Future defaultSettingsMigration( await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version); } -void _updateCakeXmrNode(Box nodes) { +/// generic function for changing any wallet default node +/// instead of making a new function for each change +Future _changeDefaultNode({ + required Box nodes, + required SharedPreferences sharedPreferences, + required WalletType type, + required String newDefaultUri, + required String currentNodePreferenceKey, + required bool useSSL, + required String oldUri, // leave empty if you want to force replace the node regardless of the user's current node +}) async { + final currentNodeId = sharedPreferences.getInt(currentNodePreferenceKey); + final currentNode = nodes.values.firstWhere((node) => node.key == currentNodeId); + final shouldReplace = currentNode.uriRaw.contains(oldUri); + + if (shouldReplace) { + var newNodeId = + nodes.values.firstWhereOrNull((element) => element.uriRaw == newDefaultUri)?.key; + + // new node doesn't exist, then add it + if (newNodeId == null) { + final newNode = Node( + uri: newDefaultUri, + type: type, + useSSL: useSSL, + ); + + await nodes.add(newNode); + newNodeId = newNode.key; + } + + await sharedPreferences.setInt(currentNodePreferenceKey, newNodeId as int); + } +} + +Future _updateCakeXmrNode(Box nodes) async { final node = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletMoneroUri); - if (node != null && !node.trusted) { + if (node != null) { node.trusted = true; - node.save(); + node.useSSL = true; + await node.save(); } } void updateBtcElectrumNodeToUseSSL(Box nodes, SharedPreferences sharedPreferences) { - final btcElectrumNode = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletBitcoinUri); + final btcElectrumNode = + nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletBitcoinUri); if (btcElectrumNode != null) { btcElectrumNode.useSSL = true; @@ -538,7 +587,6 @@ Node? getBitcoinCashDefaultElectrumServer({required Box nodes}) { } Node getMoneroDefaultNode({required Box nodes}) { - final timeZone = DateTime.now().timeZoneOffset.inHours; var nodeUri = newCakeWalletMoneroUri; try { @@ -858,7 +906,8 @@ Future changeDefaultMoneroNode( } }); - final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero, trusted: true); + final newCakeWalletNode = + Node(uri: newCakeWalletMoneroUri, type: WalletType.monero, trusted: true); await nodeSource.add(newCakeWalletNode); @@ -897,7 +946,7 @@ Future updateBtcNanoWalletInfos(Box walletsInfoSource) async { Future changeDefaultNanoNode( Box nodeSource, SharedPreferences sharedPreferences) async { const oldNanoNodeUriPattern = 'rpc.nano.to'; - final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey); + final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey); final currentNanoNode = nodeSource.values.firstWhere((node) => node.key == currentNanoNodeId); final newCakeWalletNode = Node( @@ -909,7 +958,8 @@ Future changeDefaultNanoNode( await nodeSource.add(newCakeWalletNode); if (currentNanoNode.uri.toString().contains(oldNanoNodeUriPattern)) { - await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, newCakeWalletNode.key as int); + await sharedPreferences.setInt( + PreferencesKey.currentNanoNodeIdKey, newCakeWalletNode.key as int); } } @@ -924,7 +974,7 @@ Future changeDefaultBitcoinNode( currentBitcoinNode.uri.toString().contains(cakeWalletBitcoinNodeUriPattern); final newCakeWalletBitcoinNode = - Node(uri: newCakeWalletBitcoinUri, type: WalletType.bitcoin, useSSL: false); + Node(uri: newCakeWalletBitcoinUri, type: WalletType.bitcoin, useSSL: true); if (!nodeSource.values.any((element) => element.uriRaw == newCakeWalletBitcoinUri)) { await nodeSource.add(newCakeWalletBitcoinNode); diff --git a/lib/entities/main_actions.dart b/lib/entities/main_actions.dart index 94be0d2b7..29c161c5f 100644 --- a/lib/entities/main_actions.dart +++ b/lib/entities/main_actions.dart @@ -1,7 +1,5 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:flutter/material.dart'; @@ -68,7 +66,7 @@ class MainActions { static MainActions tradeAction = MainActions._( - name: (context) => '${S.of(context).buy} / ${S.of(context).sell}', + name: (context) => '${S.of(context).buy}/${S.of(context).sell}', image: 'assets/images/buy_sell.png', isEnabled: (viewModel) => viewModel.isEnabledTradeAction, canShow: (viewModel) => viewModel.hasTradeAction, diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 11ba4724c..42ab19b31 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -26,23 +26,80 @@ class AddressResolver { final SettingsStore settingsStore; static const unstoppableDomains = [ - 'crypto', - 'zil', - 'x', - 'wallet', - 'bitcoin', - '888', - 'nft', - 'dao', - 'blockchain', - 'polygon', - 'klever', - 'hi', - 'kresus', - 'anime', - 'manga', - 'binanceus', - 'xmr', + "888", + "altimist", + "anime", + "austin", + "bald", + "benji", + "bet", + "binanceus", + "bitcoin", + "bitget", + "blockchain", + "ca", + "chomp", + "clay", + "co", + "com", + "crypto", + "dao", + "dfz", + "digital", + "dream", + "eth", + "ethermail", + "farms", + "fun", + "go", + "group", + "hi", + "host", + "info", + "io", + "klever", + "kresus", + "kryptic", + "lfg", + "life", + "live", + "ltd", + "manga", + "metropolis", + "moon", + "mumu", + "net", + "nft", + "online", + "org", + "pog", + "polygon", + "press", + "pro", + "propykeys", + "pudgy", + "pw", + "raiin", + "secret", + "site", + "smobler", + "space", + "stepn", + "store", + "tball", + "tech", + "ubu", + "uno", + "unstoppable", + "wallet", + "website", + "wifi", + "witg", + "wrkx", + "x", + "xmr", + "xyz", + "zil", ]; static String? extractAddressByType({required String raw, required CryptoCurrency type}) { diff --git a/lib/main.dart b/lib/main.dart index 51fab4dd1..d67fda098 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,7 +16,6 @@ import 'package:cake_wallet/exchange/exchange_template.dart'; import 'package:cake_wallet/exchange/trade.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/locales/locale.dart'; -import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/reactions/bootstrap.dart'; import 'package:cake_wallet/router.dart' as Router; import 'package:cake_wallet/routes.dart'; @@ -204,7 +203,7 @@ Future initializeAppConfigs() async { transactionDescriptions: transactionDescriptions, secureStorage: secureStorage, anonpayInvoiceInfo: anonpayInvoiceInfo, - initialMigrationVersion: 43, + initialMigrationVersion: 44, ); } diff --git a/lib/reactions/on_current_wallet_change.dart b/lib/reactions/on_current_wallet_change.dart index d7e6f90c0..b804ff14e 100644 --- a/lib/reactions/on_current_wallet_change.dart +++ b/lib/reactions/on_current_wallet_change.dart @@ -63,6 +63,8 @@ void startCurrentWalletChangeReaction( startWalletSyncStatusChangeReaction(wallet, fiatConversionStore); startCheckConnectionReaction(wallet, settingsStore); + await Future.delayed(Duration.zero); + if (wallet.type == WalletType.monero || wallet.type == WalletType.wownero || wallet.type == WalletType.bitcoin || diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index 9c012d518..cabf73b21 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -291,32 +291,34 @@ class _DashboardPageView extends BasePage { children: MainActions.all .where((element) => element.canShow?.call(dashboardViewModel) ?? true) .map( - (action) => Semantics( - button: true, - enabled: (action.isEnabled?.call(dashboardViewModel) ?? true), - child: ActionButton( - key: ValueKey( - 'dashboard_page_${action.name(context)}_action_button_key'), - image: Image.asset( - action.image, - height: 24, - width: 24, - color: action.isEnabled?.call(dashboardViewModel) ?? true - ? Theme.of(context) - .extension()! - .mainActionsIconColor + (action) => Expanded( + child: Semantics( + button: true, + enabled: (action.isEnabled?.call(dashboardViewModel) ?? true), + child: ActionButton( + key: ValueKey( + 'dashboard_page_${action.name(context)}_action_button_key'), + image: Image.asset( + action.image, + height: 24, + width: 24, + color: action.isEnabled?.call(dashboardViewModel) ?? true + ? Theme.of(context) + .extension()! + .mainActionsIconColor + : Theme.of(context) + .extension()! + .labelTextColor, + ), + title: action.name(context), + onClick: () async => + await action.onTap(context, dashboardViewModel), + textColor: action.isEnabled?.call(dashboardViewModel) ?? true + ? null : Theme.of(context) .extension()! .labelTextColor, ), - title: action.name(context), - onClick: () async => - await action.onTap(context, dashboardViewModel), - textColor: action.isEnabled?.call(dashboardViewModel) ?? true - ? null - : Theme.of(context) - .extension()! - .labelTextColor, ), ), ) diff --git a/lib/src/screens/dashboard/pages/cake_features_page.dart b/lib/src/screens/dashboard/pages/cake_features_page.dart index 37bc3a55f..775cb6c3f 100644 --- a/lib/src/screens/dashboard/pages/cake_features_page.dart +++ b/lib/src/screens/dashboard/pages/cake_features_page.dart @@ -10,91 +10,81 @@ import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:flutter_svg/flutter_svg.dart'; class CakeFeaturesPage extends StatelessWidget { CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel}); final DashboardViewModel dashboardViewModel; final CakeFeaturesViewModel cakeFeaturesViewModel; - final _scrollController = ScrollController(); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: RawScrollbar( - thumbColor: Colors.white.withOpacity(0.15), - radius: Radius.circular(20), - thumbVisibility: true, - thickness: 2, - controller: _scrollController, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 50), - Text( - 'Cake ${S.of(context).features}', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.w500, - color: Theme.of(context).extension()!.pageTitleTextColor, - ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 50), + Text( + 'Cake ${S.of(context).features}', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w500, + color: Theme.of(context).extension()!.pageTitleTextColor, ), - Expanded( - child: ListView( - controller: _scrollController, - children: [ - SizedBox(height: 20), - DashBoardRoundedCardWidget( - onTap: () => _navigatorToGiftCardsPage(context), - title: 'Cake Pay', - subTitle: S.of(context).cake_pay_subtitle, - image: Image.asset( - 'assets/images/cards.png', - height: 100, - width: 115, - fit: BoxFit.cover, - ), + ), + Expanded( + child: ListView( + children: [ + SizedBox(height: 20), + DashBoardRoundedCardWidget( + onTap: () => _navigatorToGiftCardsPage(context), + title: 'Cake Pay', + subTitle: S.of(context).cake_pay_subtitle, + image: Image.asset( + 'assets/images/cards.png', + height: 100, + width: 115, + fit: BoxFit.cover, ), - SizedBox(height: 10), - DashBoardRoundedCardWidget( - onTap: () => _launchUrl("cake.nano-gpt.com"), - title: "NanoGPT", - subTitle: S.of(context).nanogpt_subtitle, - image: Image.asset( - 'assets/images/nanogpt.png', - height: 80, - width: 80, - fit: BoxFit.cover, - ), + ), + SizedBox(height: 10), + DashBoardRoundedCardWidget( + onTap: () => _launchUrl("cake.nano-gpt.com"), + title: "NanoGPT", + subTitle: S.of(context).nanogpt_subtitle, + image: Image.asset( + 'assets/images/nanogpt.png', + height: 80, + width: 80, + fit: BoxFit.cover, ), - SizedBox(height: 10), - Observer( - builder: (context) { - if (!dashboardViewModel.hasSignMessages) { - return const SizedBox(); - } - return DashBoardRoundedCardWidget( - onTap: () => Navigator.of(context).pushNamed(Routes.signPage), - title: S.current.sign_verify_message, - subTitle: S.current.sign_verify_message_sub, - icon: Icon( - Icons.speaker_notes_rounded, - color: - Theme.of(context).extension()!.pageTitleTextColor, - size: 75, - ), - ); - }, - ), - ], - ), + ), + SizedBox(height: 10), + Observer( + builder: (context) { + if (!dashboardViewModel.hasSignMessages) { + return const SizedBox(); + } + return DashBoardRoundedCardWidget( + onTap: () => Navigator.of(context).pushNamed(Routes.signPage), + title: S.current.sign_verify_message, + subTitle: S.current.sign_verify_message_sub, + icon: Icon( + Icons.speaker_notes_rounded, + color: + Theme.of(context).extension()!.pageTitleTextColor, + size: 75, + ), + ); + }, + ), + ], ), - ], - ), + ), + ], ), ), ); diff --git a/lib/src/screens/dashboard/widgets/sync_indicator_icon.dart b/lib/src/screens/dashboard/widgets/sync_indicator_icon.dart index 21133a438..aca3231ec 100644 --- a/lib/src/screens/dashboard/widgets/sync_indicator_icon.dart +++ b/lib/src/screens/dashboard/widgets/sync_indicator_icon.dart @@ -8,7 +8,7 @@ class SyncIndicatorIcon extends StatelessWidget { {this.boolMode = true, this.isSynced = false, this.value = waiting, - this.size = 4.0}); + this.size = 6.0}); final bool boolMode; final bool isSynced; diff --git a/lib/src/widgets/blockchain_height_widget.dart b/lib/src/widgets/blockchain_height_widget.dart index 1c6b6da02..650ee684d 100644 --- a/lib/src/widgets/blockchain_height_widget.dart +++ b/lib/src/widgets/blockchain_height_widget.dart @@ -191,11 +191,13 @@ class BlockchainHeightState extends State { height = wownero!.getHeightByDate(date: date); } } - setState(() { - dateController.text = DateFormat('yyyy-MM-dd').format(date); - restoreHeightController.text = '$height'; - _changeHeight(height); - }); + if (mounted) { + setState(() { + dateController.text = DateFormat('yyyy-MM-dd').format(date); + restoreHeightController.text = '$height'; + _changeHeight(height); + }); + } } } diff --git a/lib/src/widgets/services_updates_widget.dart b/lib/src/widgets/services_updates_widget.dart index 1787b7118..17f231303 100644 --- a/lib/src/widgets/services_updates_widget.dart +++ b/lib/src/widgets/services_updates_widget.dart @@ -92,15 +92,17 @@ class _ServicesUpdatesWidgetState extends State { ); } return Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 20), - child: Stack( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Column( children: [ - body, + Expanded(child: body), Align( alignment: Alignment.bottomCenter, child: Padding( padding: EdgeInsets.symmetric( - horizontal: MediaQuery.of(context).size.width / 8), + horizontal: MediaQuery.of(context).size.width / 8, + vertical: 20, + ), child: PrimaryImageButton( onPressed: () { try { diff --git a/lib/store/app_store.dart b/lib/store/app_store.dart index 24d5dc6a4..ff3ba0535 100644 --- a/lib/store/app_store.dart +++ b/lib/store/app_store.dart @@ -50,8 +50,8 @@ abstract class AppStoreBase with Store { getIt.get().create(); await getIt.get().init(); } - await getIt.get().setString(PreferencesKey.currentWalletName, wallet.name); - await getIt + getIt.get().setString(PreferencesKey.currentWalletName, wallet.name); + getIt .get() .setInt(PreferencesKey.currentWalletType, serializeToInt(wallet.type)); } diff --git a/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart b/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart index 8585da9da..442bd51b4 100644 --- a/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart +++ b/lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart @@ -204,7 +204,11 @@ abstract class CakePayCardsListViewModelBase with Store { } @action - void setSelectedCountry(Country country) => settingsStore.selectedCakePayCountry = country; + void setSelectedCountry(Country country) { + // just so it triggers the reaction even when selecting the default country + settingsStore.selectedCakePayCountry = null; + settingsStore.selectedCakePayCountry = country; + } @action void togglePrepaidCards() => displayPrepaidCards = !displayPrepaidCards; diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 549ec5275..741adc472 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -919,7 +919,7 @@ "wallet_seed_legacy": "Graine de portefeuille hérité", "wallet_store_monero_wallet": "Portefeuille (Wallet) Monero", "walletConnect": "WalletConnect", - "wallets": "Portefeuilles (Wallets)", + "wallets": "Portefeuilles", "warning": "Avertissement", "welcome": "Bienvenue sur", "welcome_to_cakepay": "Bienvenue sur Cake Pay !", diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index 8f3b68ab5..930a1e5ed 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.8.0" -MONERO_COM_BUILD_NUMBER=36 +MONERO_COM_VERSION="1.8.1" +MONERO_COM_BUILD_NUMBER=37 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.14.0" -CAKEWALLET_BUILD_NUMBER=95 +CAKEWALLET_VERSION="1.14.1" +CAKEWALLET_BUILD_NUMBER=96 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then From 8ceaa013ebfd6edb00b80d6fb46dc74f8e1e1ab7 Mon Sep 17 00:00:00 2001 From: cyan Date: Mon, 25 Nov 2024 19:55:05 +0100 Subject: [PATCH 14/41] Fix sed (again) (#1830) * fix sed * 0, -> 1, so it doesn't silently error out * remve hardcoded CONFIG_ARGS --- scripts/android/inject_app_details.sh | 10 +++++----- scripts/ios/app_config.sh | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/android/inject_app_details.sh b/scripts/android/inject_app_details.sh index 9a8b12d9c..2e50ea31b 100755 --- a/scripts/android/inject_app_details.sh +++ b/scripts/android/inject_app_details.sh @@ -6,10 +6,10 @@ if [ -z "$APP_ANDROID_TYPE" ]; then fi cd ../.. -universal_sed "0,/version:/ {s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/;}" ./pubspec.yaml -universal_sed "0,/version:/ {s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/;}" ./android/app/src/main/AndroidManifest.xml -universal_sed "0,/__APP_SCHEME__/ {s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/;}" ./android/app/src/main/AndroidManifest.xml -universal_sed "0,/version:/ {s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/;}" ./android/app/src/main/AndroidManifest.xml -universal_sed "0,/version:/ {s/__versionName__/${APP_ANDROID_VERSION}/;}" ./android/app/src/main/AndroidManifest.xml +universal_sed "1,/version:/ {s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/;}" ./pubspec.yaml +universal_sed "1,/version:/ {s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/;}" ./android/app/src/main/AndroidManifest.xml +universal_sed "1,/__APP_SCHEME__/ {s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/;}" ./android/app/src/main/AndroidManifest.xml +universal_sed "1,/version:/ {s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/;}" ./android/app/src/main/AndroidManifest.xml +universal_sed "1,/version:/ {s/__versionName__/${APP_ANDROID_VERSION}/;}" ./android/app/src/main/AndroidManifest.xml cd scripts/android diff --git a/scripts/ios/app_config.sh b/scripts/ios/app_config.sh index 8b217dc54..396ccd7f0 100755 --- a/scripts/ios/app_config.sh +++ b/scripts/ios/app_config.sh @@ -43,7 +43,6 @@ case $APP_IOS_TYPE in CONFIG_ARGS="--haven" ;; esac -CONFIG_ARGS="--monero --ethereum --polygon --nano --solana --tron --wownero" cp -rf pubspec_description.yaml pubspec.yaml flutter pub get From 83cfc7dd703c04613c6b83f2a9234a3c98229660 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 25 Nov 2024 21:05:36 +0200 Subject: [PATCH 15/41] fix building with haven --- cw_haven/android/build.gradle | 18 +++++++++++++++--- cw_shared_external/android/build.gradle | 15 ++++++++++++++- linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 ++ pubspec_base.yaml | 2 +- scripts/android/inject_app_details.sh | 2 +- windows/flutter/generated_plugins.cmake | 1 + 7 files changed, 35 insertions(+), 6 deletions(-) diff --git a/cw_haven/android/build.gradle b/cw_haven/android/build.gradle index d29c31d4e..8eb728a67 100644 --- a/cw_haven/android/build.gradle +++ b/cw_haven/android/build.gradle @@ -2,14 +2,14 @@ group 'com.cakewallet.cw_haven' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '2.0.21' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:8.7.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -25,8 +25,20 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 33 + if (project.android.hasProperty("namespace")) { + namespace 'com.cakewallet.cw_haven' + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = '17' + } sourceSets { main.java.srcDirs += 'src/main/kotlin' } diff --git a/cw_shared_external/android/build.gradle b/cw_shared_external/android/build.gradle index 64b550364..8d2b1b13d 100644 --- a/cw_shared_external/android/build.gradle +++ b/cw_shared_external/android/build.gradle @@ -25,7 +25,20 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 30 + compileSdkVersion 33 + + if (project.android.hasProperty("namespace")) { + namespace 'com.cakewallet.cw_shared_external' + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = '17' + } sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 4b9eb3b2d..f52be7481 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 52b44e53e..42b9fa84c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import connectivity_plus +import cw_mweb import device_info_plus import devicelocale import fast_scanner @@ -23,6 +24,7 @@ import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + CwMwebPlugin.register(with: registry.registrar(forPlugin: "CwMwebPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 39fe953d0..221f1d9bf 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -26,7 +26,7 @@ dependencies: share_plus: ^10.0.0 # date_range_picker: ^1.0.6 #https://api.flutter.dev/flutter/material/showDateRangePicker.html - dio: ^4.0.6 + dio: ^5.7.0 hive: ^2.2.3 hive_flutter: ^1.1.0 local_auth_android: ^1.0.46 diff --git a/scripts/android/inject_app_details.sh b/scripts/android/inject_app_details.sh index 2e50ea31b..7b0d74798 100755 --- a/scripts/android/inject_app_details.sh +++ b/scripts/android/inject_app_details.sh @@ -6,10 +6,10 @@ if [ -z "$APP_ANDROID_TYPE" ]; then fi cd ../.. +set -x universal_sed "1,/version:/ {s/version:.*/version: ${APP_ANDROID_VERSION}+${APP_ANDROID_BUILD_NUMBER}/;}" ./pubspec.yaml universal_sed "1,/version:/ {s/__APP_PACKAGE__/${APP_ANDROID_PACKAGE}/;}" ./android/app/src/main/AndroidManifest.xml universal_sed "1,/__APP_SCHEME__/ {s/__APP_SCHEME__/${APP_ANDROID_SCHEME}/;}" ./android/app/src/main/AndroidManifest.xml universal_sed "1,/version:/ {s/__versionCode__/${APP_ANDROID_BUILD_NUMBER}/;}" ./android/app/src/main/AndroidManifest.xml universal_sed "1,/version:/ {s/__versionName__/${APP_ANDROID_VERSION}/;}" ./android/app/src/main/AndroidManifest.xml - cd scripts/android diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index f8f89611c..e0f2c11c0 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -14,6 +14,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) From 09bc186feadd5ad3048060a38757a9cb5f33b94a Mon Sep 17 00:00:00 2001 From: cyan Date: Tue, 26 Nov 2024 14:40:26 +0100 Subject: [PATCH 16/41] Cw 835 investigate failed to get earliest block height when sending monero (#1827) * update flutter to 3.24.3 * bump flutter to 3.24.4, fix all android issues (i hope) * update uni_links path * update sensitive_clipboard * update dependencies * update fast_scanner * update the ref * Update how_to_add_new_wallet_type.md [skip ci] * Update how_to_add_new_wallet_type.md [skip ci] * Update how_to_add_new_wallet_type.md [skip ci] * Update how_to_add_new_wallet_type.md [skip ci] * CW-835: Fix failed to get earlist block height when sending monero --------- Co-authored-by: Omar Hatem --- cw_monero/lib/api/transaction_history.dart | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index f55545801..a00a6b206 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -91,12 +91,19 @@ Future createTransactionSync( List preferredInputs = const []}) async { final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount); - + + final waddr = wptr!.address; + + // force reconnection in case the os killed the connection? + // fixes failed to get block height error. + Isolate.run(() async { + monero.Wallet_synchronized(Pointer.fromAddress(waddr)); + }); + final address_ = address.toNativeUtf8(); final paymentId_ = paymentId.toNativeUtf8(); final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8(); - final waddr = wptr!.address; final addraddr = address_.address; final paymentIdAddr = paymentId_.address; final preferredInputsAddr = preferredInputs_.address; From 738731d3e51ede6b40ad11ab9893d5e0ee86f664 Mon Sep 17 00:00:00 2001 From: cyan Date: Tue, 26 Nov 2024 14:43:56 +0100 Subject: [PATCH 17/41] CW-826 Fix missing tx keys in monero (#1828) * CW-826 Fix missing tx keys in monero * force store wallet * don't return error string --- cw_monero/lib/api/transaction_history.dart | 13 ++----------- cw_monero/lib/api/wallet.dart | 5 +++-- cw_monero/lib/pending_monero_transaction.dart | 2 ++ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index a00a6b206..662eb1bb5 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -17,7 +17,7 @@ String getTxKey(String txId) { final status = monero.Wallet_status(wptr!); if (status != 0) { final error = monero.Wallet_errorString(wptr!); - return txId+"_"+error; + return ""; } return txKey; } @@ -364,16 +364,7 @@ class Transaction { confirmations = monero.TransactionInfo_confirmations(txInfo), fee = monero.TransactionInfo_fee(txInfo), description = monero.TransactionInfo_description(txInfo), - key = getTxKey(txInfo); - - static String getTxKey(monero.TransactionInfo txInfo) { - final txKey = monero.Wallet_getTxKey(wptr!, txid: monero.TransactionInfo_hash(txInfo)); - final status = monero.Wallet_status(wptr!); - if (status != 0) { - return ""; - } - return txKey; - } + key = getTxKey(monero.TransactionInfo_hash(txInfo)); Transaction.dummy({ required this.displayLabel, diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 928fd7ef1..70c610418 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -150,14 +150,15 @@ final storeMutex = Mutex(); int lastStorePointer = 0; int lastStoreHeight = 0; -void storeSync() async { +void storeSync({bool force = false}) async { final addr = wptr!.address; final synchronized = await Isolate.run(() { return monero.Wallet_synchronized(Pointer.fromAddress(addr)); }); if (lastStorePointer == wptr!.address && lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) && - !synchronized) { + !synchronized && + !force) { return; } lastStorePointer = wptr!.address; diff --git a/cw_monero/lib/pending_monero_transaction.dart b/cw_monero/lib/pending_monero_transaction.dart index eb714eeb3..1c01a60dc 100644 --- a/cw_monero/lib/pending_monero_transaction.dart +++ b/cw_monero/lib/pending_monero_transaction.dart @@ -6,6 +6,7 @@ import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/amount_converter.dart'; import 'package:cw_core/pending_transaction.dart'; +import 'package:cw_monero/api/wallet.dart'; class DoubleSpendException implements Exception { DoubleSpendException(); @@ -53,6 +54,7 @@ class PendingMoneroTransaction with PendingTransaction { rethrow; } + storeSync(force: true); } @override From eff6616981cd2fe453e0322e5d8e05f30ab6b4c0 Mon Sep 17 00:00:00 2001 From: Seth For Privacy <40500387+sethforprivacy@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:56:00 -0500 Subject: [PATCH 18/41] Migrate to new self-hosted mempool.space instance (#1820) Co-authored-by: Omar Hatem --- cw_bitcoin/lib/electrum_wallet.dart | 4 ++-- cw_core/lib/get_height_by_date.dart | 2 +- lib/view_model/transaction_details_view_model.dart | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 73f7e09f5..c29df3c4a 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1707,7 +1707,7 @@ abstract class ElectrumWalletBase try { final blockHash = await http.get( Uri.parse( - "http://mempool.cakewallet.com:8999/api/v1/block-height/$height", + "https://mempool.cakewallet.com/api/v1/block-height/$height", ), ); @@ -1716,7 +1716,7 @@ abstract class ElectrumWalletBase jsonDecode(blockHash.body) != null) { final blockResponse = await http.get( Uri.parse( - "http://mempool.cakewallet.com:8999/api/v1/block/${blockHash.body}", + "https://mempool.cakewallet.com/api/v1/block/${blockHash.body}", ), ); if (blockResponse.statusCode == 200 && diff --git a/cw_core/lib/get_height_by_date.dart b/cw_core/lib/get_height_by_date.dart index 2b0b77a89..7929d7cbd 100644 --- a/cw_core/lib/get_height_by_date.dart +++ b/cw_core/lib/get_height_by_date.dart @@ -270,7 +270,7 @@ const bitcoinDates = { Future getBitcoinHeightByDateAPI({required DateTime date}) async { final response = await http.get( Uri.parse( - "http://mempool.cakewallet.com:8999/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}", + "https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}", ), ); diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart index a189ebe6c..e675acf17 100644 --- a/lib/view_model/transaction_details_view_model.dart +++ b/lib/view_model/transaction_details_view_model.dart @@ -159,7 +159,7 @@ abstract class TransactionDetailsViewModelBase with Store { case WalletType.monero: return 'https://monero.com/tx/${txId}'; case WalletType.bitcoin: - return 'https://mempool.space/${wallet.isTestnet ? "testnet/" : ""}tx/${txId}'; + return 'https://mempool.cakewallet.com/${wallet.isTestnet ? "testnet/" : ""}tx/${txId}'; case WalletType.litecoin: return 'https://blockchair.com/litecoin/transaction/${txId}'; case WalletType.bitcoinCash: From 765ae877126a71b580c09bbf9c329f03c96e1f5d Mon Sep 17 00:00:00 2001 From: cyan Date: Tue, 26 Nov 2024 15:59:22 +0100 Subject: [PATCH 19/41] Automatically upgrade non-SSL nodes to SSL if they fail (#1757) * Automatically upgrade non-SSL nodes to SSL if they fail * another ssl catch * [skip ci] pr fixes --- cw_core/lib/node.dart | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart index 1094b6402..18d2ffc44 100644 --- a/cw_core/lib/node.dart +++ b/cw_core/lib/node.dart @@ -203,9 +203,30 @@ class Node extends HiveObject with Keyable { headers: {'Content-Type': 'application/json'}, body: json.encode(body), ); - client.close(); + if (( + response.body.contains("400 Bad Request") // Some other generic error + || response.body.contains("plain HTTP request was sent to HTTPS port") // Cloudflare + || response.headers["location"] != null // Generic reverse proxy + || response.body.contains("301 Moved Permanently") // Poorly configured generic reverse proxy + ) && !(useSSL??false) + ) { + + final oldUseSSL = useSSL; + useSSL = true; + try { + final ret = await requestMoneroNode(); + if (ret == true) { + await save(); + return ret; + } + useSSL = oldUseSSL; + } catch (e) { + useSSL = oldUseSSL; + } + } + final resBody = json.decode(response.body) as Map; return !(resBody['result']['offline'] as bool); } catch (_) { From 9706243c81d4c6d0888846a09c5ef5874c5cd53f Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Wed, 27 Nov 2024 02:20:08 +0200 Subject: [PATCH 20/41] change default tron node to nowNodes if not already --- lib/entities/default_settings_migration.dart | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 9e0e3457d..7f0679625 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -273,7 +273,19 @@ Future defaultSettingsMigration( newDefaultUri: newCakeWalletBitcoinUri, currentNodePreferenceKey: PreferencesKey.currentBitcoinElectrumSererIdKey, useSSL: true, - oldUri: 'cakewallet.com', + oldUri: ['cakewallet.com'], + ); + _changeDefaultNode( + nodes: nodes, + sharedPreferences: sharedPreferences, + type: WalletType.tron, + newDefaultUri: tronDefaultNodeUri, + currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey, + useSSL: true, + oldUri: [ + 'tron-rpc.publicnode.com:443', + 'api.trongrid.io', + ], ); break; @@ -300,11 +312,11 @@ Future _changeDefaultNode({ required String newDefaultUri, required String currentNodePreferenceKey, required bool useSSL, - required String oldUri, // leave empty if you want to force replace the node regardless of the user's current node + required List oldUri, // leave empty if you want to force replace the node regardless of the user's current node }) async { final currentNodeId = sharedPreferences.getInt(currentNodePreferenceKey); final currentNode = nodes.values.firstWhere((node) => node.key == currentNodeId); - final shouldReplace = currentNode.uriRaw.contains(oldUri); + final shouldReplace = oldUri.any((e) => currentNode.uriRaw.contains(e)); if (shouldReplace) { var newNodeId = From 87178b2a54481b4c9498c093b06002f0f2e0d5b0 Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 27 Nov 2024 16:34:36 +0100 Subject: [PATCH 21/41] CW-766 fix coin freezing (#1751) * fix coin freezing * fix frozen balance * update monero_c hash * update monero_c hash (after merge) * fix test E make it ready * revert local change * throw error on wow as well * experiment with view model code * move view model into di.dart --- cw_monero/lib/api/coins_info.dart | 12 +++++++ cw_monero/lib/api/transaction_history.dart | 7 +++- cw_monero/lib/api/wallet.dart | 10 ++++++ cw_monero/lib/monero_unspent.dart | 24 ++++++++++++- cw_monero/lib/monero_wallet.dart | 40 +++++++++------------ cw_wownero/lib/api/transaction_history.dart | 10 ++++-- lib/di.dart | 1 + lib/view_model/send/send_view_model.dart | 16 ++++++++- 8 files changed, 92 insertions(+), 28 deletions(-) diff --git a/cw_monero/lib/api/coins_info.dart b/cw_monero/lib/api/coins_info.dart index c1b634cc6..ef7d3cfd6 100644 --- a/cw_monero/lib/api/coins_info.dart +++ b/cw_monero/lib/api/coins_info.dart @@ -12,6 +12,18 @@ int countOfCoins() => monero.Coins_count(coins!); monero.CoinsInfo getCoin(int index) => monero.Coins_coin(coins!, index); +int? getCoinByKeyImage(String keyImage) { + final count = countOfCoins(); + for (int i = 0; i < count; i++) { + final coin = getCoin(i); + final coinAddress = monero.CoinsInfo_keyImage(coin); + if (keyImage == coinAddress) { + return i; + } + } + return null; +} + void freezeCoin(int index) => monero.Coins_setFrozen(coins!, index: index); void thawCoin(int index) => monero.Coins_thaw(coins!, index: index); diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index 662eb1bb5..7c253509c 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -6,6 +6,7 @@ import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart'; import 'package:cw_monero/api/monero_output.dart'; import 'package:cw_monero/api/structs/pending_transaction.dart'; import 'package:cw_monero/api/wallet.dart'; +import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart'; import 'package:ffi/ffi.dart'; import 'package:monero/monero.dart' as monero; import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen; @@ -101,7 +102,11 @@ Future createTransactionSync( }); final address_ = address.toNativeUtf8(); - final paymentId_ = paymentId.toNativeUtf8(); + final paymentId_ = paymentId.toNativeUtf8(); + if (preferredInputs.isEmpty) { + throw MoneroTransactionCreationException("No inputs provided, transaction cannot be constructed"); + } + final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8(); final addraddr = address_.address; diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 70c610418..667a1ff69 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -4,6 +4,7 @@ import 'dart:isolate'; import 'package:cw_monero/api/account_list.dart'; import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart'; +import 'package:flutter/foundation.dart'; import 'package:monero/monero.dart' as monero; import 'package:mutex/mutex.dart'; @@ -129,6 +130,15 @@ Future setupNodeSync( throw SetupWalletException(message: error); } + if (kDebugMode) { + monero.Wallet_init3( + wptr!, argv0: '', + defaultLogBaseName: 'moneroc', + console: true, + logPath: '', + ); + } + return status == 0; } diff --git a/cw_monero/lib/monero_unspent.dart b/cw_monero/lib/monero_unspent.dart index 87d8f0b39..f45fcddaf 100644 --- a/cw_monero/lib/monero_unspent.dart +++ b/cw_monero/lib/monero_unspent.dart @@ -1,10 +1,32 @@ import 'package:cw_core/unspent_transaction_output.dart'; +import 'package:cw_monero/api/coins_info.dart'; +import 'package:monero/monero.dart' as monero; class MoneroUnspent extends Unspent { MoneroUnspent( String address, String hash, String keyImage, int value, bool isFrozen, this.isUnlocked) : super(address, hash, value, 0, keyImage) { - this.isFrozen = isFrozen; + } + + @override + set isFrozen(bool freeze) { + print("set isFrozen: $freeze ($keyImage): $freeze"); + final coinId = getCoinByKeyImage(keyImage!); + if (coinId == null) throw Exception("Unable to find a coin for address $address"); + if (freeze) { + freezeCoin(coinId); + } else { + thawCoin(coinId); + } + } + + @override + bool get isFrozen { + print("get isFrozen"); + final coinId = getCoinByKeyImage(keyImage!); + if (coinId == null) throw Exception("Unable to find a coin for address $address"); + final coin = getCoin(coinId); + return monero.CoinsInfo_frozen(coin); } final bool isUnlocked; diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index 5f53b30ba..2b302e745 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -309,9 +309,8 @@ abstract class MoneroWalletBase extends WalletBase element.walletId == id && element.accountIndex == walletAddresses.account!.id)) { - if (coin.isFrozen) frozenBalance += coin.value; + if (coin.isFrozen && !coin.isSending) frozenBalance += coin.value; } - return frozenBalance; } diff --git a/cw_wownero/lib/api/transaction_history.dart b/cw_wownero/lib/api/transaction_history.dart index 6b0923e83..ce93df7d1 100644 --- a/cw_wownero/lib/api/transaction_history.dart +++ b/cw_wownero/lib/api/transaction_history.dart @@ -6,13 +6,16 @@ import 'package:cw_wownero/api/exceptions/creation_transaction_exception.dart'; import 'package:cw_wownero/api/wallet.dart'; import 'package:cw_wownero/api/wownero_output.dart'; import 'package:cw_wownero/api/structs/pending_transaction.dart'; +import 'package:cw_wownero/exceptions/wownero_transaction_creation_exception.dart'; import 'package:ffi/ffi.dart'; import 'package:monero/wownero.dart' as wownero; import 'package:monero/src/generated_bindings_wownero.g.dart' as wownero_gen; String getTxKey(String txId) { - return wownero.Wallet_getTxKey(wptr!, txid: txId); + final ret = wownero.Wallet_getTxKey(wptr!, txid: txId); + wownero.Wallet_status(wptr!); + return ret; } wownero.TransactionHistory? txhistory; @@ -86,7 +89,10 @@ Future createTransactionSync( final amt = amount == null ? 0 : wownero.Wallet_amountFromString(amount); final address_ = address.toNativeUtf8(); - final paymentId_ = paymentId.toNativeUtf8(); + final paymentId_ = paymentId.toNativeUtf8(); + if (preferredInputs.isEmpty) { + throw WowneroTransactionCreationException("No inputs provided, transaction cannot be constructed"); + } final preferredInputs_ = preferredInputs.join(wownero.defaultSeparatorStr).toNativeUtf8(); final waddr = wptr!.address; diff --git a/lib/di.dart b/lib/di.dart index facdec912..be014f665 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -746,6 +746,7 @@ Future setup({ _transactionDescriptionBox, getIt.get().wallet!.isHardwareWallet ? getIt.get() : null, coinTypeToSpendFrom: coinTypeToSpendFrom ?? UnspentCoinType.any, + getIt.get(param1: coinTypeToSpendFrom), ), ); diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 69011aa74..69a500c9b 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -19,6 +19,7 @@ import 'package:cake_wallet/tron/tron.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; +import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart'; import 'package:cake_wallet/wownero/wownero.dart'; import 'package:cw_core/exceptions.dart'; import 'package:cw_core/transaction_info.dart'; @@ -64,6 +65,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor wallet.type == WalletType.tron; } + UnspentCoinsListViewModel unspentCoinsListViewModel; + SendViewModelBase( AppStore appStore, this.sendTemplateViewModel, @@ -71,7 +74,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor this.balanceViewModel, this.contactListViewModel, this.transactionDescriptionBox, - this.ledgerViewModel, { + this.ledgerViewModel, + this.unspentCoinsListViewModel, { this.coinTypeToSpendFrom = UnspentCoinType.any, }) : state = InitialExecutionState(), currencies = appStore.wallet!.balance.keys.toList(), @@ -530,6 +534,16 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor throw Exception('Priority is null for wallet type: ${wallet.type}'); } + if (hasCoinControl) { + bool isCoinSelected = false; + for (var coin in unspentCoinsListViewModel.items) { + isCoinSelected = isCoinSelected || (coin.isSending && !coin.isFrozen); + } + if (!isCoinSelected) { + throw Exception("No coin selected in coin control, you need to select a coin in order to spend"); + } + } + switch (wallet.type) { case WalletType.bitcoin: case WalletType.litecoin: From c3978bfbe1f06a3d41c2bc1c8e4a21a3b12c05a0 Mon Sep 17 00:00:00 2001 From: Serhii Date: Wed, 27 Nov 2024 17:42:00 +0200 Subject: [PATCH 22/41] enhance exception handling in cakePay getVendors (#1833) --- lib/cake_pay/cake_pay_api.dart | 3 ++- lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/cake_pay/cake_pay_api.dart b/lib/cake_pay/cake_pay_api.dart index 1f91b338d..a39fbe085 100644 --- a/lib/cake_pay/cake_pay_api.dart +++ b/lib/cake_pay/cake_pay_api.dart @@ -233,7 +233,8 @@ class CakePayApi { var response = await http.get(uri, headers: headers); if (response.statusCode != 200) { - throw Exception(response.body); + throw Exception( + 'Failed to fetch vendors: statusCode - ${response.statusCode}, queryParams -$queryParams, response - ${response.body}'); } final bodyJson = json.decode(response.body); diff --git a/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart index 31eaa23ff..f2958ee31 100644 --- a/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart +++ b/lib/src/screens/cake_pay/cards/cake_pay_cards_page.dart @@ -94,6 +94,10 @@ class CakePayCardsPage extends BasePage { _cardsListViewModel.resetLoadingNextPageState(); _cardsListViewModel.getVendors(); } + + _cardsListViewModel.settingsStore.selectedCakePayCountry = + _cardsListViewModel.selectedCountry; + } }); }); From 125c40b49af4c9eeffe6dd462445bddb185a38e5 Mon Sep 17 00:00:00 2001 From: Serhii Date: Wed, 27 Nov 2024 19:06:28 +0200 Subject: [PATCH 23/41] fix onramper network tag plus UI (#1832) --- lib/buy/onramper/onramper_buy_provider.dart | 3 +++ lib/src/screens/buy/buy_sell_page.dart | 5 +++-- lib/view_model/buy/buy_sell_view_model.dart | 7 ++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/buy/onramper/onramper_buy_provider.dart b/lib/buy/onramper/onramper_buy_provider.dart index e4bf38275..827a5d448 100644 --- a/lib/buy/onramper/onramper_buy_provider.dart +++ b/lib/buy/onramper/onramper_buy_provider.dart @@ -248,9 +248,12 @@ class OnRamperBuyProvider extends BuyProvider { String _tagToNetwork(String tag) { switch (tag) { case 'OMNI': + case 'BSC': return tag; case 'POL': return 'POLYGON'; + case 'ZEC': + return 'ZCASH'; default: try { return CryptoCurrency.fromString(tag).fullName!; diff --git a/lib/src/screens/buy/buy_sell_page.dart b/lib/src/screens/buy/buy_sell_page.dart index d2f16fe3c..945559bb6 100644 --- a/lib/src/screens/buy/buy_sell_page.dart +++ b/lib/src/screens/buy/buy_sell_page.dart @@ -170,8 +170,9 @@ class BuySellPage extends BasePage { }, color: Theme.of(context).primaryColor, textColor: Colors.white, - isDisabled: false, - isLoading: !buySellViewModel.isReadyToTrade)), + isDisabled: buySellViewModel.isBuySellQuotFailed, + isLoading: !buySellViewModel.isReadyToTrade && + !buySellViewModel.isBuySellQuotFailed)), ]), )), )); diff --git a/lib/view_model/buy/buy_sell_view_model.dart b/lib/view_model/buy/buy_sell_view_model.dart index e1c53ee56..4d7151fac 100644 --- a/lib/view_model/buy/buy_sell_view_model.dart +++ b/lib/view_model/buy/buy_sell_view_model.dart @@ -155,13 +155,18 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S final hasSelectedPaymentMethod = selectedPaymentMethod != null; final isPaymentMethodLoaded = paymentMethodState is PaymentMethodLoaded; final isBuySellQuotLoaded = buySellQuotState is BuySellQuotLoaded; + final isBuySellQuotFailed = buySellQuotState is BuySellQuotFailed; return hasSelectedQuote && hasSelectedPaymentMethod && isPaymentMethodLoaded && - isBuySellQuotLoaded; + isBuySellQuotLoaded && + !isBuySellQuotFailed; } + @computed + bool get isBuySellQuotFailed => buySellQuotState is BuySellQuotFailed; + @action void reset() { cryptoCurrency = wallet.currency; From 13c4fbd225a540f82081e38ad7355878646e057c Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Wed, 27 Nov 2024 19:33:53 +0200 Subject: [PATCH 24/41] minor UI change --- lib/src/screens/dashboard/dashboard_page.dart | 2 +- lib/src/screens/dashboard/widgets/action_button.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index cabf73b21..8c236404d 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -285,7 +285,7 @@ class _DashboardPageView extends BasePage { .syncedBackgroundColor, ), child: Container( - padding: EdgeInsets.only(left: 24, right: 32), + padding: EdgeInsets.symmetric(horizontal: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: MainActions.all diff --git a/lib/src/screens/dashboard/widgets/action_button.dart b/lib/src/screens/dashboard/widgets/action_button.dart index 49ebab3cd..21f056c0c 100644 --- a/lib/src/screens/dashboard/widgets/action_button.dart +++ b/lib/src/screens/dashboard/widgets/action_button.dart @@ -50,6 +50,7 @@ class ActionButton extends StatelessWidget { fontSize: 10, color: textColor ?? Theme.of(context).extension()!.cardTextColor), + textAlign: TextAlign.center, ) ], ), From 5ca1c0c56e64f6a3c7ece8d955fab35a5cb19f1d Mon Sep 17 00:00:00 2001 From: Serhii Date: Wed, 27 Nov 2024 23:05:04 +0200 Subject: [PATCH 25/41] Cw 765 onboarding flow improvements (#1817) * update onboarding flow * update welcome subtitle * update wallet title * add create restore wallet subtitles * info button * minor fix [skip ci] * Update text and iconbutton * Cleanup --------- Co-authored-by: tuxpizza --- lib/di.dart | 3 + lib/router.dart | 76 ++--- lib/routes.dart | 2 + .../screens/restore/restore_options_page.dart | 17 +- .../welcome/create_pin_welcome_page.dart | 138 +++++++++ .../screens/welcome/create_welcome_page.dart | 4 - lib/src/screens/welcome/welcome_page.dart | 268 ++++++++++-------- res/values/strings_ar.arb | 7 +- res/values/strings_bg.arb | 7 +- res/values/strings_cs.arb | 7 +- res/values/strings_de.arb | 7 +- res/values/strings_en.arb | 7 +- res/values/strings_es.arb | 7 +- res/values/strings_fr.arb | 7 +- res/values/strings_ha.arb | 7 +- res/values/strings_hi.arb | 7 +- res/values/strings_hr.arb | 7 +- res/values/strings_hy.arb | 7 +- res/values/strings_id.arb | 7 +- res/values/strings_it.arb | 7 +- res/values/strings_ja.arb | 7 +- res/values/strings_ko.arb | 7 +- res/values/strings_my.arb | 7 +- res/values/strings_nl.arb | 7 +- res/values/strings_pl.arb | 7 +- res/values/strings_pt.arb | 7 +- res/values/strings_ru.arb | 7 +- res/values/strings_th.arb | 7 +- res/values/strings_tl.arb | 7 +- res/values/strings_tr.arb | 7 +- res/values/strings_uk.arb | 7 +- res/values/strings_ur.arb | 7 +- res/values/strings_vi.arb | 7 +- res/values/strings_yo.arb | 7 +- res/values/strings_zh.arb | 7 +- 35 files changed, 478 insertions(+), 226 deletions(-) create mode 100644 lib/src/screens/welcome/create_pin_welcome_page.dart delete mode 100644 lib/src/screens/welcome/create_welcome_page.dart diff --git a/lib/di.dart b/lib/di.dart index be014f665..7b1cf3d07 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -42,6 +42,7 @@ import 'package:cake_wallet/src/screens/receive/address_list_page.dart'; import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart'; import 'package:cake_wallet/src/screens/settings/mweb_logs_page.dart'; import 'package:cake_wallet/src/screens/settings/mweb_node_page.dart'; +import 'package:cake_wallet/src/screens/welcome/welcome_page.dart'; import 'package:cake_wallet/view_model/link_view_model.dart'; import 'package:cake_wallet/tron/tron.dart'; import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart'; @@ -1103,6 +1104,8 @@ Future setup({ (onSuccessfulPinSetup, _) => SetupPinCodePage(getIt.get(), onSuccessfulPinSetup: onSuccessfulPinSetup)); + getIt.registerFactory(() => WelcomePage()); + getIt.registerFactory(() => RescanViewModel(getIt.get().wallet!)); getIt.registerFactory(() => RescanPage(getIt.get())); diff --git a/lib/router.dart b/lib/router.dart index 1382da28f..a64369b32 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -105,7 +105,8 @@ import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart'; import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart'; import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart'; import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart'; -import 'package:cake_wallet/src/screens/welcome/create_welcome_page.dart'; +import 'package:cake_wallet/src/screens/welcome/create_pin_welcome_page.dart'; +import 'package:cake_wallet/src/screens/welcome/welcome_page.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart'; @@ -142,36 +143,33 @@ Route createRoute(RouteSettings settings) { switch (settings.name) { case Routes.welcome: - return MaterialPageRoute(builder: (_) => createWelcomePage()); + return MaterialPageRoute(builder: (_) => CreatePinWelcomePage()); - case Routes.newWalletFromWelcome: + case Routes.welcomeWallet: if (SettingsStoreBase.walletPasswordDirectInput) { - if (availableWalletTypes.length == 1) { - return createRoute( - RouteSettings( - name: Routes.newWallet, - arguments: NewWalletArguments(type: availableWalletTypes.first), - ), - ); - } else { - return createRoute(RouteSettings(name: Routes.newWalletType)); - } + return createRoute(RouteSettings(name: Routes.welcomePage)); } - return CupertinoPageRoute( builder: (_) => getIt.get(param1: (PinCodeState context, dynamic _) { - if (availableWalletTypes.length == 1) { - Navigator.of(context.context).pushNamed( - Routes.newWallet, - arguments: NewWalletArguments(type: availableWalletTypes.first), - ); - } else { - Navigator.of(context.context).pushNamed(Routes.newWalletType); - } + Navigator.of(context.context).pushNamed(Routes.welcomePage); }), fullscreenDialog: true); + case Routes.welcomePage: + return CupertinoPageRoute(builder: (_) => getIt.get()); + + case Routes.newWalletFromWelcome: + if (isSingleCoin) { + return createRoute( + RouteSettings( + name: Routes.newWallet, + arguments: NewWalletArguments(type: availableWalletTypes.first) + ), + ); + } + return createRoute(RouteSettings(name: Routes.newWalletType)); + case Routes.newWalletType: return CupertinoPageRoute( builder: (_) => getIt.get( @@ -251,24 +249,10 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get(param1: isNewInstall)); case Routes.restoreWalletFromSeedKeys: - final isNewInstall = settings.arguments as bool; - - if (isNewInstall) { + if (isSingleCoin) { return CupertinoPageRoute( - builder: (_) => getIt.get( - param1: (PinCodeState context, dynamic _) { - if (isSingleCoin) { - return Navigator.of(context.context) - .pushNamed(Routes.restoreWallet, arguments: availableWalletTypes.first); - } - - return Navigator.pushNamed(context.context, Routes.restoreWalletType); - }), - fullscreenDialog: true); - } else if (isSingleCoin) { - return MaterialPageRoute( builder: (_) => getIt.get(param1: availableWalletTypes.first)); - } else { + } return CupertinoPageRoute( builder: (_) => getIt.get( param1: NewWalletTypeArguments( @@ -279,21 +263,8 @@ Route createRoute(RouteSettings settings) { ), ), ); - } case Routes.restoreWalletFromHardwareWallet: - final isNewInstall = settings.arguments as bool; - - if (isNewInstall) { - return CupertinoPageRoute( - builder: (_) => getIt.get( - param1: (PinCodeState context, dynamic _) => - Navigator.of(context.context) - .pushNamed(Routes.restoreWalletFromHardwareWallet, arguments: false), - ), - fullscreenDialog: true, - ); - } if (isSingleCoin) { return MaterialPageRoute( builder: (_) => ConnectDevicePage( @@ -305,7 +276,7 @@ Route createRoute(RouteSettings settings) { ), getIt.get(), )); - } else { + } return CupertinoPageRoute( builder: (_) => getIt.get( param1: NewWalletTypeArguments( @@ -323,7 +294,6 @@ Route createRoute(RouteSettings settings) { ), ), ); - } case Routes.restoreWalletTypeFromQR: return CupertinoPageRoute( diff --git a/lib/routes.dart b/lib/routes.dart index 0b8beb0ea..bea118ae0 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,5 +1,7 @@ class Routes { static const welcome = '/welcome'; + static const welcomeWallet = '/welcome_create_restore_wallet'; + static const welcomePage = '/welcome_page'; static const newWallet = '/new_wallet'; static const setupPin = '/setup_pin_code'; static const newWalletFromWelcome = '/new_wallet_from_welcome'; diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart index d1d419d60..79714aa05 100644 --- a/lib/src/screens/restore/restore_options_page.dart +++ b/lib/src/screens/restore/restore_options_page.dart @@ -85,9 +85,7 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> { key: ValueKey('restore_options_from_seeds_or_keys_button_key'), onPressed: () => Navigator.pushNamed( context, - Routes.restoreWalletFromSeedKeys, - arguments: widget.isNewInstall, - ), + Routes.restoreWalletFromSeedKeys), image: imageSeedKeys, title: S.of(context).restore_title_from_seed_keys, description: S.of(context).restore_description_from_seed_keys, @@ -109,8 +107,7 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> { child: OptionTile( key: ValueKey('restore_options_from_hardware_wallet_button_key'), onPressed: () => Navigator.pushNamed( - context, Routes.restoreWalletFromHardwareWallet, - arguments: widget.isNewInstall), + context, Routes.restoreWalletFromHardwareWallet), image: imageLedger, title: S.of(context).restore_title_from_hardware_wallet, description: S.of(context).restore_description_from_hardware_wallet, @@ -158,15 +155,6 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> { await PermissionHandler.checkPermission(Permission.camera, context); if (!isCameraPermissionGranted) return; - bool isPinSet = false; - if (widget.isNewInstall) { - await Navigator.pushNamed(context, Routes.setupPin, - arguments: (PinCodeState setupPinContext, String _) { - setupPinContext.close(); - isPinSet = true; - }); - } - if (!widget.isNewInstall || isPinSet) { try { if (isRestoring) { return; @@ -188,5 +176,4 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> { _onWalletCreateFailure(context, e.toString()); } } - } } diff --git a/lib/src/screens/welcome/create_pin_welcome_page.dart b/lib/src/screens/welcome/create_pin_welcome_page.dart new file mode 100644 index 000000000..d8ff1578e --- /dev/null +++ b/lib/src/screens/welcome/create_pin_welcome_page.dart @@ -0,0 +1,138 @@ +import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; +import 'package:cake_wallet/themes/theme_base.dart'; +import 'package:cake_wallet/utils/responsive_layout_util.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/routes.dart'; +import 'package:cake_wallet/src/widgets/primary_button.dart'; +import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/wallet_type_utils.dart'; +import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart'; +import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart'; + +class CreatePinWelcomePage extends BasePage { + static const aspectRatioImage = 1.25; + final welcomeImageLight = Image.asset('assets/images/welcome_light.png'); + final welcomeImageDark = Image.asset('assets/images/welcome.png'); + + String appTitle(BuildContext context) { + if (isMoneroOnly) { + return S.of(context).monero_com; + } + + if (isHaven) { + return S.of(context).haven_app; + } + + return S.of(context).cake_wallet; + } + + String appDescription(BuildContext context) { + if (isMoneroOnly) { + return S.of(context).monero_com_wallet_text; + } + + if (isHaven) { + return S.of(context).haven_app_wallet_text; + } + + return S.of(context).new_first_wallet_text; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Theme.of(context).colorScheme.background, + resizeToAvoidBottomInset: false, + body: body(context)); + } + + @override + Widget body(BuildContext context) { + final welcomeImage = currentTheme.type == ThemeType.dark ? welcomeImageDark : welcomeImageLight; + + final newWalletImage = Image.asset('assets/images/new_wallet.png', + height: 12, + width: 12, + color: Theme.of(context).extension()!.restoreWalletButtonTextColor); + + return PopScope( + canPop: false, + child: ScrollableWithBottomSection( + content: Container( + alignment: Alignment.center, + child: ConstrainedBox( + constraints: + BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + SizedBox(height: 70), + AspectRatio( + aspectRatio: aspectRatioImage, + child: FittedBox(child: welcomeImage, fit: BoxFit.contain), + ), + SizedBox(height: 50), + Padding( + padding: EdgeInsets.only(top: 24), + child: Text( + S.of(context).welcome, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + color: Theme.of(context).extension()!.hintTextColor, + ), + textAlign: TextAlign.center, + ), + ), + Padding( + padding: EdgeInsets.only(top: 5), + child: Text( + appTitle(context), + style: TextStyle( + fontSize: 36, + fontWeight: FontWeight.bold, + color: Theme.of(context).extension()!.titleColor, + ), + textAlign: TextAlign.center, + ), + ), + Padding( + padding: EdgeInsets.only(top: 5), + child: Text( + appDescription(context), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).extension()!.hintTextColor, + ), + textAlign: TextAlign.center, + ), + ), + ], + ), + ], + ), + ), + ), + bottomSection: Padding( + padding: EdgeInsets.only(top: 24), + child: PrimaryImageButton( + key: ValueKey('create_pin_welcome_page_create_a_pin_button_key'), + onPressed: () => Navigator.pushNamed(context, Routes.welcomeWallet), + image: newWalletImage, + text: S.current.set_a_pin, + color: Theme.of(context) + .extension()! + .createNewWalletButtonBackgroundColor, + textColor: + Theme.of(context).extension()!.restoreWalletButtonTextColor, + ), + ), + ), + ); + } +} diff --git a/lib/src/screens/welcome/create_welcome_page.dart b/lib/src/screens/welcome/create_welcome_page.dart deleted file mode 100644 index 2d4b3cc28..000000000 --- a/lib/src/screens/welcome/create_welcome_page.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/screens/welcome/welcome_page.dart'; - -Widget createWelcomePage() => WelcomePage(); \ No newline at end of file diff --git a/lib/src/screens/welcome/welcome_page.dart b/lib/src/screens/welcome/welcome_page.dart index 5b7b7f06d..f76c7723a 100644 --- a/lib/src/screens/welcome/welcome_page.dart +++ b/lib/src/screens/welcome/welcome_page.dart @@ -10,42 +10,28 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart'; import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart'; +import 'package:url_launcher/url_launcher.dart'; class WelcomePage extends BasePage { static const aspectRatioImage = 1.25; - final welcomeImageLight = Image.asset('assets/images/welcome_light.png'); - final welcomeImageDark = Image.asset('assets/images/welcome.png'); - - String appTitle(BuildContext context) { - if (isMoneroOnly) { - return S.of(context).monero_com; - } - - if (isHaven) { - return S.of(context).haven_app; - } - - return S.of(context).cake_wallet; - } - - String appDescription(BuildContext context) { - if (isMoneroOnly) { - return S.of(context).monero_com_wallet_text; - } - - if (isHaven) { - return S.of(context).haven_app_wallet_text; - } - - return S.of(context).new_first_wallet_text; - } + final welcomeImageLight = Image.asset('assets/images/wallet_type_light.png'); + final welcomeImageDark = Image.asset('assets/images/wallet_type.png'); @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Theme.of(context).colorScheme.background, - resizeToAvoidBottomInset: false, - body: body(context)); + String? get title => S.current.wallet; + + @override + bool get resizeToAvoidBottomInset => false; + + @override + Widget trailing(BuildContext context) { + final Uri _url = Uri.parse('https://guides.cakewallet.com/docs/basic-features/basic-features/'); + return IconButton( + icon: Icon(Icons.info_outline), + onPressed: () async { + await launchUrl(_url); + }, + ); } @override @@ -59,106 +45,136 @@ class WelcomePage extends BasePage { final restoreWalletImage = Image.asset('assets/images/restore_wallet.png', height: 12, width: 12, color: Theme.of(context).extension()!.titleColor); - return WillPopScope( - onWillPop: () async => false, - child: ScrollableWithBottomSection( - content: Container( - alignment: Alignment.center, - padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24), - child: ConstrainedBox( - constraints: - BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - AspectRatio( - aspectRatio: aspectRatioImage, - child: FittedBox(child: welcomeImage, fit: BoxFit.contain), - ), - Padding( - padding: EdgeInsets.only(top: 24), - child: Text( - S.of(context).welcome, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w500, - color: Theme.of(context).extension()!.hintTextColor, - ), - textAlign: TextAlign.center, - ), - ), - Padding( + return ScrollableWithBottomSection( + content: Container( + alignment: Alignment.center, + padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24), + child: ConstrainedBox( + constraints: + BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + AspectRatio( + aspectRatio: aspectRatioImage, + child: FittedBox(child: welcomeImage, fit: BoxFit.contain), + ), + Padding( + padding: EdgeInsets.only(top: 20), + child: highlightText(context, S.of(context).welcome_subtitle_new_wallet, + S.of(context).create_new)), + SizedBox(height: 10), + Padding( padding: EdgeInsets.only(top: 5), - child: Text( - appTitle(context), - style: TextStyle( - fontSize: 36, - fontWeight: FontWeight.bold, - color: Theme.of(context).extension()!.titleColor, - ), - textAlign: TextAlign.center, - ), - ), - Padding( - padding: EdgeInsets.only(top: 5), - child: Text( - appDescription(context), - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).extension()!.hintTextColor, - ), - textAlign: TextAlign.center, - ), - ), - ], - ), - ], - ), + child: highlightText(context, S.of(context).welcome_subtitle_restore_wallet, + S.of(context).restore_existing_wallet)), + ], + ), + ], ), ), - bottomSection: Column( - children: [ - Text( - S.of(context).please_make_selection, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: Theme.of(context).extension()!.hintTextColor, - ), - textAlign: TextAlign.center, - ), - Padding( - padding: EdgeInsets.only(top: 24), - child: PrimaryImageButton( - key: ValueKey('welcome_page_create_new_wallet_button_key'), - onPressed: () => Navigator.pushNamed(context, Routes.newWalletFromWelcome), - image: newWalletImage, - text: S.of(context).create_new, - color: Theme.of(context) - .extension()! - .createNewWalletButtonBackgroundColor, - textColor: - Theme.of(context).extension()!.restoreWalletButtonTextColor, - ), - ), - Padding( - padding: EdgeInsets.only(top: 10), - child: PrimaryImageButton( + ), + bottomSection: Column( + children: [ + Padding( + padding: EdgeInsets.only(top: 24), + child: PrimaryImageButton( key: ValueKey('welcome_page_restore_wallet_button_key'), - onPressed: () { - Navigator.pushNamed(context, Routes.restoreOptions, arguments: true); - }, - image: restoreWalletImage, - text: S.of(context).restore_wallet, - color: Theme.of(context).cardColor, - textColor: Theme.of(context).extension()!.titleColor), - ) - ], - ), + onPressed: () { + Navigator.pushNamed(context, Routes.restoreOptions, arguments: true); + }, + image: restoreWalletImage, + text: S.of(context).restore_existing_wallet, + color: Theme.of(context).cardColor, + textColor: Theme.of(context).extension()!.titleColor), + ), + Padding( + padding: EdgeInsets.only(top: 10), + child: PrimaryImageButton( + key: ValueKey('welcome_page_create_new_wallet_button_key'), + onPressed: () => Navigator.pushNamed(context, Routes.newWalletFromWelcome), + image: newWalletImage, + text: S.of(context).create_new, + color: Theme.of(context) + .extension()! + .createNewWalletButtonBackgroundColor, + textColor: + Theme.of(context).extension()!.restoreWalletButtonTextColor, + ), + ), + ], ), ); } + + RichText highlightText(BuildContext context, String text, String highlightWord) { + final regex = RegExp(highlightWord, caseSensitive: false); + final matches = regex.allMatches(text); + + if (matches.isEmpty) { + return RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: text, + style: TextStyle( + fontSize: 16, + height: 1.5, + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.secondaryTextColor, + ), + ), + ); + } + + List spans = []; + int lastMatchEnd = 0; + + for (final match in matches) { + final start = match.start; + final end = match.end; + + if (start > lastMatchEnd) { + spans.add(TextSpan( + text: text.substring(lastMatchEnd, start), + style: TextStyle( + fontSize: 16, + height: 1.5, + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.secondaryTextColor, + ), + )); + } + + spans.add(TextSpan( + text: text.substring(start, end), + style: TextStyle( + fontSize: 16, + height: 1.5, + color: Theme.of(context).extension()!.secondaryTextColor, + fontWeight: FontWeight.bold, + ), + )); + + lastMatchEnd = end; + } + + if (lastMatchEnd < text.length) { + spans.add(TextSpan( + text: text.substring(lastMatchEnd), + style: TextStyle( + fontSize: 16, + height: 1.5, + fontWeight: FontWeight.w400, + color: Theme.of(context).extension()!.secondaryTextColor, + ), + )); + } + + return RichText( + textAlign: TextAlign.center, + text: TextSpan(children: spans), + ); + } } diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 9ebab6b6f..25a3d5fa5 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "اختر ممثلًا جديدًا", "nanogpt_subtitle": "جميع النماذج الأحدث (GPT-4 ، Claude). \\ nno اشتراك ، ادفع مع Crypto.", "narrow": "ضيق", - "new_first_wallet_text": "حافظ بسهولة على أمان العملة المشفرة", + "new_first_wallet_text": "الحفاظ على سلامة التشفير الخاص بك هو قطعة من الكعكة", "new_node_testing": "تجربة العقدة الجديدة", "new_subaddress_create": "إنشاء", "new_subaddress_label_name": "تسمية", @@ -570,6 +570,7 @@ "restore_description_from_keys": "قم باستعادة محفظتك من ضغطات المفاتيح المولدة المحفوظة من مفاتيحك الخاصة", "restore_description_from_seed": "قم باستعادة محفظتك من الرمز المكون من 25 كلمة أو 13 كلمة", "restore_description_from_seed_keys": "استرجع محفظتك من السييد / المفاتيح التي قمت بحفظها في مكان آمن", + "restore_existing_wallet": "استعادة محفظة موجودة", "restore_from_date_or_blockheight": "الرجاء إدخال تاريخ قبل إنشاء هذه المحفظة ببضعة أيام. أو إذا كنت تعرف ارتفاع البلوك، فيرجى إدخاله بدلاً من ذلك", "restore_from_seed_placeholder": "الرجاء إدخال أو لصق السييد الخاصة بك هنا", "restore_new_seed": "سييد جديدة", @@ -670,6 +671,7 @@ "sent": "تم الأرسال", "service_health_disabled": "تم تعطيل نشرة صحة الخدمة", "service_health_disabled_message": "هذه هي صفحة نشرة صحة الخدمة ، يمكنك تمكين هذه الصفحة ضمن الإعدادات -> الخصوصية", + "set_a_pin": "تعيين دبوس", "settings": "إعدادات", "settings_all": "الكل", "settings_allow_biometrical_authentication": "السماح بالمصادقة البيومترية", @@ -890,6 +892,7 @@ "view_transaction_on": "عرض العملية على", "voting_weight": "وزن التصويت", "waitFewSecondForTxUpdate": "ﺕﻼﻣﺎﻌﻤﻟﺍ ﻞﺠﺳ ﻲﻓ ﺔﻠﻣﺎﻌﻤﻟﺍ ﺲﻜﻌﻨﺗ ﻰﺘﺣ ﻥﺍﻮﺛ ﻊﻀﺒﻟ ﺭﺎﻈﺘﻧﻻﺍ ﻰﺟﺮﻳ", + "wallet": "محفظة", "wallet_group": "مجموعة محفظة", "wallet_group_description_four": "لإنشاء محفظة مع بذرة جديدة تماما.", "wallet_group_description_one": "في محفظة الكيك ، يمكنك إنشاء ملف", @@ -922,6 +925,8 @@ "wallets": "المحافظ", "warning": "تحذير", "welcome": "مرحبا بك في", + "welcome_subtitle_new_wallet": "إذا كنت ترغب في البدء من جديد ، فانقر فوق إنشاء محفظة جديدة أدناه وستكون خارج السباقات.", + "welcome_subtitle_restore_wallet": "إذا كان لديك محفظة موجودة تريد إحضارها إلى كعكة ، فما عليك سوى اختيار استعادة المحفظة الموجودة وسنمشيك خلال العملية.", "welcome_to_cakepay": "مرحبا بكم في Cake Pay!", "what_is_silent_payments": "ما هي المدفوعات الصامتة؟", "widgets_address": "عنوان", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 91256938d..ef3dc48df 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Изберете нов представител", "nanogpt_subtitle": "Всички най-нови модели (GPT-4, Claude). \\ Nno абонамент, платете с Crypto.", "narrow": "Тесен", - "new_first_wallet_text": "Лесно пазете криптовалутата си в безопасност", + "new_first_wallet_text": "Запазването на криптовалутата ви е парче торта", "new_node_testing": "Тестване на нов node", "new_subaddress_create": "Създаване", "new_subaddress_label_name": "Име на Label", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Възстановяване на портфейл от генерираните от Вашите тайни ключове клавиши", "restore_description_from_seed": "Възстановяване на портфейл от кода от 13 или 25 думи", "restore_description_from_seed_keys": "Възстановете своя портфейл от seed/keys, които сте съхранили на сигурно място", + "restore_existing_wallet": "Възстановете съществуващия портфейл", "restore_from_date_or_blockheight": "Моля, въведете дата няколко дни преди създаването на този портфейл. Ако знаете blockheight-а, въведето него вместо това", "restore_from_seed_placeholder": "Моля, въведете своя seed тук", "restore_new_seed": "Нов seed", @@ -670,6 +671,7 @@ "sent": "Изпратени", "service_health_disabled": "Service Health Bulletin е деактивиран", "service_health_disabled_message": "Това е страницата на Bulletin на Service Health, можете да активирате тази страница в Настройки -> Поверителност", + "set_a_pin": "Поставете щифт", "settings": "Настройки", "settings_all": "Всичко", "settings_allow_biometrical_authentication": "Позволяване на биометрично удостоверяване.", @@ -890,6 +892,7 @@ "view_transaction_on": "Вижте транзакция на ", "voting_weight": "Тегло на гласуване", "waitFewSecondForTxUpdate": "Моля, изчакайте няколко секунди, докато транзакцията се отрази в историята на транзакциите", + "wallet": "Портфейл", "wallet_group": "Група на портфейла", "wallet_group_description_four": "За да създадете портфейл с изцяло ново семе.", "wallet_group_description_one": "В портфейла за торта можете да създадете a", @@ -922,6 +925,8 @@ "wallets": "Портфейли", "warning": "Внимание", "welcome": "Добре дошли в", + "welcome_subtitle_new_wallet": "Ако искате да стартирате свеж, докоснете Създайте нов портфейл по -долу и ще се откажете от състезанията.", + "welcome_subtitle_restore_wallet": "Ако имате съществуващ портфейл, който искате да внесете в тортата, просто изберете възстановяване на съществуващия портфейл и ще ви преведем през процеса.", "welcome_to_cakepay": "Добре дошли в Cake Pay!", "what_is_silent_payments": "Какво са мълчаливи плащания?", "widgets_address": "Адрес", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 0fe38166c..1e8e9eff6 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Vyberte nového zástupce", "nanogpt_subtitle": "Všechny nejnovější modely (GPT-4, Claude). \\ Nno předplatné, plaťte krypto.", "narrow": "Úzký", - "new_first_wallet_text": "Snadno udržujte svou kryptoměnu v bezpečí", + "new_first_wallet_text": "Udržování svého kryptového v bezpečí je kus dortu", "new_node_testing": "Testování nového uzlu", "new_subaddress_create": "Vytvořit", "new_subaddress_label_name": "Popisek", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Obnovte svou peněženku pomocí generovaných stisků kláves uložených z vašich soukromých klíčů", "restore_description_from_seed": "Obnovte svou peněženku pomocí kombinace 25, nebo 13 slov", "restore_description_from_seed_keys": "Obnovte svou peněženku ze seedu/klíčů, které jste si uložili na bezpečném místě", + "restore_existing_wallet": "Obnovte stávající peněženku", "restore_from_date_or_blockheight": "Prosím zadejte datum z doby několik dnů před tím, než jste si zakládali tuto peněženku. Nebo místo toho zadejte výšku bloku, pokud ji znáte.", "restore_from_seed_placeholder": "Prosím zadejte, nebo vložte ze schránky svůj seed.", "restore_new_seed": "Nový seed", @@ -670,6 +671,7 @@ "sent": "Odesláno", "service_health_disabled": "Bulletin zdraví služeb je deaktivován", "service_health_disabled_message": "Toto je stránka Bulletin Service Health Bulletin, můžete tuto stránku povolit v rámci nastavení -> Ochrana osobních údajů", + "set_a_pin": "Nastavte špendlík", "settings": "Nastavení", "settings_all": "VŠE", "settings_allow_biometrical_authentication": "Povolit biometrické ověření", @@ -890,6 +892,7 @@ "view_transaction_on": "Zobrazit transakci na ", "voting_weight": "Hlasová váha", "waitFewSecondForTxUpdate": "Počkejte několik sekund, než se transakce projeví v historii transakcí", + "wallet": "Peněženka", "wallet_group": "Skupina peněženky", "wallet_group_description_four": "Vytvoření peněženky s zcela novým semenem.", "wallet_group_description_one": "V peněžence dortu můžete vytvořit a", @@ -922,6 +925,8 @@ "wallets": "Peněženky", "warning": "Varování", "welcome": "Vítejte v", + "welcome_subtitle_new_wallet": "Pokud chcete začít čerstvě, klepněte na Vytvořit novou peněženku níže a budete na závodech.", + "welcome_subtitle_restore_wallet": "Pokud máte existující peněženku, kterou chcete přinést do dortu, jednoduše si vyberte obnovení stávající peněženky a my vás projdeme procesem.", "welcome_to_cakepay": "Vítejte v Cake Pay!", "what_is_silent_payments": "Co jsou tiché platby?", "widgets_address": "Adresa", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 212ce05f7..871301833 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Wählen Sie einen neuen Vertreter aus", "nanogpt_subtitle": "Alle neuesten Modelle (GPT-4, Claude).", "narrow": "Eng", - "new_first_wallet_text": "Bewahren Sie Ihre Kryptowährung einfach sicher auf", + "new_first_wallet_text": "Wenn Sie Ihren Krypto schützen, ist ein Kinderspiel", "new_node_testing": "Neuen Knoten testen", "new_subaddress_create": "Erstellen", "new_subaddress_label_name": "Bezeichnung", @@ -571,6 +571,7 @@ "restore_description_from_keys": "Stellen Sie Ihr Wallet aus generierten Tastenanschlägen her, die von Ihren privaten Schlüsseln gespeichert wurden", "restore_description_from_seed": "Stellen Sie Ihre Wallet aus den 25 Wörtern oder dem 13-Wort-Kombinationscode wieder her", "restore_description_from_seed_keys": "Stellen Sie Ihr Wallet aus Seed/Schlüsseln wieder her, die Sie sicher aufbewahrt haben", + "restore_existing_wallet": "Bestehende Brieftasche wiederherstellen", "restore_from_date_or_blockheight": "Bitte geben Sie ein Datum ein, das einige Tage vor dem Erstellen dieser Wallet liegt. Oder wenn Sie die Blockhöhe kennen, geben Sie stattdessen diese ein", "restore_from_seed_placeholder": "Seed bitte hier eingeben oder einfügen", "restore_new_seed": "Neuer Seed", @@ -671,6 +672,7 @@ "sent": "Versendet", "service_health_disabled": "Service Health Bulletin ist deaktiviert", "service_health_disabled_message": "Dies ist die Seite \"Service Health Bulletin\", können Sie diese Seite unter Einstellungen -> Privatsphäre aktivieren", + "set_a_pin": "Setzen Sie einen Stift", "settings": "Einstellungen", "settings_all": "ALLE", "settings_allow_biometrical_authentication": "Biometrische Authentifizierung zulassen", @@ -893,6 +895,7 @@ "voting_weight": "Stimmgewicht", "waitFewSecondForTxUpdate": "Bitte warten Sie einige Sekunden, bis die Transaktion im Transaktionsverlauf angezeigt wird", "waiting_payment_confirmation": "Warte auf Zahlungsbestätigung", + "wallet": "Geldbörse", "wallet_group": "Walletgruppe", "wallet_group_description_four": "eine Wallet mit einem völlig neuen Seed schaffen.", "wallet_group_description_one": "In CakeWallet können Sie eine erstellen", @@ -925,6 +928,8 @@ "wallets": "Wallets", "warning": "Warnung", "welcome": "Willkommen bei", + "welcome_subtitle_new_wallet": "Wenn Sie frisch anfangen möchten, tippen Sie unten neue Brieftaschen und Sie werden zu den Rennen gehen.", + "welcome_subtitle_restore_wallet": "Wenn Sie über eine vorhandene Brieftasche verfügen, die Sie in Kuchen bringen möchten, wählen Sie einfach die vorhandene Brieftasche wiederherstellen und wir werden Sie durch den Prozess führen.", "welcome_to_cakepay": "Willkommen bei Cake Pay!", "what_is_silent_payments": "Was sind stille Zahlungen?", "widgets_address": "Adresse", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 15e0c04b3..057bc6d6b 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Pick a new representative", "nanogpt_subtitle": "All the newest models (GPT-4, Claude).\\nNo subscription, pay with crypto.", "narrow": "Narrow", - "new_first_wallet_text": "Keep your crypto safe, piece of cake", + "new_first_wallet_text": "Keeping your crypto safe is a piece of cake", "new_node_testing": "New node testing", "new_subaddress_create": "Create", "new_subaddress_label_name": "Label name", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Restore your wallet from generated keystrokes saved from your private keys", "restore_description_from_seed": "Restore your wallet from either the 25 word or 13 word combination code", "restore_description_from_seed_keys": "Get back your wallet from seed/keys that you've saved to secure place", + "restore_existing_wallet": "Restore Existing Wallet", "restore_from_date_or_blockheight": "Please enter a date a few days before you created this wallet. Or if you know the blockheight, please enter it instead", "restore_from_seed_placeholder": "Please enter or paste your seed here", "restore_new_seed": "New seed", @@ -670,6 +671,7 @@ "sent": "Sent", "service_health_disabled": "Service Health Bulletin is disabled", "service_health_disabled_message": "This is the service health bulletin page, you can enable this page under Settings -> Privacy", + "set_a_pin": "Set a PIN", "settings": "Settings", "settings_all": "ALL", "settings_allow_biometrical_authentication": "Allow biometrical authentication", @@ -890,6 +892,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "Voting Weight", "waitFewSecondForTxUpdate": "Kindly wait for a few seconds for transaction to reflect in transactions history", + "wallet": "Wallet", "wallet_group": "Wallet Group", "wallet_group_description_four": "to create a wallet with an entirely new seed.", "wallet_group_description_one": "In Cake Wallet, you can create a", @@ -922,6 +925,8 @@ "wallets": "Wallets", "warning": "Warning", "welcome": "Welcome to", + "welcome_subtitle_new_wallet": "If you want to start fresh, tap Create New Wallet below and you'll be off to the races.", + "welcome_subtitle_restore_wallet": "If you have an existing wallet you want to bring into Cake, simply choose Restore Existing Wallet and we'll walk you through the process.", "welcome_to_cakepay": "Welcome to Cake Pay!", "what_is_silent_payments": "What are Silent Payments?", "widgets_address": "Address", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 83c0a09f0..c9135f054 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Elija un nuevo representante", "nanogpt_subtitle": "Todos los modelos más nuevos (GPT-4, Claude). \\nSin suscripción, pague con cripto.", "narrow": "Angosto", - "new_first_wallet_text": "Mantén fácilmente tu criptomoneda segura", + "new_first_wallet_text": "Mantener su criptografía a salvo es un pedazo de pastel", "new_node_testing": "Prueba nuevos nodos", "new_subaddress_create": "Crear", "new_subaddress_label_name": "Nombre de etiqueta", @@ -571,6 +571,7 @@ "restore_description_from_keys": "Restaure su billetera de las pulsaciones de teclas generadas guardadas de sus claves privadas", "restore_description_from_seed": "Restaure su billetera desde el código de combinación de 25 palabras i de 13 palabras", "restore_description_from_seed_keys": "Recupere su billetera de las semillas/claves que ha guardado en un lugar seguro", + "restore_existing_wallet": "Restaurar la billetera existente", "restore_from_date_or_blockheight": "Ingrese una fecha unos días antes de crear esta billetera. O si conoce la altura del bloque, ingréselo en su lugar", "restore_from_seed_placeholder": "Ingrese o pegue su frase de código aquí", "restore_new_seed": "Nueva semilla", @@ -671,6 +672,7 @@ "sent": "Expedido", "service_health_disabled": "El boletín de salud del servicio está deshabilitado", "service_health_disabled_message": "Esta es la página del Boletín de Salud del Servicio, puede habilitar esta página en Configuración -> Privacidad", + "set_a_pin": "Establecer un alfiler", "settings": "Configuraciones", "settings_all": "TODOS", "settings_allow_biometrical_authentication": "Permitir autenticación biométrica", @@ -891,6 +893,7 @@ "view_transaction_on": "Ver transacción en ", "voting_weight": "Peso de votación", "waitFewSecondForTxUpdate": "Espera unos segundos para que la transacción se refleje en el historial de transacciones.", + "wallet": "Billetera", "wallet_group": "Grupo de billetera", "wallet_group_description_four": "Para crear una billetera con una semilla completamente nueva.", "wallet_group_description_one": "En la billetera de pastel, puedes crear un", @@ -923,6 +926,8 @@ "wallets": "Carteras", "warning": "Advertencia", "welcome": "Bienvenido", + "welcome_subtitle_new_wallet": "Si desea comenzar de nuevo, toque Crear nueva billetera a continuación y se irá a las carreras.", + "welcome_subtitle_restore_wallet": "Si tiene una billetera existente que desea llevar al pastel, simplemente elija Restaurar la billetera existente y lo guiaremos a través del proceso.", "welcome_to_cakepay": "¡Bienvenido a Cake Pay!", "what_is_silent_payments": "¿Qué son los pagos silenciosos?", "widgets_address": "Dirección", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 741adc472..eaeac58a9 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Choisissez un nouveau représentant", "nanogpt_subtitle": "Tous les modèles les plus récents (GPT-4, Claude). \\ NNO abonnement, payez avec crypto.", "narrow": "Étroit", - "new_first_wallet_text": "Gardez facilement votre crypto-monnaie en sécurité", + "new_first_wallet_text": "Garder votre crypto en sécurité est un morceau de gâteau", "new_node_testing": "Test du nouveau nœud", "new_subaddress_create": "Créer", "new_subaddress_label_name": "Nom", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Restaurer votre portefeuille (wallet) d'après les séquences de touches générées d'après vos clefs privées", "restore_description_from_seed": "Restaurer votre portefeuille (wallet) depuis une phrase secrète (seed) de 25 ou 13 mots", "restore_description_from_seed_keys": "Restaurez votre portefeuille (wallet) depuis une phrase secrète (seed) ou des clefs que vous avez stockées en lieu sûr", + "restore_existing_wallet": "Restaurer le portefeuille existant", "restore_from_date_or_blockheight": "Merci d'entrer une date antérieure de quelques jours à la date de création de votre portefeuille (wallet). Ou si vous connaissez la hauteur de bloc, merci de la spécifier plutôt qu'une date", "restore_from_seed_placeholder": "Merci d'entrer ou de coller votre phrase secrète (seed) ici", "restore_new_seed": "Nouvelle phrase secrète (seed)", @@ -670,6 +671,7 @@ "sent": "Envoyés", "service_health_disabled": "Le bulletin de santé du service est handicapé", "service_health_disabled_message": "Ceci est la page du Bulletin de santé du service, vous pouvez activer cette page sous Paramètres -> Confidentialité", + "set_a_pin": "Régler une goupille", "settings": "Paramètres", "settings_all": "TOUT", "settings_allow_biometrical_authentication": "Autoriser l'authentification biométrique", @@ -890,6 +892,7 @@ "view_transaction_on": "Voir la Transaction sur ", "voting_weight": "Poids de vote", "waitFewSecondForTxUpdate": "Veuillez attendre quelques secondes pour que la transaction soit reflétée dans l'historique des transactions.", + "wallet": "Portefeuille", "wallet_group": "Groupe de portefeuille", "wallet_group_description_four": "Pour créer un portefeuille avec une graine entièrement nouvelle.", "wallet_group_description_one": "Dans Cake Wallet, vous pouvez créer un", @@ -922,6 +925,8 @@ "wallets": "Portefeuilles", "warning": "Avertissement", "welcome": "Bienvenue sur", + "welcome_subtitle_new_wallet": "Si vous souhaitez recommencer à créer un nouveau portefeuille ci-dessous et vous serez parti pour les courses.", + "welcome_subtitle_restore_wallet": "Si vous avez un portefeuille existant que vous souhaitez apporter dans le gâteau, choisissez simplement restaurer le portefeuille existant et nous vous guiderons tout au long du processus.", "welcome_to_cakepay": "Bienvenue sur Cake Pay !", "what_is_silent_payments": "Qu'est-ce que les paiements silencieux?", "widgets_address": "Adresse", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 222a9cf2f..6a0713d6d 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Dauki sabon wakili", "nanogpt_subtitle": "Duk sabbin samfuran (GPT-4, CLODE). \\ NNO biyan kuɗi, biya tare da crypto.", "narrow": "kunkuntar", - "new_first_wallet_text": "A sauƙaƙe kiyaye kuzarin ku", + "new_first_wallet_text": "Tsayawa kayatar da lafiya", "new_node_testing": "Sabbin gwajin kumburi", "new_subaddress_create": "Ƙirƙiri", "new_subaddress_label_name": "Lakabin suna", @@ -572,6 +572,7 @@ "restore_description_from_keys": "Maido da walat ɗin ku daga maɓallan maɓalli da aka ƙera da aka ajiye daga maɓallan ku na sirri", "restore_description_from_seed": "Dawo da kwalinku daga 25 ko 13 lambar haɗin kalma", "restore_description_from_seed_keys": "Maido da walat ɗin ku daga iri/maɓallan da kuka adana don amintaccen wuri", + "restore_existing_wallet": "Dawo da walat ɗin da yake", "restore_from_date_or_blockheight": "Don Allah shigar da wata kwanan a kafin ku ƙirƙirar wannan kwalinku. Ko idan kun san blockheight, don Allah shigar da shi", "restore_from_seed_placeholder": "Da fatan za a shigar da ko manna maɓallin ku a nan", "restore_new_seed": "Sabon iri", @@ -672,6 +673,7 @@ "sent": "Aika", "service_health_disabled": "Ba a kashe Bayar da Kiwon Lafiya", "service_health_disabled_message": "Wannan shafin yanar gizo mai kula da sabis ne, zaka iya kunna wannan shafin a karkashin saiti -> Sirri", + "set_a_pin": "Saita PIN", "settings": "Saiti", "settings_all": "DUK", "settings_allow_biometrical_authentication": "Bada izinin tantance sawun yatsa", @@ -892,6 +894,7 @@ "view_transaction_on": "Dubo aikace-aikacen akan", "voting_weight": "Nauyi mai nauyi", "waitFewSecondForTxUpdate": "Da fatan za a jira ƴan daƙiƙa don ciniki don yin tunani a tarihin ma'amala", + "wallet": "Zabira", "wallet_group": "Wallet kungiyar", "wallet_group_description_four": "Don ƙirƙirar walat tare da sabon iri.", "wallet_group_description_one": "A cikin walat walat, zaka iya ƙirƙirar", @@ -924,6 +927,8 @@ "wallets": "Wallets", "warning": "Gargadi", "welcome": "Barka da zuwa", + "welcome_subtitle_new_wallet": "Idan kana son farawa sabo ne, matsa Newirƙiri Sabuwar Wallow a ƙasa kuma za ka tafi da tsere.", + "welcome_subtitle_restore_wallet": "Idan kuna da walat ɗin da kuke son shigo da cake, kawai zaɓi a cikin walat ɗin da yake ciki kuma za mu bi ku ta hanyar aiwatarwa.", "welcome_to_cakepay": "Barka da zuwa Cake Pay!", "what_is_silent_payments": "Menene biyan shiru?", "widgets_address": "Adireshin", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 1b2f3a1b3..f1e294d22 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "एक नया प्रतिनिधि चुनें", "nanogpt_subtitle": "सभी नवीनतम मॉडल (GPT-4, क्लाउड)। \\ nno सदस्यता, क्रिप्टो के साथ भुगतान करें।", "narrow": "सँकरा", - "new_first_wallet_text": "आसानी से अपनी क्रिप्टोक्यूरेंसी को सुरक्षित रखें", + "new_first_wallet_text": "अपने क्रिप्टो को सुरक्षित रखना केक का एक टुकड़ा है", "new_node_testing": "नई नोड परीक्षण", "new_subaddress_create": "सर्जन करना", "new_subaddress_label_name": "लेबल का नाम", @@ -572,6 +572,7 @@ "restore_description_from_keys": "अपने वॉलेट को जेनरेट से पुनर्स्थापित करें आपकी निजी कुंजी से कीस्ट्रोक्स सहेजे गए", "restore_description_from_seed": "या तो 25 शब्द से अपने वॉलेट को पुनर्स्थापित करें या 13 शब्द संयोजन कोड", "restore_description_from_seed_keys": "अपने बटुए को बीज से वापस लें/वे कुंजियाँ जिन्हें आपने सुरक्षित स्थान पर सहेजा है", + "restore_existing_wallet": "मौजूदा बटुए को पुनर्स्थापित करें", "restore_from_date_or_blockheight": "कृपया इस वॉलेट को बनाने से कुछ दिन पहले एक तारीख दर्ज करें। या यदि आप ब्लॉकचेट जानते हैं, तो कृपया इसके बजाय इसे दर्ज करें", "restore_from_seed_placeholder": "कृपया अपना कोड वाक्यांश यहां दर्ज करें या पेस्ट करें", "restore_new_seed": "नया बीज", @@ -672,6 +673,7 @@ "sent": "भेज दिया", "service_health_disabled": "सेवा स्वास्थ्य बुलेटिन अक्षम है", "service_health_disabled_message": "यह सेवा स्वास्थ्य बुलेटिन पृष्ठ है, आप इस पृष्ठ को सेटिंग्स के तहत सक्षम कर सकते हैं -> गोपनीयता", + "set_a_pin": "एक पिन सेट करना", "settings": "समायोजन", "settings_all": "सब", "settings_allow_biometrical_authentication": "बायोमेट्रिक प्रमाणीकरण की अनुमति दें", @@ -892,6 +894,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "वोटिंग वेट", "waitFewSecondForTxUpdate": "लेन-देन इतिहास में लेन-देन प्रतिबिंबित होने के लिए कृपया कुछ सेकंड प्रतीक्षा करें", + "wallet": "बटुआ", "wallet_group": "बटुए समूह", "wallet_group_description_four": "एक पूरी तरह से नए बीज के साथ एक बटुआ बनाने के लिए।", "wallet_group_description_one": "केक बटुए में, आप एक बना सकते हैं", @@ -924,6 +927,8 @@ "wallets": "पर्स", "warning": "चेतावनी", "welcome": "स्वागत हे सेवा मेरे", + "welcome_subtitle_new_wallet": "यदि आप ताजा शुरू करना चाहते हैं, तो नीचे नया बटुआ बनाएं और आप दौड़ से दूर हो जाएंगे।", + "welcome_subtitle_restore_wallet": "यदि आपके पास एक मौजूदा बटुआ है जिसे आप केक में लाना चाहते हैं, तो बस मौजूदा बटुए को पुनर्स्थापित करें और हम आपको प्रक्रिया के माध्यम से चलेंगे।", "welcome_to_cakepay": "केकपे में आपका स्वागत है!", "what_is_silent_payments": "मूक भुगतान क्या है?", "widgets_address": "पता", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 4e106fdf6..6b9f20259 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Odaberite novog predstavnika", "nanogpt_subtitle": "Svi najnoviji modeli (GPT-4, Claude). \\ NNO pretplata, plaćajte kripto.", "narrow": "Usko", - "new_first_wallet_text": "Jednostavno čuvajte svoju kripto valutu", + "new_first_wallet_text": "Čuvanje kriptovaluta je komad torte", "new_node_testing": "Provjera novog nodea", "new_subaddress_create": "Izradi", "new_subaddress_label_name": "Oznaka", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Oporavi novčanik pomoću generiranih pritisaka na tipke spremljenih od vlastitih privatnih ključeva (keys)", "restore_description_from_seed": "Oporavi novčanik pomoću koda koji sadrži kombinaciju od 25 ili 13 riječi", "restore_description_from_seed_keys": "Oporavi novčanik pomoću pristupnog izraza/ključa spremljenog na sigurno mjesto", + "restore_existing_wallet": "Vratite postojeći novčanik", "restore_from_date_or_blockheight": "Molimo unesite datum od nekoliko dana prije nego što ste izradili ovaj novčanik ili ako znate visinu bloka, molimo unesite je.", "restore_from_seed_placeholder": "Molimo unesite ili zalijepite svoj pristupni izraz ovdje", "restore_new_seed": "Novi pristupi izraz", @@ -670,6 +671,7 @@ "sent": "Poslano", "service_health_disabled": "Zdravstveni bilten usluge je onemogućen", "service_health_disabled_message": "Ovo je stranica zdravstvenog biltena o usluzi, možete omogućiti ovu stranicu pod postavkama -> privatnost", + "set_a_pin": "Postavite pin", "settings": "Postavke", "settings_all": "SVE", "settings_allow_biometrical_authentication": "Dopusti biometrijsku autentifikaciju", @@ -890,6 +892,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "Težina glasanja", "waitFewSecondForTxUpdate": "Pričekajte nekoliko sekundi da se transakcija prikaže u povijesti transakcija", + "wallet": "Novčanik", "wallet_group": "Skupina novčanika", "wallet_group_description_four": "Da biste stvorili novčanik s potpuno novim sjemenom.", "wallet_group_description_one": "U novčaniku kolača možete stvoriti a", @@ -922,6 +925,8 @@ "wallets": "Novčanici", "warning": "Upozorenje", "welcome": "Dobrodošli na", + "welcome_subtitle_new_wallet": "Ako želite započeti svježe, dodirnite Create New Wallet u nastavku i krenite na utrke.", + "welcome_subtitle_restore_wallet": "Ako imate postojeći novčanik koji želite unijeti u tortu, jednostavno odaberite Vratite postojeći novčanik i prošetat ćemo vas kroz postupak.", "welcome_to_cakepay": "Dobro došli u Cake Pay!", "what_is_silent_payments": "Što je tiha plaćanja?", "widgets_address": "Adresa", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 40142ca5b..d3d7987d2 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Ընտրեք նոր ներկայացուցիչ", "nanogpt_subtitle": "Բոլոր ամենանոր մոդելներ (GPT-4, Claude).\\nԱռանց բաժանորդագրության, վճարեք կրիպտոարժույթով", "narrow": "Նեղ", - "new_first_wallet_text": "Ինչպես պահել ձեր կրիպտոգրաֆիան անվտանգ, կարկանդակ", + "new_first_wallet_text": "Ձեր ծպտյալ անվտանգ պահելը տորթի մի կտոր է", "new_node_testing": "Նոր հանգույցի փորձարկում", "new_subaddress_create": "Ստեղծել", "new_subaddress_label_name": "Պիտակի անուն", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Վերականգնեք ձեր դրամապանակը ձեր գախտնի բանալիների հիման վրա ստեղծված մուտքագրումներից", "restore_description_from_seed": "Վերականգնեք ձեր դրամապպանակը 25 բառերի կամ 13 բառերի համադրությամբ", "restore_description_from_seed_keys": "Վերականգնեք ձեր դրամապանակը սերմից/բանալիներից, որը դուք պահպանել եք ապահով վայրում", + "restore_existing_wallet": "Վերականգնել առկա դրամապանակը", "restore_from_date_or_blockheight": "Խնդրում ենք մուտքագրել այն ամսաթիվը, երբ դուք ստեղծել եք այս դրամապանակը։ Կամ, եթե դուք գիտեք բլոկի բարձրությունը, խնդրում ենք մուտքագրել այն", "restore_from_seed_placeholder": "Խնդրում ենք մուտքագրել կամ տեղադրել ձեր սերմը այստեղ", "restore_new_seed": "Նոր սերմ", @@ -670,6 +671,7 @@ "sent": "Ուղարկված", "service_health_disabled": "Ծառայության առողջությունը անջատված է", "service_health_disabled_message": "Սա ծառայության առողջության էջն է, դուք կարող եք այս էջը միացնել Կարգավորումներ -> Գաղտնիություն", + "set_a_pin": "Սեփական քորոց սահմանեք", "settings": "Կարգավորումներ", "settings_all": "Բոլորը", "settings_allow_biometrical_authentication": "Թույլատրել կենսաչափական վավերացում", @@ -890,6 +892,7 @@ "view_transaction_on": "Դիտել Գործարքը ", "voting_weight": "Քվեարկության Քաշ", "waitFewSecondForTxUpdate": "Խնդրում ենք սպասել մի քանի վայրկյան, որպեսզի գործարքը արտացոլվի գործարքների պատմության մեջ", + "wallet": "Դրամապանակ", "wallet_group": "Դրամապանակների խումբ", "wallet_group_description_four": "Ամբողջովին նոր սերմով դրամապանակ ստեղծելու համար:", "wallet_group_description_one": "Տորթի դրամապանակում կարող եք ստեղծել ա", @@ -922,6 +925,8 @@ "wallets": "Դրամապանակներ", "warning": "Զգուշացում", "welcome": "Բարի գալուստ", + "welcome_subtitle_new_wallet": "Եթե ​​ցանկանում եք սկսել թարմ, հպեք Ստեղծեք նոր դրամապանակ ներքեւում եւ դուրս կգաք ցեղերի:", + "welcome_subtitle_restore_wallet": "Եթե ​​ունեք գոյություն ունեցող դրամապանակ, որը ցանկանում եք տորթի մեջ մտցնել, պարզապես ընտրեք վերականգնել առկա դրամապանակը, եւ մենք ձեզ քայլելու ենք գործընթացի միջոցով:", "welcome_to_cakepay": "Բարի գալուստ Cake Pay!", "what_is_silent_payments": "Ի՞նչ է Լուռ Վճարումները:", "widgets_address": "Հասցե", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 04336b76e..fae208549 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Pilih perwakilan baru", "nanogpt_subtitle": "Semua model terbaru (GPT-4, Claude). \\ Nno langganan, bayar dengan crypto.", "narrow": "Sempit", - "new_first_wallet_text": "Dengan mudah menjaga cryptocurrency Anda aman", + "new_first_wallet_text": "Menjaga crypto Anda aman adalah sepotong kue", "new_node_testing": "Pengujian node baru", "new_subaddress_create": "Buat", "new_subaddress_label_name": "Nama label", @@ -572,6 +572,7 @@ "restore_description_from_keys": "Pulihkan dompet Anda dari tombol yang dihasilkan yang disimpan dari kunci pribadi Anda", "restore_description_from_seed": "Pulihkan dompet Anda dari kombinasi kode 25 atau 13 kata", "restore_description_from_seed_keys": "Dapatkan kembali dompet Anda dari seed/kunci yang Anda simpan di tempat yang aman", + "restore_existing_wallet": "Kembalikan dompet yang ada", "restore_from_date_atau_blockheight": "Silakan masukkan tanggal beberapa hari sebelum Anda membuat dompet ini. Atau jika Anda tahu blockheight, silakan masukkannya sebagai gantinya", "restore_from_date_or_blockheight": "Harap masukkan tanggal beberapa hari sebelum Anda membuat dompet ini. Atau jika Anda tahu blockheight, silakan masukkan sebagai gantinya", "restore_from_seed_placeholder": "Silakan masukkan atau tempel seed Anda di sini", @@ -673,6 +674,7 @@ "sent": "Dikirim", "service_health_disabled": "Buletin Kesehatan Layanan dinonaktifkan", "service_health_disabled_message": "Ini adalah halaman Buletin Kesehatan Layanan, Anda dapat mengaktifkan halaman ini di bawah Pengaturan -> Privasi", + "set_a_pin": "Atur pin", "settings": "Pengaturan", "settings_all": "SEMUA", "settings_allow_biometrical_authentication": "Izinkan otentikasi biometrik", @@ -893,6 +895,7 @@ "view_transaction_on": "Lihat Transaksi di ", "voting_weight": "Berat voting", "waitFewSecondForTxUpdate": "Mohon tunggu beberapa detik hingga transaksi terlihat di riwayat transaksi", + "wallet": "Dompet", "wallet_group": "Kelompok dompet", "wallet_group_description_four": "Untuk membuat dompet dengan benih yang sama sekali baru.", "wallet_group_description_one": "Di dompet kue, Anda dapat membuat file", @@ -925,6 +928,8 @@ "wallets": "Dompet", "warning": "Peringatan", "welcome": "Selamat datang di", + "welcome_subtitle_new_wallet": "Jika Anda ingin memulai segar, ketuk membuat dompet baru di bawah ini dan Anda akan pergi ke balapan.", + "welcome_subtitle_restore_wallet": "Jika Anda memiliki dompet yang ada yang ingin Anda bawa ke dalam kue, cukup pilih kembalikan dompet yang ada dan kami akan memandu Anda melalui prosesnya.", "welcome_to_cakepay": "Selamat Datang di Cake Pay!", "what_is_silent_payments": "Apa itu pembayaran diam?", "widgets_address": "Alamat", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index ad15ab3a9..e6e4928c5 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -428,7 +428,7 @@ "nano_pick_new_rep": "Scegli un nuovo rappresentante", "nanogpt_subtitle": "Tutti i modelli più recenti (GPT-4, Claude). Abbonamento nno, paga con cripto.", "narrow": "Stretto", - "new_first_wallet_text": "Mantieni facilmente la tua criptovaluta al sicuro", + "new_first_wallet_text": "Mantenere la tua criptovaluta è un pezzo di torta", "new_node_testing": "Test novo nodo", "new_subaddress_create": "Crea", "new_subaddress_label_name": "Nome etichetta", @@ -572,6 +572,7 @@ "restore_description_from_keys": "Recupera il tuo portafoglio da una sequenza di caratteri generati dalle tue chiavi private", "restore_description_from_seed": "Recupera il tuo portafoglio da una combinazione di 25 o 13 parole", "restore_description_from_seed_keys": "Recupera il tuo portafoglio dal seme/chiavi che hai salvato in un posto sicuro", + "restore_existing_wallet": "Ripristina il portafoglio esistente", "restore_from_date_or_blockheight": "Gentilmente inserisci la data di un paio di giorni prima che hai creato questo portafoglio. Oppure inserisci l'altezza del blocco se la conosci", "restore_from_seed_placeholder": "Gentilmente inserisci o incolla il tuo seme qui", "restore_new_seed": "Nuovo seme", @@ -672,6 +673,7 @@ "sent": "Inviato", "service_health_disabled": "Il Bollettino sanitario di servizio è disabilitato", "service_health_disabled_message": "Questa è la pagina del Bollettino sanitario del servizio, è possibile abilitare questa pagina in Impostazioni -> Privacy", + "set_a_pin": "Imposta un pin", "settings": "Impostazioni", "settings_all": "TUTTO", "settings_allow_biometrical_authentication": "Consenti autenticazione biometrica", @@ -893,6 +895,7 @@ "voting_weight": "Peso di voto", "waitFewSecondForTxUpdate": "Attendi qualche secondo affinché la transazione venga riflessa nella cronologia delle transazioni", "waiting_payment_confirmation": "In attesa di conferma del pagamento", + "wallet": "Portafoglio", "wallet_group": "Gruppo di portafoglio", "wallet_group_description_four": "Per creare un portafoglio con un seme completamente nuovo.", "wallet_group_description_one": "Nel portafoglio di torte, puoi creare un", @@ -925,6 +928,8 @@ "wallets": "Portafogli", "warning": "Avvertimento", "welcome": "Benvenuto", + "welcome_subtitle_new_wallet": "Se vuoi ricominciare da capo, tocca Crea un nuovo portafoglio di seguito e sarai alle gare.", + "welcome_subtitle_restore_wallet": "Se hai un portafoglio esistente che vuoi portare nella torta, scegli semplicemente il ripristino del portafoglio esistente e ti guideremo attraverso il processo.", "welcome_to_cakepay": "Benvenuto in Cake Pay!", "what_is_silent_payments": "Che cos'è i pagamenti silenziosi?", "widgets_address": "Indirizzo", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 520a73ade..fd4d83cc8 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -428,7 +428,7 @@ "nano_pick_new_rep": "新しい代表者を選びます", "nanogpt_subtitle": "すべての最新モデル(GPT-4、Claude)。\\ nnoサブスクリプション、暗号で支払います。", "narrow": "狭い", - "new_first_wallet_text": "暗号通貨を簡単に安全に保ちます", + "new_first_wallet_text": "暗号を安全に保つことはケーキです", "new_node_testing": "新しいノードのテスト", "new_subaddress_create": "作成する", "new_subaddress_label_name": "ラベル名", @@ -571,6 +571,7 @@ "restore_description_from_keys": "生成されたウォレットを復元します秘密鍵から保存されたキーストローク", "restore_description_from_seed": "25ワードからウォレットを復元しますまたは13ワードの組み合わせコード", "restore_description_from_seed_keys": "安全な場所に保存したシード/キーから財布を取り戻す", + "restore_existing_wallet": "既存のウォレットを復元します", "restore_from_date_or_blockheight": "このウォレットを作成する数日前に日付を入力してください。 または、ブロックの高さがわかっている場合は、代わりに入力してください", "restore_from_seed_placeholder": "ここにコードフレーズを入力または貼り付けてください", "restore_new_seed": "新しい種", @@ -671,6 +672,7 @@ "sent": "送信済み", "service_health_disabled": "サービスヘルス速報は無効です", "service_health_disabled_message": "これはService Health Bulletinページです。設定の下でこのページを有効にすることができます - >プライバシー", + "set_a_pin": "ピンを設定します", "settings": "設定", "settings_all": "すべて", "settings_allow_biometrical_authentication": "生体認証を許可する", @@ -891,6 +893,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "投票重み", "waitFewSecondForTxUpdate": "取引履歴に取引が反映されるまで数秒お待ちください。", + "wallet": "財布", "wallet_group": "ウォレットグループ", "wallet_group_description_four": "まったく新しい種子の財布を作成します。", "wallet_group_description_one": "ケーキウォレットでは、aを作成できます", @@ -923,6 +926,8 @@ "wallets": "財布", "warning": "警告", "welcome": "ようこそ に", + "welcome_subtitle_new_wallet": "新鮮な開始したい場合は、以下の新しい財布を作成すると、レースに出かけることができます。", + "welcome_subtitle_restore_wallet": "ケーキに持ち込みたい既存のウォレットがある場合は、既存のウォレットを復元するだけで、プロセスを説明します。", "welcome_to_cakepay": "Cake Payへようこそ!", "what_is_silent_payments": "サイレント支払いとは何ですか?", "widgets_address": "住所", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 1d9748866..6fce665ec 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "새로운 담당자를 선택하십시오", "nanogpt_subtitle": "모든 최신 모델 (GPT-4, Claude). \\ nno 구독, Crypto로 지불하십시오.", "narrow": "좁은", - "new_first_wallet_text": "cryptocurrency를 쉽게 안전하게 유지하십시오", + "new_first_wallet_text": "암호화를 안전하게 유지하는 것은 케이크 조각입니다", "new_node_testing": "새로운 노드 테스트", "new_subaddress_create": "몹시 떠들어 대다", "new_subaddress_label_name": "라벨 이름", @@ -571,6 +571,7 @@ "restore_description_from_keys": "개인 키에서 저장된 생성 된 키 스트로크에서 월렛 복원", "restore_description_from_seed": "25 단어 또는 13 단어 조합 코드에서 지갑을 복원하십시오.", "restore_description_from_seed_keys": "안전한 장소에 저장 한 종자 / 키로 지갑을 되 찾으십시오.", + "restore_existing_wallet": "기존 지갑을 복원하십시오", "restore_from_date_or_blockheight": "이 지갑을 생성하기 며칠 전에 날짜를 입력하십시오. 또는 블록 높이를 알고있는 경우 대신 입력하십시오.", "restore_from_seed_placeholder": "여기에 코드 문구를 입력하거나 붙여 넣으십시오.", "restore_new_seed": "새로운 씨앗", @@ -671,6 +672,7 @@ "sent": "보냄", "service_health_disabled": "서비스 건강 게시판이 장애가되었습니다", "service_health_disabled_message": "이것은 서비스 건강 게시판 페이지입니다. 설정 에서이 페이지를 활성화 할 수 있습니다 -> 개인 정보", + "set_a_pin": "핀을 설정하십시오", "settings": "설정", "settings_all": "모든", "settings_allow_biometrical_authentication": "생체 인증 허용", @@ -891,6 +893,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "투표 중량", "waitFewSecondForTxUpdate": "거래 내역에 거래가 반영될 때까지 몇 초 정도 기다려 주세요.", + "wallet": "지갑", "wallet_group": "지갑 그룹", "wallet_group_description_four": "완전히 새로운 씨앗으로 지갑을 만듭니다.", "wallet_group_description_one": "케이크 지갑에서는 a를 만들 수 있습니다", @@ -923,6 +926,8 @@ "wallets": "지갑", "warning": "경고", "welcome": "환영 에", + "welcome_subtitle_new_wallet": "신선하게 시작하려면 아래에서 새 지갑을 만들면 레이스로 떠날 것입니다.", + "welcome_subtitle_restore_wallet": "케이크에 가져 오려는 기존 지갑이 있다면 기존 지갑 복원을 선택하면 프로세스를 안내해 드리겠습니다.", "welcome_to_cakepay": "Cake Pay에 오신 것을 환영합니다!", "what_is_silent_payments": "조용한 지불이란 무엇입니까?", "widgets_address": "주소", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index e6be67060..e933010fd 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "အသစ်တစ်ခုကိုရွေးပါ", "nanogpt_subtitle": "အားလုံးနောက်ဆုံးပေါ်မော်ဒယ်များ (GPT-4, Claude) ။ \\ nno subscription, crypto နှင့်အတူပေးဆောင်။", "narrow": "ကျဉ်းသော", - "new_first_wallet_text": "သင့်ရဲ့ cryptocurrencrencres ကိုအလွယ်တကူလုံခြုံစွာထားရှိပါ", + "new_first_wallet_text": "သင်၏ Crypto Safe ကိုလုံခြုံအောင်ပြုလုပ်ခြင်းသည်ကိတ်မုန့်တစ်မျိုးဖြစ်သည်", "new_node_testing": "နှာခေါင်း အသစ်စမ်းသပ်ခြင်း။", "new_subaddress_create": "ဖန်တီးပါ။", "new_subaddress_label_name": "အညွှန်းအမည်", @@ -570,6 +570,7 @@ "restore_description_from_keys": "သင့်ကိုယ်ပိုင်သော့များမှ သိမ်းဆည်းထားသော ထုတ်ပေးထားသော သော့ချက်များမှ သင့်ပိုက်ဆံအိတ်ကို ပြန်လည်ရယူပါ။", "restore_description_from_seed": "25 စကားလုံး သို့မဟုတ် 13 စကားလုံးပေါင်းစပ်ကုဒ်မှ သင့်ပိုက်ဆံအိတ်ကို ပြန်လည်ရယူပါ။", "restore_description_from_seed_keys": "သင့်ပိုက်ဆံအိတ်ကို လုံခြုံသောနေရာတွင် သိမ်းဆည်းထားသော မျိုးစေ့/သော့များမှ ပြန်လည်ရယူပါ။", + "restore_existing_wallet": "ရှိပြီးသားပိုက်ဆံအိတ်ကို restore", "restore_from_date_or_blockheight": "ဤပိုက်ဆံအိတ်ကို သင်မဖန်တီးမီ ရက်အနည်းငယ်အလိုတွင် ရက်စွဲတစ်ခု ထည့်သွင်းပါ။ သို့မဟုတ် ဘလော့ခ်ဟိုက် ကို သိပါက ၎င်းအစား ၎င်းကို ထည့်ပါ။", "restore_from_seed_placeholder": "သင့်အစေ့ကို ဤနေရာတွင် ထည့်ပါ သို့မဟုတ် ကူးထည့်ပါ။", "restore_new_seed": "မျိုးစေ့အသစ်", @@ -670,6 +671,7 @@ "sent": "ပို့လိုက်ပါတယ်။", "service_health_disabled": "ဝန်ဆောင်မှုကျန်းမာရေးစာစောင်အားပိတ်ထားသည်", "service_health_disabled_message": "ဤသည်မှာ 0 န်ဆောင်မှုကျန်းမာရေးစာစောင်စာမျက်နှာတွင်ဤစာမျက်နှာကို Settings အောက်တွင်ဖွင့်ထားနိုင်သည်", + "set_a_pin": "PIN နံပါတ်ကိုသတ်မှတ်ပါ", "settings": "ဆက်တင်များ", "settings_all": "အားလုံး", "settings_allow_biometrical_authentication": "ဇီဝဗေဒဆိုင်ရာ အထောက်အထားစိစစ်ခြင်းကို ခွင့်ပြုပါ။", @@ -890,6 +892,7 @@ "view_transaction_on": "ငွေလွှဲခြင်းကို ဖွင့်ကြည့်ပါ။", "voting_weight": "မဲပေးအလေးချိန်", "waitFewSecondForTxUpdate": "ငွေပေးငွေယူ မှတ်တမ်းတွင် ရောင်ပြန်ဟပ်ရန် စက္ကန့်အနည်းငယ်စောင့်ပါ။", + "wallet": "ပိုက်ဆံအိတ်", "wallet_group": "ပိုက်ဆံအိတ်အုပ်စု", "wallet_group_description_four": "လုံးဝအသစ်သောမျိုးစေ့နှင့်အတူပိုက်ဆံအိတ်ဖန်တီးရန်။", "wallet_group_description_one": "ကိတ်မုန့်၌, သင်တစ် ဦး ဖန်တီးနိုင်ပါတယ်", @@ -922,6 +925,8 @@ "wallets": "ပိုက်ဆံအိတ်", "warning": "သတိပေးချက်", "welcome": "မှကြိုဆိုပါတယ်။", + "welcome_subtitle_new_wallet": "လတ်ဆတ်စွာစတင်လိုပါကအောက်ကပိုက်ဆံအိတ်အသစ်ကိုဖန်တီးပါ။", + "welcome_subtitle_restore_wallet": "အကယ်. သင့်တွင်သင်ကိတ်မုန့်ထဲသို့ယူဆောင်လိုသောလက်ရှိပိုက်ဆံအိတ်ရှိပါက Restore Lestore Wallet ကိုရွေးပါ။", "welcome_to_cakepay": "Cake Pay မှကြိုဆိုပါသည်။", "what_is_silent_payments": "အသံတိတ်ငွေပေးချေမှုဆိုတာဘာလဲ", "widgets_address": "လိပ်စာ", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 82c3899d4..fc6496c3f 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Kies een nieuwe vertegenwoordiger", "nanogpt_subtitle": "Alle nieuwste modellen (GPT-4, Claude). \\ Nno-abonnement, betalen met crypto.", "narrow": "Smal", - "new_first_wallet_text": "Houd uw cryptocurrency gemakkelijk veilig", + "new_first_wallet_text": "Je crypto veilig houden is een fluitje van een cent", "new_node_testing": "Nieuwe knooppunttest", "new_subaddress_create": "Creëren", "new_subaddress_label_name": "Label naam", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Herstel uw portemonnee van gegenereerd toetsaanslagen opgeslagen van uw privésleutels", "restore_description_from_seed": "Herstel uw portemonnee van het 25 woord of 13 woord combinatiecode", "restore_description_from_seed_keys": "Ontvang uw portemonnee terug uit seed / keys die u hebt opgeslagen op een veilige plaats", + "restore_existing_wallet": "Herstel de bestaande portemonnee", "restore_from_date_or_blockheight": "Voer een datum in een paar dagen voordat u deze portemonnee heeft gemaakt. Of als u de blokhoogte kent, voert u deze in", "restore_from_seed_placeholder": "Voer hier uw codefrase in of plak deze", "restore_new_seed": "Nieuw zaad", @@ -670,6 +671,7 @@ "sent": "Verzonden", "service_health_disabled": "Service Health Bulletin is uitgeschakeld", "service_health_disabled_message": "Dit is de Service Health Bulletin -pagina, u kunt deze pagina instellingen inschakelen -> Privacy", + "set_a_pin": "Zet een speld", "settings": "Instellingen", "settings_all": "ALLE", "settings_allow_biometrical_authentication": "Biometrische authenticatie toestaan", @@ -891,6 +893,7 @@ "voting_weight": "Stemgewicht", "waitFewSecondForTxUpdate": "Wacht een paar seconden totdat de transactie wordt weergegeven in de transactiegeschiedenis", "waiting_payment_confirmation": "In afwachting van betalingsbevestiging", + "wallet": "Portemonnee", "wallet_group": "Portemonnee", "wallet_group_description_four": "om een ​​portemonnee te maken met een geheel nieuw zaadje.", "wallet_group_description_one": "In cakeballet kun je een", @@ -923,6 +926,8 @@ "wallets": "Portefeuilles", "warning": "Waarschuwing", "welcome": "Welkom bij", + "welcome_subtitle_new_wallet": "Als u opnieuw wilt beginnen, tikt u op de nieuwe portemonnee hieronder en u bent op weg naar de races.", + "welcome_subtitle_restore_wallet": "Als je een bestaande portemonnee hebt die je in cake wilt brengen, kies dan gewoon om de bestaande portemonnee te herstellen en we zullen je door het proces leiden.", "welcome_to_cakepay": "Welkom bij Cake Pay!", "what_is_silent_payments": "Wat zijn stille betalingen?", "widgets_address": "Adres", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index ed54624bf..c7cf09cd8 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Wybierz nowego przedstawiciela", "nanogpt_subtitle": "Wszystkie najnowsze modele (GPT-4, Claude). \\ Nno subskrypcja, płacą za pomocą kryptografii.", "narrow": "Wąski", - "new_first_wallet_text": "Łatwo zapewnić bezpieczeństwo kryptowalut", + "new_first_wallet_text": "Zachowanie bezpieczeństwa kryptograficznego jest kawałkiem ciasta", "new_node_testing": "Testowanie nowych węzłów", "new_subaddress_create": "Stwórz", "new_subaddress_label_name": "Etykieta nazwy adresu", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Przywróć swój portfel z kluczy prywatnych", "restore_description_from_seed": "Przywróć swój portfel z 25 lub 13-słownej frazy seed", "restore_description_from_seed_keys": "Odzyskaj swój portfel z seedów / kluczy, które zapisałeś w bezpiecznym miejscu", + "restore_existing_wallet": "Przywróć istniejący portfel", "restore_from_date_or_blockheight": "Wprowadź datę na kilka dni przed utworzeniem tego portfela, lub jeśli znasz wysokość bloku, wprowadź go zamiast daty", "restore_from_seed_placeholder": "Wpisz lub wklej tutaj swoją frazę seed", "restore_new_seed": "Nowy seed", @@ -670,6 +671,7 @@ "sent": "Wysłano", "service_health_disabled": "Biuletyn zdrowia usług jest wyłączony", "service_health_disabled_message": "To jest strona Biuletynu Zdrowie Service, możesz włączyć tę stronę w Ustawieniach -> Prywatność", + "set_a_pin": "Ustaw szpilkę", "settings": "Ustawienia", "settings_all": "Wszystkie", "settings_allow_biometrical_authentication": "Zezwalaj na uwierzytelnianie biometryczne", @@ -890,6 +892,7 @@ "view_transaction_on": "Zobacz transakcje na ", "voting_weight": "Waga głosu", "waitFewSecondForTxUpdate": "Poczekaj kilka sekund, aż transakcja zostanie odzwierciedlona w historii transakcji", + "wallet": "Portfel", "wallet_group": "Grupa portfela", "wallet_group_description_four": "Aby stworzyć portfel z zupełnie nowym ziarnem.", "wallet_group_description_one": "W portfelu ciasta możesz stworzyć", @@ -922,6 +925,8 @@ "wallets": "Portfele", "warning": "Ostrzeżenie", "welcome": "Witamy w", + "welcome_subtitle_new_wallet": "Jeśli chcesz zacząć od nowa, dotknij Utwórz nowy portfel poniżej, a będziesz na wyścigach.", + "welcome_subtitle_restore_wallet": "Jeśli masz istniejący portfel, który chcesz wnieść do ciasta, po prostu wybierz przywróć istniejący portfel, a my przeprowadzimy Cię przez proces.", "welcome_to_cakepay": "Witamy w Cake Pay!", "what_is_silent_payments": "Co to są ciche płatności?", "widgets_address": "Adres", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 7b43b5b12..50c7f4d6c 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -428,7 +428,7 @@ "nano_pick_new_rep": "Escolha um novo representante", "nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude). \\ Nno assinatura, pagam com criptografia.", "narrow": "Estreito", - "new_first_wallet_text": "Mantenha sua criptomoeda facilmente segura", + "new_first_wallet_text": "Manter sua cripto segura é um pedaço de bolo", "new_node_testing": "Teste de novo nó", "new_subaddress_create": "Criar", "new_subaddress_label_name": "Nome", @@ -572,6 +572,7 @@ "restore_description_from_keys": "Restaure sua carteira a partir de suas chaves privadas", "restore_description_from_seed": "Restaure sua carteira a partir de semente com 25 palavras ou 13 palavras", "restore_description_from_seed_keys": "Restaure a sua carteira a partir de sementes/chaves que você salvou em um local seguro", + "restore_existing_wallet": "Restaure a carteira existente", "restore_from_date_or_blockheight": "Insira uma data alguns dias antes de criar esta carteira. Ou se você souber a altura do bloco, insira-o", "restore_from_seed_placeholder": "Digite ou cole sua frase de código aqui", "restore_new_seed": "Nova semente", @@ -672,6 +673,7 @@ "sent": "Enviada", "service_health_disabled": "O Boletim de Saúde de Serviço está desativado", "service_health_disabled_message": "Esta é a página do Boletim de Saúde de Serviço, você pode ativar esta página em Configurações -> Privacidade", + "set_a_pin": "Defina um pino", "settings": "Configurações", "settings_all": "Tudo", "settings_allow_biometrical_authentication": "Permitir autenticação biométrica", @@ -893,6 +895,7 @@ "voting_weight": "Peso de votação", "waitFewSecondForTxUpdate": "Aguarde alguns segundos para que a transação seja refletida no histórico de transações", "waiting_payment_confirmation": "Aguardando confirmação de pagamento", + "wallet": "Carteira", "wallet_group": "Grupo de carteira", "wallet_group_description_four": "Para criar uma carteira com uma semente totalmente nova.", "wallet_group_description_one": "Na carteira de bolo, você pode criar um", @@ -925,6 +928,8 @@ "wallets": "Carteiras", "warning": "Aviso", "welcome": "Bem-vindo ao", + "welcome_subtitle_new_wallet": "Se você quiser começar de novo, toque em criar uma nova carteira abaixo e você estará nas corridas.", + "welcome_subtitle_restore_wallet": "Se você tem uma carteira existente que deseja trazer para o bolo, basta escolher a carteira existente e nós o guiaremos pelo processo.", "welcome_to_cakepay": "Bem-vindo ao Cake Pay!", "what_is_silent_payments": "O que são pagamentos silenciosos?", "widgets_address": "Endereço", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 2795e1ffc..639ddfe63 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Выберите нового представителя", "nanogpt_subtitle": "Все новейшие модели (GPT-4, Claude). \\ Nno Подписка, платите с крипто.", "narrow": "Узкий", - "new_first_wallet_text": "Легко сохранить свою криптовалюту в безопасности", + "new_first_wallet_text": "Сохранение вашего криптографии - это кусок торта", "new_node_testing": "Тестирование новой ноды", "new_subaddress_create": "Создать", "new_subaddress_label_name": "Имя", @@ -571,6 +571,7 @@ "restore_description_from_keys": "Вы можете восстановить кошелёк с помощью приватных ключей", "restore_description_from_seed": "Вы можете восстановить кошелёк используя 25-ти значную мнемоническую фразу", "restore_description_from_seed_keys": "Вы можете восстановить кошелёк из мнемонической фразы/ключей, которые вы сохранили ранее", + "restore_existing_wallet": "Восстановите существующий кошелек", "restore_from_date_or_blockheight": "Пожалуйста, введите дату за несколько дней до создания этого кошелька. Или, если вы знаете высоту блока, введите ее значение", "restore_from_seed_placeholder": "Введите или вставьте мнемоническую фразу вашего кошелька", "restore_new_seed": "Новая мнемоническая фраза", @@ -671,6 +672,7 @@ "sent": "Отправленные", "service_health_disabled": "Бюллетень для здоровья обслуживания инвалид", "service_health_disabled_message": "Это страница бюллетени обслуживания услуг, вы можете включить эту страницу в соответствии с настройками -> Конфиденциальность", + "set_a_pin": "Установить булавку", "settings": "Настройки", "settings_all": "ВСЕ", "settings_allow_biometrical_authentication": "Включить биометрическую аутентификацию", @@ -891,6 +893,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "Вес голоса", "waitFewSecondForTxUpdate": "Пожалуйста, подождите несколько секунд, чтобы транзакция отразилась в истории транзакций.", + "wallet": "Кошелек", "wallet_group": "Группа кошелька", "wallet_group_description_four": "создать кошелек с совершенно новым семенем.", "wallet_group_description_one": "В кошельке для торта вы можете создать", @@ -923,6 +926,8 @@ "wallets": "Кошельки", "warning": "Предупреждение", "welcome": "Приветствуем в", + "welcome_subtitle_new_wallet": "Если вы хотите начать Fresh, нажмите «Создать новый кошелек» ниже, и вы отправитесь на гонки.", + "welcome_subtitle_restore_wallet": "Если у вас есть существующий кошелек, который вы хотите принести в торт, просто выберите «Восстановить существующий кошелек», и мы проведем вас через процесс.", "welcome_to_cakepay": "Добро пожаловать в Cake Pay!", "what_is_silent_payments": "Что такое молчаливые платежи?", "widgets_address": "Адрес", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 596861646..e0b352fea 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "เลือกตัวแทนใหม่", "nanogpt_subtitle": "รุ่นใหม่ล่าสุดทั้งหมด (GPT-4, Claude). การสมัครสมาชิก \\ nno, จ่ายด้วย crypto", "narrow": "แคบ", - "new_first_wallet_text": "ทำให้สกุลเงินดิจิตอลของคุณปลอดภัยได้อย่างง่ายดาย", + "new_first_wallet_text": "การรักษา crypto ของคุณให้ปลอดภัยเป็นเค้กชิ้นหนึ่ง", "new_node_testing": "การทดสอบโหนดใหม่", "new_subaddress_create": "สร้าง", "new_subaddress_label_name": "ชื่อป้ายกำกับ", @@ -570,6 +570,7 @@ "restore_description_from_keys": "กู้กระเป๋าของคุณจากการกดปุ่มที่สร้างขึ้นจาก private keys ของคุณที่บันทึกไว้", "restore_description_from_seed": "กู้กระเป๋าของคุณจากรหัสผสมของ 25 คำหรือ 13 คำ", "restore_description_from_seed_keys": "เรียกกระเป๋าของคุณกลับมาจาก seed/keys ที่คุณได้บันทึกไว้ในที่ปลอดภัย", + "restore_existing_wallet": "คืนค่ากระเป๋าเงินที่มีอยู่", "restore_from_date_or_blockheight": "โปรดป้อนวันที่หลายวันก่อนที่คุณสร้างกระเป๋านี้ หรือหากคุณรู้ความสูงของบล็อก (blockheight) โปรดป้อนมันแทน", "restore_from_seed_placeholder": "โปรดป้อนหรือวาง seed ของคุณที่นี่", "restore_new_seed": "ซีดใหม่", @@ -670,6 +671,7 @@ "sent": "ส่ง", "service_health_disabled": "Service Health Bulletin ถูกปิดใช้งาน", "service_health_disabled_message": "นี่คือหน้า Service Health Bulletin คุณสามารถเปิดใช้งานหน้านี้ภายใต้การตั้งค่า -> ความเป็นส่วนตัว", + "set_a_pin": "ตั้งพิน", "settings": "การตั้งค่า", "settings_all": "ทั้งหมด", "settings_allow_biometrical_authentication": "อนุญาตให้ใช้การยืนยันตัวตนทางระบบชีวภาพ", @@ -890,6 +892,7 @@ "view_transaction_on": "ดูการทำธุรกรรมบน ", "voting_weight": "น้ำหนักโหวต", "waitFewSecondForTxUpdate": "กรุณารอสักครู่เพื่อให้ธุรกรรมปรากฏในประวัติการทำธุรกรรม", + "wallet": "กระเป๋าสตางค์", "wallet_group": "กลุ่มกระเป๋าเงิน", "wallet_group_description_four": "เพื่อสร้างกระเป๋าเงินที่มีเมล็ดพันธุ์ใหม่ทั้งหมด", "wallet_group_description_one": "ในกระเป๋าเงินเค้กคุณสามารถสร้างไฟล์", @@ -922,6 +925,8 @@ "wallets": "กระเป๋า", "warning": "คำเตือน", "welcome": "ยินดีต้อนรับสู่", + "welcome_subtitle_new_wallet": "หากคุณต้องการเริ่มต้นใหม่ให้แตะสร้างกระเป๋าเงินใหม่ด้านล่างและคุณจะออกจากการแข่งขัน", + "welcome_subtitle_restore_wallet": "หากคุณมีกระเป๋าเงินที่มีอยู่ที่คุณต้องการนำเข้าเค้กให้เลือกคืนกระเป๋าเงินที่มีอยู่แล้วเราจะพาคุณผ่านกระบวนการ", "welcome_to_cakepay": "ยินดีต้อนรับสู่ Cake Pay!", "what_is_silent_payments": "การชำระเงินเงียบคืออะไร?", "widgets_address": "ที่อยู่", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index f4678e00d..5f05e3d51 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Pumili ng isang bagong representative", "nanogpt_subtitle": "Ang lahat ng mga pinakabagong modelo (GPT-4, Claude). \nNo subscription, magbayad gamit ang crypto.", "narrow": "Makitid", - "new_first_wallet_text": "Panatilihing ligtas ang iyong crypto, piraso ng cake", + "new_first_wallet_text": "Ang pagpapanatiling ligtas sa iyong crypto ay isang piraso ng cake", "new_node_testing": "Bagong node testing", "new_subaddress_create": "Lumikha", "new_subaddress_label_name": "Pangalan ng label", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Ibalik ang iyong wallet mula sa nabuong mga keystrokes na na-save mula sa iyong mga private key", "restore_description_from_seed": "Ibalik ang iyong wallet mula sa alinman sa 25 na salita o 13 na salita na seed", "restore_description_from_seed_keys": "Ibalik ang inyong wallet mula sa inyong seed/keys na iyong na-save sa ligtas na lugar", + "restore_existing_wallet": "Ibalik ang umiiral na pitaka", "restore_from_date_or_blockheight": "Mangyaring maglagay ng petsa ilang araw bago mo ginawa ang wallet na ito. O kung alam mo ang block height pwede ilagay ito sa halip", "restore_from_seed_placeholder": "Mangyaring ipasok o idikit ang iyong seed dito", "restore_new_seed": "Bagong seed", @@ -670,6 +671,7 @@ "sent": "Ipinadala", "service_health_disabled": "Hindi pinagana ang Service Health Bulletin", "service_health_disabled_message": "Ito ang pahina ng Service Health Bulletin, maaari mong paganahin ang pahinang ito sa ilalim ng Mga Setting -> Pagkapribado", + "set_a_pin": "Magtakda ng isang pin", "settings": "Mga Setting", "settings_all": "LAHAT", "settings_allow_biometrical_authentication": "Payagan ang biometrical authentication", @@ -890,6 +892,7 @@ "view_transaction_on": "Tingnan ang transaksyon sa ", "voting_weight": "Bigat ng pagboto", "waitFewSecondForTxUpdate": "Mangyaring maghintay ng ilang segundo para makita ang transaksyon sa history ng mga transaksyon", + "wallet": "Wallet", "wallet_group": "Group ng Wallet", "wallet_group_description_four": "Upang lumikha ng isang pitaka na may ganap na bagong binhi.", "wallet_group_description_one": "Sa cake wallet, maaari kang lumikha ng isang", @@ -922,6 +925,8 @@ "wallets": "Mga Wallet", "warning": "Babala", "welcome": "Maligayang pagdating sa", + "welcome_subtitle_new_wallet": "Kung nais mong simulan ang sariwa, tapikin ang Lumikha ng Bagong Wallet sa ibaba at pupunta ka sa mga karera.", + "welcome_subtitle_restore_wallet": "Kung mayroon kang isang umiiral na pitaka na nais mong dalhin sa cake, piliin lamang ang ibalik ang umiiral na pitaka at lalakad ka namin sa proseso.", "welcome_to_cakepay": "Maligayang pagdating sa Cake Pay!", "what_is_silent_payments": "Ano ang tahimik na pagbabayad?", "widgets_address": "Address", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index d8b3ae3cf..80990ae2d 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Yeni bir temsilci seçin", "nanogpt_subtitle": "En yeni modeller (GPT-4, Claude). \\ Nno aboneliği, kripto ile ödeme yapın.", "narrow": "Dar", - "new_first_wallet_text": "Kripto para biriminizi kolayca güvende tutun", + "new_first_wallet_text": "Kripto'nuzu güvende tutmak bir parça kek", "new_node_testing": "Yeni düğüm test ediliyor", "new_subaddress_create": "Oluştur", "new_subaddress_label_name": "Etiket ismi", @@ -570,6 +570,7 @@ "restore_description_from_keys": "Cüzdanınızı özel anahtarlarınızdan kaydedilen oluşturulmuş tuş vuruşlarından geri yükleyin", "restore_description_from_seed": "Cüzdanınızı 25 veya 13 kelimelik kombinasyon kodundan geri döndürün", "restore_description_from_seed_keys": "Güvenli bir yere kaydettiğin tohumdan/anahtarlardan cüzdanını geri döndür", + "restore_existing_wallet": "Mevcut cüzdanı geri yükleyin", "restore_from_date_or_blockheight": "Lütfen bu cüzdanı oluşturmadan birkaç gün önceki bir tarihi girin. Veya blok yüksekliğini biliyorsan, lütfen bunu gir", "restore_from_seed_placeholder": "Lütfen tohumunu buraya gir veya yapıştır", "restore_new_seed": "Yeni tohum", @@ -670,6 +671,7 @@ "sent": "Gönderildi", "service_health_disabled": "Service Health Bülten devre dışı bırakıldı", "service_health_disabled_message": "Bu Hizmet Sağlığı Bülten Sayfası, bu sayfayı Ayarlar -> Gizlilik altında etkinleştirebilirsiniz", + "set_a_pin": "Bir pim ayarlamak", "settings": "ayarlar", "settings_all": "HEPSİ", "settings_allow_biometrical_authentication": "Biyometrik doğrulamaya izin ver", @@ -890,6 +892,7 @@ "view_transaction_on": "İşlemi şurada görüntüle ", "voting_weight": "Oy kullanma", "waitFewSecondForTxUpdate": "İşlemin işlem geçmişine yansıması için lütfen birkaç saniye bekleyin", + "wallet": "Cüzdan", "wallet_group": "Cüzdan grubu", "wallet_group_description_four": "Tamamen yeni bir tohumla bir cüzdan oluşturmak için.", "wallet_group_description_one": "Kek cüzdanında bir", @@ -922,6 +925,8 @@ "wallets": "Cüzdanlar", "warning": "Uyarı", "welcome": "Hoş Geldiniz", + "welcome_subtitle_new_wallet": "Taze başlamak istiyorsanız, aşağıda yeni cüzdan oluşturun ve yarışlara gidersiniz.", + "welcome_subtitle_restore_wallet": "Mevcut bir cüzdanınız varsa, kek içine getirmek istediğiniz, mevcut cüzdanı geri yüklemeyi seçin ve bu süreç boyunca size yol gösterelim.", "welcome_to_cakepay": "Cake Pay'e Hoş Geldiniz!", "what_is_silent_payments": "Sessiz ödemeler nedir?", "widgets_address": "Adres", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index f27300c18..b2d7a22e5 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "Виберіть нового представника", "nanogpt_subtitle": "Усі найновіші моделі (GPT-4, Claude). \\ Nno підписка, оплата криптовалютою.", "narrow": "вузькі", - "new_first_wallet_text": "Легко зберігайте свою криптовалюту в безпеці", + "new_first_wallet_text": "Зберігання вашої криптовалюти це просто як шматок торта", "new_node_testing": "Тестування нового вузла", "new_subaddress_create": "Створити", "new_subaddress_label_name": "Ім'я", @@ -571,6 +571,7 @@ "restore_description_from_keys": "Ви можете відновити гаманець за допомогою приватних ключів", "restore_description_from_seed": "Ви можете відновити гаманець використовуючи 25-ти слівну мнемонічну фразу", "restore_description_from_seed_keys": "Ви можете відновити гаманець з мнемонічної фрази/ключів, які ви зберегли раніше", + "restore_existing_wallet": "Відновити існуючий гаманець", "restore_from_date_or_blockheight": "Будь ласка, введіть дату за кілька днів до створення цього гаманця. Або, якщо ви знаєте висоту блоку, введіть її значення", "restore_from_seed_placeholder": "Введіть або вставте мнемонічну фразу вашого гаманця", "restore_new_seed": "Нова мнемонічна фраза", @@ -671,6 +672,7 @@ "sent": "Відправлені", "service_health_disabled": "Вісник охорони здоров'я інвалідів", "service_health_disabled_message": "Це сторінка бюлетеня Health Service, ви можете включити цю сторінку в налаштуваннях -> конфіденційність", + "set_a_pin": "Встановити PIN", "settings": "Налаштування", "settings_all": "ВСІ", "settings_allow_biometrical_authentication": "Включити біометричну аутентифікацію", @@ -891,6 +893,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "Вага голосування", "waitFewSecondForTxUpdate": "Будь ласка, зачекайте кілька секунд, поки транзакція відобразиться в історії транзакцій", + "wallet": "Гаманець", "wallet_group": "Група гаманців", "wallet_group_description_four": "створити гаманець з абсолютно новим насінням.", "wallet_group_description_one": "У гаманці тортів ви можете створити a", @@ -923,6 +926,8 @@ "wallets": "Гаманці", "warning": "УВАГА", "welcome": "Вітаємо в", + "welcome_subtitle_new_wallet": "Якщо ви хочете почати спочатку, торкніться Створити новий гаманець нижче, і ви будете поза конкуренціею.", + "welcome_subtitle_restore_wallet": "Якщо у вас є існуючий гаманець, який ви хочете ввести в торт, просто виберіть Відновити існуючий гаманець, і ми проведемо вас через процес.", "welcome_to_cakepay": "Ласкаво просимо до Cake Pay!", "what_is_silent_payments": "Що таке мовчазні платежі?", "widgets_address": "Адреса", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 00f336d72..289bfb958 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "ایک نیا نمائندہ منتخب کریں", "nanogpt_subtitle": "تمام تازہ ترین ماڈل (GPT-4 ، کلاڈ)۔ n n no سبسکرپشن ، کریپٹو کے ساتھ ادائیگی کریں۔", "narrow": "تنگ", - "new_first_wallet_text": "آسانی سے اپنے cryptocurrency محفوظ رکھیں", + "new_first_wallet_text": "اپنے کریپٹو کو محفوظ رکھنا کیک کا ایک ٹکڑا ہے", "new_node_testing": "نیا نوڈ ٹیسٹنگ", "new_subaddress_create": "بنانا", "new_subaddress_label_name": "لیبل کا نام", @@ -572,6 +572,7 @@ "restore_description_from_keys": "اپنے بٹوے کو اپنی نجی کلیدوں سے محفوظ کردہ کی اسٹروکس سے بحال کریں۔", "restore_description_from_seed": "اپنے بٹوے کو 25 لفظ یا 13 الفاظ کے مجموعہ کوڈ سے بحال کریں۔", "restore_description_from_seed_keys": "اپنے بٹوے کو بیج / چابیاں سے واپس حاصل کریں جنہیں آپ نے محفوظ جگہ پر محفوظ کیا ہے۔", + "restore_existing_wallet": "موجودہ پرس کو بحال کریں", "restore_from_date_or_blockheight": "براہ کرم یہ پرس بنانے سے چند دن پہلے کی تاریخ درج کریں۔ یا اگر آپ کو بلاک ہائیٹ معلوم ہے تو براہ کرم اس کی بجائے اسے درج کریں۔", "restore_from_seed_placeholder": "براہ کرم اپنا بیج یہاں درج کریں یا پیسٹ کریں۔", "restore_new_seed": "نیا بیج", @@ -672,6 +673,7 @@ "sent": "بھیجا", "service_health_disabled": "سروس ہیلتھ بلیٹن غیر فعال ہے", "service_health_disabled_message": "یہ سروس ہیلتھ بلیٹن پیج ہے ، آپ اس صفحے کو ترتیبات کے تحت اہل بنا سکتے ہیں -> رازداری", + "set_a_pin": "ایک پن مرتب کریں", "settings": "ترتیبات", "settings_all": "تمام", "settings_allow_biometrical_authentication": "بایومیٹریکل تصدیق کی اجازت دیں۔", @@ -892,6 +894,7 @@ "view_transaction_on": "لین دین دیکھیں آن", "voting_weight": "ووٹ کا وزن", "waitFewSecondForTxUpdate": "۔ﮟﯾﺮﮐ ﺭﺎﻈﺘﻧﺍ ﺎﮐ ﮉﻨﮑﯿﺳ ﺪﻨﭼ ﻡﺮﮐ ﮦﺍﺮﺑ ﮯﯿﻟ ﮯﮐ ﮯﻧﺮﮐ ﯽﺳﺎﮑﻋ ﯽﮐ ﻦﯾﺩ ﻦﯿﻟ ﮟﯿﻣ ﺦﯾﺭﺎﺗ ﯽﮐ ﻦ", + "wallet": "پرس", "wallet_group": "پرس گروپ", "wallet_group_description_four": "مکمل طور پر نئے بیج کے ساتھ پرس بنانے کے ل.", "wallet_group_description_one": "کیک پرس میں ، آپ بنا سکتے ہیں", @@ -924,6 +927,8 @@ "wallets": "بٹوے", "warning": "وارننگ", "welcome": "میں خوش آمدید", + "welcome_subtitle_new_wallet": "اگر آپ تازہ شروع کرنا چاہتے ہیں تو ، نیچے نیا پرس بنائیں پر تھپتھپائیں اور آپ ریسوں پر جائیں گے۔", + "welcome_subtitle_restore_wallet": "اگر آپ کے پاس موجودہ پرس ہے تو آپ کیک میں لانا چاہتے ہیں تو ، موجودہ بٹوے کو بحال کریں کا انتخاب کریں اور ہم آپ کو اس عمل میں چلیں گے۔", "welcome_to_cakepay": "Cake پے میں خوش آمدید!", "what_is_silent_payments": "خاموش ادائیگی کیا ہے؟", "widgets_address": "پتہ", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index 1291b505e..e7c95b8ec 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -426,7 +426,7 @@ "nano_pick_new_rep": "Chọn đại diện mới", "nanogpt_subtitle": "Tất cả các mẫu mới nhất (GPT-4, Claude).\\nKhông cần đăng ký, thanh toán bằng tiền điện tử.", "narrow": "Hẹp", - "new_first_wallet_text": "Giữ an toàn cho tiền điện tử của bạn, dễ dàng như ăn bánh", + "new_first_wallet_text": "Giữ tiền điện tử của bạn an toàn là một miếng bánh", "new_node_testing": "Đang thử nghiệm nút mới", "new_subaddress_create": "Tạo", "new_subaddress_label_name": "Tên nhãn", @@ -569,6 +569,7 @@ "restore_description_from_keys": "Khôi phục ví của bạn từ các thao tác nhập được lưu từ khóa riêng của bạn", "restore_description_from_seed": "Khôi phục ví của bạn từ mã kết hợp 25 từ hoặc 13 từ", "restore_description_from_seed_keys": "Khôi phục ví của bạn từ hạt giống/khóa mà bạn đã lưu ở nơi an toàn", + "restore_existing_wallet": "Khôi phục ví hiện có", "restore_from_date_or_blockheight": "Vui lòng nhập một ngày vài ngày trước khi bạn tạo ví này. Hoặc nếu bạn biết chiều cao khối, hãy nhập nó thay thế", "restore_from_seed_placeholder": "Vui lòng nhập hoặc dán hạt giống của bạn vào đây", "restore_new_seed": "Hạt giống mới", @@ -669,6 +670,7 @@ "sent": "Đã gửi", "service_health_disabled": "Thông báo sức khỏe dịch vụ bị vô hiệu hóa", "service_health_disabled_message": "Đây là trang thông báo sức khỏe dịch vụ, bạn có thể kích hoạt trang này trong Cài đặt -> Quyền riêng tư", + "set_a_pin": "Đặt một pin", "settings": "Cài đặt", "settings_all": "TẤT CẢ", "settings_allow_biometrical_authentication": "Cho phép xác thực sinh trắc học", @@ -889,6 +891,7 @@ "view_transaction_on": "Xem giao dịch trên", "voting_weight": "Trọng số bỏ phiếu", "waitFewSecondForTxUpdate": "Vui lòng đợi vài giây để giao dịch được phản ánh trong lịch sử giao dịch", + "wallet": "Cái ví", "wallet_group": "Nhóm ví", "wallet_group_description_four": "Để tạo ra một ví với một hạt giống hoàn toàn mới.", "wallet_group_description_one": "Trong ví bánh, bạn có thể tạo", @@ -921,6 +924,8 @@ "wallets": "Các ví", "warning": "Cảnh báo", "welcome": "Chào mừng đến với", + "welcome_subtitle_new_wallet": "Nếu bạn muốn bắt đầu mới, hãy nhấn Tạo ví mới bên dưới và bạn sẽ rời khỏi các cuộc đua.", + "welcome_subtitle_restore_wallet": "Nếu bạn có một ví hiện có mà bạn muốn mang vào bánh, chỉ cần chọn khôi phục ví hiện có và chúng tôi sẽ hướng dẫn bạn qua quá trình này.", "welcome_to_cakepay": "Chào mừng đến với Cake Pay!", "what_is_silent_payments": "Thanh toán im lặng là gì?", "widgets_address": "Địa chỉ", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index c9275b018..c9b8c4cbd 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -428,7 +428,7 @@ "nano_pick_new_rep": "Mu aṣoju tuntun kan", "nanogpt_subtitle": "Gbogbo awọn awoṣe tuntun (GPT-4, Claude). \\ Nno alabapin kan, sanwo pẹlu Crypto.", "narrow": "Taara", - "new_first_wallet_text": "Ni rọọrun jẹ ki o jẹ ki o jẹ ki o jẹ ki a mu", + "new_first_wallet_text": "Tọju ẹrọ ti o ni aabo rẹ jẹ nkan ti akara oyinbo kan", "new_node_testing": "A ń dán apẹka títun wò", "new_subaddress_create": "Ṣe é", "new_subaddress_label_name": "Orúkọ", @@ -571,6 +571,7 @@ "restore_description_from_keys": "Mú àpamọ́wọ́ yín padà láti àwọn àtẹ̀ nípamọ́ láti àwọn kọ́kọ́rọ́ àdáni yín", "restore_description_from_seed": "Ẹ mú àpamọ́wọ́ yín padà láti àkànpọ̀ ọlọ́rọ̀ ẹ̀ẹ̀marùndínlọgbọ̀n tàbí ti mẹ́talá.", "restore_description_from_seed_keys": "Mú àpamọ́wọ́ yín padà láti hóró/kọ́kọ́rọ́ t'ẹ́ ti pamọ́ sí ibi láìléwu", + "restore_existing_wallet": "Mu pada apamọwọ to wa tẹlẹ", "restore_from_date_or_blockheight": "Ẹ jọ̀wọ́, tẹ̀ ìgbà ọjọ́ díẹ̀ k'ẹ́ tó ti dá àpamọ́wọ́ yìí. Tàbí ẹ lè tẹ̀ ẹ́ t'ẹ́ bá mọ gíga àkójọpọ̀.", "restore_from_seed_placeholder": "Ẹ jọ̀wọ́ tẹ̀ hóró yín tàbí fikún ẹ̀dà hóró ḿbí.", "restore_new_seed": "Hóró títun", @@ -671,6 +672,7 @@ "sent": "Owó t'á ti ránṣẹ́", "service_health_disabled": "IPỌRỌ IWE TI AGBARA TI O LE RẸ", "service_health_disabled_message": "Eyi ni oju-iwe Iwe itẹlera Iṣẹ Ile-iṣẹ Iṣẹ: O le mu oju-iwe yii ṣiṣẹ labẹ Eto -> Asiri", + "set_a_pin": "Ṣeto PIN kan", "settings": "Awọn aseṣe", "settings_all": "Gbogbo", "settings_allow_biometrical_authentication": "Fi àyè gba ìfẹ̀rílàdí biometrical", @@ -891,6 +893,7 @@ "view_transaction_on": "Wo pàṣípààrọ̀ lórí ", "voting_weight": "Idibo iwuwo", "waitFewSecondForTxUpdate": "Fi inurere duro fun awọn iṣeju diẹ fun idunadura lati ṣe afihan ninu itan-akọọlẹ iṣowo", + "wallet": "Ohun apamọwọwọ", "wallet_group": "Ẹgbẹ apamọwọ", "wallet_group_description_four": "Lati ṣẹda apamọwọ kan pẹlu irugbin tuntun tuntun.", "wallet_group_description_one": "Ni apamọwọ akara oyinbo, o le ṣẹda a", @@ -923,6 +926,8 @@ "wallets": "Àwọn àpamọ́wọ́", "warning": "Ikilo", "welcome": "Ẹ káàbọ sí", + "welcome_subtitle_new_wallet": "Ti o ba fẹ bẹrẹ alabapade, tẹ Ṣẹda apamọwọ tuntun ni isalẹ iwọ yoo wa ni pipa si awọn ere-ije.", + "welcome_subtitle_restore_wallet": "Ti o ba ni apamọwọ ti o wa tẹlẹ ti o fẹ lati mu wa sinu akara oyinbo, yan omi apamọwọ wa tẹlẹ ati pe a yoo rin ọ nipasẹ ilana naa.", "welcome_to_cakepay": "Ẹ káàbọ̀ sí Cake Pay!", "what_is_silent_payments": "Kini awọn sisanwo ipalọlọ?", "widgets_address": "Àdírẹ́sì", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index e508d3c2c..37b35ea6d 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -427,7 +427,7 @@ "nano_pick_new_rep": "选择新代表", "nanogpt_subtitle": "所有最新型号(GPT-4,Claude)。\\ nno订阅,用加密货币付款。", "narrow": "狭窄的", - "new_first_wallet_text": "轻松确保您的加密货币安全", + "new_first_wallet_text": "保持加密货币是一件小菜一碟", "new_node_testing": "新节点测试", "new_subaddress_create": "创建", "new_subaddress_label_name": "标签名称", @@ -570,6 +570,7 @@ "restore_description_from_keys": "使用私钥恢复钱包", "restore_description_from_seed": "从25个字中恢复您的钱包或13个字的组合码", "restore_description_from_seed_keys": "从保存到安全地方的种子/钥匙取回钱包", + "restore_existing_wallet": "恢复现有的钱包", "restore_from_date_or_blockheight": "请输入您创建这个钱包前几天的日期。或者如果您知道区块高度,请输入区块高度", "restore_from_seed_placeholder": "请在此处输入或粘贴您的代码短语", "restore_new_seed": "新种子", @@ -670,6 +671,7 @@ "sent": "已发送", "service_health_disabled": "服务健康公告被禁用", "service_health_disabled_message": "这是服务健康公告页面,您可以在设置 - >隐私下启用此页面", + "set_a_pin": "设置一个别针", "settings": "设置", "settings_all": "全部", "settings_allow_biometrical_authentication": "允许生物识别认证", @@ -890,6 +892,7 @@ "view_transaction_on": "View Transaction on ", "voting_weight": "投票权重", "waitFewSecondForTxUpdate": "请等待几秒钟,交易才会反映在交易历史记录中", + "wallet": "钱包", "wallet_group": "钱包组", "wallet_group_description_four": "创建一个带有全新种子的钱包。", "wallet_group_description_one": "在蛋糕钱包中,您可以创建一个", @@ -922,6 +925,8 @@ "wallets": "钱包", "warning": "警告", "welcome": "欢迎使用", + "welcome_subtitle_new_wallet": "如果您想开始新鲜,请点击下面的创建新钱包,您将参加比赛。", + "welcome_subtitle_restore_wallet": "如果您有一个现有的钱包要把蛋糕带入蛋糕,只需选择还原现有的钱包,我们将带您完成整个过程。", "welcome_to_cakepay": "欢迎来到 Cake Pay!", "what_is_silent_payments": "什么是无声付款?", "widgets_address": "地址", From 4ca50b5e6329dd5be066396ccb2e5a4c0483df53 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 28 Nov 2024 02:42:46 +0200 Subject: [PATCH 26/41] Cw 649 rbf improvements opt in (#1772) * initial commit * revert changes * allow adding inputs to RBF transactions * address review comments[skip ci] --------- Co-authored-by: Omar Hatem --- cw_bitcoin/lib/electrum_wallet.dart | 145 ++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 32 deletions(-) diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index c29df3c4a..17ced5adf 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1503,14 +1503,21 @@ abstract class ElectrumWalletBase final bundle = await getTransactionExpanded(hash: txId); final outputs = bundle.originalTransaction.outputs; - final changeAddresses = walletAddresses.allAddresses.where((element) => element.isHidden); + final ownAddresses = walletAddresses.allAddresses.map((addr) => addr.address).toSet(); - // look for a change address in the outputs - final changeOutput = outputs.firstWhereOrNull((output) => changeAddresses.any( - (element) => element.address == addressFromOutputScript(output.scriptPubKey, network))); + final receiverAmount = outputs + .where((output) => !ownAddresses.contains(addressFromOutputScript(output.scriptPubKey, network))) + .fold(0, (sum, output) => sum + output.amount.toInt()); - var allInputsAmount = 0; + if (receiverAmount == 0) { + throw Exception("Receiver output not found."); + } + final availableInputs = unspentCoins.where((utxo) => utxo.isSending && !utxo.isFrozen).toList(); + int totalBalance = availableInputs.fold( + 0, (previousValue, element) => previousValue + element.value.toInt()); + + int allInputsAmount = 0; for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) { final input = bundle.originalTransaction.inputs[i]; final inputTransaction = bundle.ins[i]; @@ -1521,12 +1528,10 @@ abstract class ElectrumWalletBase int totalOutAmount = bundle.originalTransaction.outputs .fold(0, (previousValue, element) => previousValue + element.amount.toInt()); - var currentFee = allInputsAmount - totalOutAmount; int remainingFee = (newFee - currentFee > 0) ? newFee - currentFee : newFee; - - return changeOutput != null && changeOutput.amount.toInt() - remainingFee >= 0; + return totalBalance - receiverAmount - remainingFee >= _dustAmount; } Future replaceByFee(String hash, int newFee) async { @@ -1534,12 +1539,13 @@ abstract class ElectrumWalletBase final bundle = await getTransactionExpanded(hash: hash); final utxos = []; + final outputs = []; List privateKeys = []; var allInputsAmount = 0; String? memo; - // Add inputs + // Add original inputs for (var i = 0; i < bundle.originalTransaction.inputs.length; i++) { final input = bundle.originalTransaction.inputs[i]; final inputTransaction = bundle.ins[i]; @@ -1549,8 +1555,7 @@ abstract class ElectrumWalletBase allInputsAmount += outTransaction.amount.toInt(); final addressRecord = - walletAddresses.allAddresses.firstWhere((element) => element.address == address); - + walletAddresses.allAddresses.firstWhere((element) => element.address == address); final btcAddress = RegexUtils.addressTypeFromStr(addressRecord.address, network); final privkey = generateECPrivate( hd: addressRecord.isHidden ? walletAddresses.sideHd : walletAddresses.mainHd, @@ -1568,15 +1573,13 @@ abstract class ElectrumWalletBase scriptType: _getScriptType(btcAddress), ), ownerDetails: - UtxoAddressDetails(publicKey: privkey.getPublic().toHex(), address: btcAddress), + UtxoAddressDetails(publicKey: privkey.getPublic().toHex(), address: btcAddress), ), ); } - // Create a list of available outputs - final outputs = []; + // Add original outputs for (final out in bundle.originalTransaction.outputs) { - // Check if the script contains OP_RETURN final script = out.scriptPubKey.script; if (script.contains('OP_RETURN') && memo == null) { final index = script.indexOf('OP_RETURN'); @@ -1598,7 +1601,7 @@ abstract class ElectrumWalletBase // Calculate the total amount and fees int totalOutAmount = - outputs.fold(0, (previousValue, output) => previousValue + output.value.toInt()); + outputs.fold(0, (previousValue, output) => previousValue + output.value.toInt()); int currentFee = allInputsAmount - totalOutAmount; int remainingFee = newFee - currentFee; @@ -1606,17 +1609,95 @@ abstract class ElectrumWalletBase throw Exception("New fee must be higher than the current fee."); } - // Deduct Remaining Fee from Main Outputs + // Deduct fee from change outputs first, if possible if (remainingFee > 0) { + final changeAddresses = walletAddresses.allAddresses.where((element) => element.isHidden); for (int i = outputs.length - 1; i >= 0; i--) { - int outputAmount = outputs[i].value.toInt(); + final output = outputs[i]; + final isChange = changeAddresses + .any((element) => element.address == output.address.toAddress(network)); + + if (isChange) { + int outputAmount = output.value.toInt(); + if (outputAmount > _dustAmount) { + int deduction = (outputAmount - _dustAmount >= remainingFee) + ? remainingFee + : outputAmount - _dustAmount; + outputs[i] = BitcoinOutput( + address: output.address, value: BigInt.from(outputAmount - deduction)); + remainingFee -= deduction; + + if (remainingFee <= 0) break; + } + } + } + } + + // If still not enough, add UTXOs until the fee is covered + if (remainingFee > 0) { + final unusedUtxos = unspentCoins + .where((utxo) => utxo.isSending && !utxo.isFrozen && utxo.confirmations! > 0) + .toList(); + + for (final utxo in unusedUtxos) { + final address = RegexUtils.addressTypeFromStr(utxo.address, network); + final privkey = generateECPrivate( + hd: utxo.bitcoinAddressRecord.isHidden + ? walletAddresses.sideHd + : walletAddresses.mainHd, + index: utxo.bitcoinAddressRecord.index, + network: network, + ); + privateKeys.add(privkey); + + utxos.add(UtxoWithAddress( + utxo: BitcoinUtxo( + txHash: utxo.hash, + value: BigInt.from(utxo.value), + vout: utxo.vout, + scriptType: _getScriptType(address)), + ownerDetails: + UtxoAddressDetails(publicKey: privkey.getPublic().toHex(), address: address), + )); + + allInputsAmount += utxo.value; + remainingFee -= utxo.value; + + if (remainingFee < 0) { + final changeOutput = outputs.firstWhereOrNull((output) => walletAddresses.allAddresses + .any((addr) => addr.address == output.address.toAddress(network))); + if (changeOutput != null) { + final newValue = changeOutput.value.toInt() + (-remainingFee); + outputs[outputs.indexOf(changeOutput)] = + BitcoinOutput(address: changeOutput.address, value: BigInt.from(newValue)); + } else { + final changeAddress = await walletAddresses.getChangeAddress(); + outputs.add(BitcoinOutput( + address: RegexUtils.addressTypeFromStr(changeAddress.address, network), + value: BigInt.from(-remainingFee))); + } + + remainingFee = 0; + break; + } + + if (remainingFee <= 0) break; + } + } + + // Deduct from the receiver's output if remaining fee is still greater than 0 + if (remainingFee > 0) { + for (int i = 0; i < outputs.length; i++) { + final output = outputs[i]; + int outputAmount = output.value.toInt(); if (outputAmount > _dustAmount) { int deduction = (outputAmount - _dustAmount >= remainingFee) ? remainingFee : outputAmount - _dustAmount; + outputs[i] = BitcoinOutput( - address: outputs[i].address, value: BigInt.from(outputAmount - deduction)); + address: output.address, value: BigInt.from(outputAmount - deduction)); remainingFee -= deduction; if (remainingFee <= 0) break; @@ -1633,11 +1714,11 @@ abstract class ElectrumWalletBase final changeAddresses = walletAddresses.allAddresses.where((element) => element.isHidden); final List changeOutputs = outputs .where((output) => changeAddresses - .any((element) => element.address == output.address.toAddress(network))) + .any((element) => element.address == output.address.toAddress(network))) .toList(); int totalChangeAmount = - changeOutputs.fold(0, (sum, output) => sum + output.value.toInt()); + changeOutputs.fold(0, (sum, output) => sum + output.value.toInt()); // The final amount that the receiver will receive int sendingAmount = allInputsAmount - newFee - totalChangeAmount; @@ -1654,8 +1735,7 @@ abstract class ElectrumWalletBase final transaction = txb.buildTransaction((txDigest, utxo, publicKey, sighash) { final key = - privateKeys.firstWhereOrNull((element) => element.getPublic().toHex() == publicKey); - + privateKeys.firstWhereOrNull((element) => element.getPublic().toHex() == publicKey); if (key == null) { throw Exception("Cannot find private key"); } @@ -1665,6 +1745,7 @@ abstract class ElectrumWalletBase } else { return key.signInput(txDigest, sigHash: sighash); } + }); return PendingBitcoinTransaction( @@ -1677,16 +1758,16 @@ abstract class ElectrumWalletBase hasChange: changeOutputs.isNotEmpty, feeRate: newFee.toString(), )..addListener((transaction) async { - transactionHistory.transactions.values.forEach((tx) { - if (tx.id == hash) { - tx.isReplaced = true; - tx.isPending = false; - transactionHistory.addOne(tx); - } - }); - transactionHistory.addOne(transaction); - await updateBalance(); + transactionHistory.transactions.values.forEach((tx) { + if (tx.id == hash) { + tx.isReplaced = true; + tx.isPending = false; + transactionHistory.addOne(tx); + } }); + transactionHistory.addOne(transaction); + await updateBalance(); + }); } catch (e) { throw e; } From 9cd69c4ba3649a1a928de806d925f540b07b5ad6 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 28 Nov 2024 17:53:03 +0200 Subject: [PATCH 27/41] Cw 830 coin control getting cleared (#1825) * init commit * add select all button * localisation all coins * fix isSending and isFrozen state updates * fix: clean up electrum UTXOs * ui fixes * address the review comments[skip ci] * remove onPopInvoked[skip ci] --------- Co-authored-by: Omar Hatem --- cw_bitcoin/lib/bitcoin_wallet_service.dart | 9 + cw_bitcoin/lib/electrum_wallet.dart | 57 +++-- cw_bitcoin/lib/litecoin_wallet_service.dart | 9 + .../lib/src/bitcoin_cash_wallet_service.dart | 9 + cw_core/lib/unspent_coins_info.dart | 3 +- cw_core/lib/unspent_comparable_mixin.dart | 27 +++ cw_core/lib/unspent_transaction_output.dart | 4 +- .../unspent_coins_list_page.dart | 194 +++++++++++++++--- .../widgets/alert_with_no_action.dart.dart | 8 +- lib/src/widgets/base_alert_dialog.dart | 7 +- .../unspent_coins/unspent_coins_item.dart | 7 +- .../unspent_coins_list_view_model.dart | 163 +++++++++------ res/values/strings_ar.arb | 1 + res/values/strings_bg.arb | 1 + res/values/strings_cs.arb | 1 + res/values/strings_de.arb | 1 + res/values/strings_en.arb | 1 + res/values/strings_es.arb | 1 + res/values/strings_fr.arb | 1 + res/values/strings_ha.arb | 1 + res/values/strings_hi.arb | 1 + res/values/strings_hr.arb | 1 + res/values/strings_hy.arb | 1 + res/values/strings_id.arb | 1 + res/values/strings_it.arb | 1 + res/values/strings_ja.arb | 1 + res/values/strings_ko.arb | 3 +- res/values/strings_my.arb | 1 + res/values/strings_nl.arb | 1 + res/values/strings_pl.arb | 1 + res/values/strings_pt.arb | 1 + res/values/strings_ru.arb | 1 + res/values/strings_th.arb | 1 + res/values/strings_tl.arb | 1 + res/values/strings_tr.arb | 1 + res/values/strings_uk.arb | 1 + res/values/strings_ur.arb | 1 + res/values/strings_vi.arb | 1 + res/values/strings_yo.arb | 1 + res/values/strings_zh.arb | 1 + 40 files changed, 402 insertions(+), 125 deletions(-) create mode 100644 cw_core/lib/unspent_comparable_mixin.dart diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart index 06f2082e4..7ee1534bf 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_service.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart @@ -106,6 +106,15 @@ class BitcoinWalletService extends WalletService< final walletInfo = walletInfoSource.values .firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!; await walletInfoSource.delete(walletInfo.key); + + final unspentCoinsToDelete = unspentCoinsInfoSource.values.where( + (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList(); + + final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList(); + + if (keysToDelete.isNotEmpty) { + await unspentCoinsInfoSource.deleteAll(keysToDelete); + } } @override diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 17ced5adf..771d135a0 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -304,6 +304,7 @@ abstract class ElectrumWalletBase Future init() async { await walletAddresses.init(); await transactionHistory.init(); + await cleanUpDuplicateUnspentCoins(); await save(); _autoSaveTimer = @@ -1379,10 +1380,11 @@ abstract class ElectrumWalletBase })); unspentCoins = updatedUnspentCoins; + + final currentWalletUnspentCoins = unspentCoinsInfo.values.where((element) => element.walletId == id); - if (unspentCoinsInfo.length != updatedUnspentCoins.length) { + if (currentWalletUnspentCoins.length != updatedUnspentCoins.length) { unspentCoins.forEach((coin) => addCoinInfo(coin)); - return; } await updateCoins(unspentCoins); @@ -1408,6 +1410,7 @@ abstract class ElectrumWalletBase coin.isFrozen = coinInfo.isFrozen; coin.isSending = coinInfo.isSending; coin.note = coinInfo.note; + if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord) coin.bitcoinAddressRecord.balance += coinInfo.value; } else { @@ -1445,20 +1448,27 @@ abstract class ElectrumWalletBase @action Future addCoinInfo(BitcoinUnspent coin) async { - final newInfo = UnspentCoinsInfo( - walletId: id, - hash: coin.hash, - isFrozen: coin.isFrozen, - isSending: coin.isSending, - noteRaw: coin.note, - address: coin.bitcoinAddressRecord.address, - value: coin.value, - vout: coin.vout, - isChange: coin.isChange, - isSilentPayment: coin is BitcoinSilentPaymentsUnspent, - ); - await unspentCoinsInfo.add(newInfo); + // Check if the coin is already in the unspentCoinsInfo for the wallet + final existingCoinInfo = unspentCoinsInfo.values.firstWhereOrNull( + (element) => element.walletId == walletInfo.id && element == coin); + + if (existingCoinInfo == null) { + final newInfo = UnspentCoinsInfo( + walletId: id, + hash: coin.hash, + isFrozen: coin.isFrozen, + isSending: coin.isSending, + noteRaw: coin.note, + address: coin.bitcoinAddressRecord.address, + value: coin.value, + vout: coin.vout, + isChange: coin.isChange, + isSilentPayment: coin is BitcoinSilentPaymentsUnspent, + ); + + await unspentCoinsInfo.add(newInfo); + } } Future _refreshUnspentCoinsInfo() async { @@ -1486,6 +1496,23 @@ abstract class ElectrumWalletBase } } + Future cleanUpDuplicateUnspentCoins() async { + final currentWalletUnspentCoins = unspentCoinsInfo.values.where((element) => element.walletId == id); + final Map uniqueUnspentCoins = {}; + final List duplicateKeys = []; + + for (final unspentCoin in currentWalletUnspentCoins) { + final key = '${unspentCoin.hash}:${unspentCoin.vout}'; + if (!uniqueUnspentCoins.containsKey(key)) { + uniqueUnspentCoins[key] = unspentCoin; + } else { + duplicateKeys.add(unspentCoin.key); + } + } + + if (duplicateKeys.isNotEmpty) await unspentCoinsInfo.deleteAll(duplicateKeys); + } + int transactionVSize(String transactionHex) => BtcTransaction.fromRaw(transactionHex).getVSize(); Future canReplaceByFee(ElectrumTransactionInfo tx) async { diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart index d519f4d0a..89ae384d4 100644 --- a/cw_bitcoin/lib/litecoin_wallet_service.dart +++ b/cw_bitcoin/lib/litecoin_wallet_service.dart @@ -126,6 +126,15 @@ class LitecoinWalletService extends WalletService< mwebdLogs.deleteSync(); } } + + final unspentCoinsToDelete = unspentCoinsInfoSource.values.where( + (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList(); + + final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList(); + + if (keysToDelete.isNotEmpty) { + await unspentCoinsInfoSource.deleteAll(keysToDelete); + } } @override diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart index d14dc582d..931893ef8 100644 --- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart +++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart @@ -85,6 +85,15 @@ class BitcoinCashWalletService extends WalletService< final walletInfo = walletInfoSource.values .firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!; await walletInfoSource.delete(walletInfo.key); + + final unspentCoinsToDelete = unspentCoinsInfoSource.values.where( + (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList(); + + final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList(); + + if (keysToDelete.isNotEmpty) { + await unspentCoinsInfoSource.deleteAll(keysToDelete); + } } @override diff --git a/cw_core/lib/unspent_coins_info.dart b/cw_core/lib/unspent_coins_info.dart index ed09e17e0..a60feb634 100644 --- a/cw_core/lib/unspent_coins_info.dart +++ b/cw_core/lib/unspent_coins_info.dart @@ -1,10 +1,11 @@ import 'package:cw_core/hive_type_ids.dart'; +import 'package:cw_core/unspent_comparable_mixin.dart'; import 'package:hive/hive.dart'; part 'unspent_coins_info.g.dart'; @HiveType(typeId: UnspentCoinsInfo.typeId) -class UnspentCoinsInfo extends HiveObject { +class UnspentCoinsInfo extends HiveObject with UnspentComparable { UnspentCoinsInfo({ required this.walletId, required this.hash, diff --git a/cw_core/lib/unspent_comparable_mixin.dart b/cw_core/lib/unspent_comparable_mixin.dart new file mode 100644 index 000000000..ee0c05496 --- /dev/null +++ b/cw_core/lib/unspent_comparable_mixin.dart @@ -0,0 +1,27 @@ +mixin UnspentComparable { + String get address; + + String get hash; + + int get value; + + int get vout; + + String? get keyImage; + + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is UnspentComparable && + other.hash == hash && + other.address == address && + other.value == value && + other.vout == vout && + other.keyImage == keyImage; + } + + @override + int get hashCode { + return Object.hash(address, hash, value, vout, keyImage); + } +} diff --git a/cw_core/lib/unspent_transaction_output.dart b/cw_core/lib/unspent_transaction_output.dart index d225493e9..da71f6983 100644 --- a/cw_core/lib/unspent_transaction_output.dart +++ b/cw_core/lib/unspent_transaction_output.dart @@ -1,4 +1,6 @@ -class Unspent { +import 'package:cw_core/unspent_comparable_mixin.dart'; + +class Unspent with UnspentComparable { Unspent(this.address, this.hash, this.value, this.vout, this.keyImage) : isSending = true, isFrozen = false, diff --git a/lib/src/screens/unspent_coins/unspent_coins_list_page.dart b/lib/src/screens/unspent_coins/unspent_coins_list_page.dart index ee6d6dc73..f26a2a17f 100644 --- a/lib/src/screens/unspent_coins/unspent_coins_list_page.dart +++ b/lib/src/screens/unspent_coins/unspent_coins_list_page.dart @@ -1,13 +1,14 @@ -import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart'; +import 'package:cake_wallet/src/widgets/alert_with_no_action.dart.dart'; +import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:mobx/mobx.dart'; class UnspentCoinsListPage extends BasePage { UnspentCoinsListPage({required this.unspentCoinsListViewModel}); @@ -15,16 +16,53 @@ class UnspentCoinsListPage extends BasePage { @override String get title => S.current.unspent_coins_title; + @override + Widget leading(BuildContext context) { + return MergeSemantics( + child: SizedBox( + height: 37, + width: 37, + child: ButtonTheme( + minWidth: double.minPositive, + child: Semantics( + label: S.of(context).seed_alert_back, + child: TextButton( + style: ButtonStyle( + overlayColor: WidgetStateColor.resolveWith((states) => Colors.transparent), + ), + onPressed: () async => await handleOnPopInvoked(context), + child: backButton(context), + ), + ), + ), + ), + ); + } + final UnspentCoinsListViewModel unspentCoinsListViewModel; + Future handleOnPopInvoked(BuildContext context) async { + final hasChanged = unspentCoinsListViewModel.hasAdjustableFieldChanged; + if (unspentCoinsListViewModel.items.isEmpty || !hasChanged) { + Navigator.of(context).pop(); + } else { + unspentCoinsListViewModel.setIsDisposing(true); + await unspentCoinsListViewModel.dispose(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } + } + @override - Widget body(BuildContext context) => UnspentCoinsListForm(unspentCoinsListViewModel); + Widget body(BuildContext context) => + UnspentCoinsListForm(unspentCoinsListViewModel, handleOnPopInvoked); } class UnspentCoinsListForm extends StatefulWidget { - UnspentCoinsListForm(this.unspentCoinsListViewModel); + UnspentCoinsListForm(this.unspentCoinsListViewModel, this.handleOnPopInvoked); final UnspentCoinsListViewModel unspentCoinsListViewModel; + final Future Function(BuildContext context) handleOnPopInvoked; @override UnspentCoinsListFormState createState() => UnspentCoinsListFormState(unspentCoinsListViewModel); @@ -35,36 +73,126 @@ class UnspentCoinsListFormState extends State { final UnspentCoinsListViewModel unspentCoinsListViewModel; + late Future _initialization; + ReactionDisposer? _disposer; + + @override + void initState() { + super.initState(); + _initialization = unspentCoinsListViewModel.initialSetup(); + _setupReactions(); + } + + void _setupReactions() { + _disposer = reaction( + (_) => unspentCoinsListViewModel.isDisposing, + (isDisposing) { + if (isDisposing) { + _showSavingDataAlert(); + } + }, + ); + } + + void _showSavingDataAlert() { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertWithNoAction( + alertContent: 'Updating, please wait…', + alertBarrierDismissible: false, + ); + }, + ); + } + + @override + void dispose() { + _disposer?.call(); + super.dispose(); + } + @override Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.fromLTRB(24, 12, 24, 24), - child: Observer( - builder: (_) => ListView.separated( - itemCount: unspentCoinsListViewModel.items.length, - separatorBuilder: (_, __) => SizedBox(height: 15), - itemBuilder: (_, int index) { - return Observer(builder: (_) { - final item = unspentCoinsListViewModel.items[index]; + return PopScope( + canPop: false, + onPopInvokedWithResult: (bool didPop, Object? result) async { + if (didPop) return; + if(mounted) + await widget.handleOnPopInvoked(context); + }, + child: FutureBuilder( + future: _initialization, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator()); + } - return GestureDetector( - onTap: () => Navigator.of(context).pushNamed(Routes.unspentCoinsDetails, - arguments: [item, unspentCoinsListViewModel]), - child: UnspentCoinsListItem( - note: item.note, - amount: item.amount, - address: item.address, - isSending: item.isSending, - isFrozen: item.isFrozen, - isChange: item.isChange, - isSilentPayment: item.isSilentPayment, - onCheckBoxTap: item.isFrozen - ? null - : () async { - item.isSending = !item.isSending; - await unspentCoinsListViewModel.saveUnspentCoinInfo(item); - })); - }); - }))); + if (snapshot.hasError) return Center(child: Text('Failed to load unspent coins')); + + return Container( + padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), + child: Observer( + builder: (_) => Column( + children: [ + if (unspentCoinsListViewModel.items.isNotEmpty) + Row( + children: [ + SizedBox(width: 12), + StandardCheckbox( + iconColor: Theme.of(context).extension()!.buttonTextColor, + value: unspentCoinsListViewModel.isAllSelected, + onChanged: (value) => unspentCoinsListViewModel.toggleSelectAll(value), + ), + SizedBox(width: 12), + Text( + S.current.all_coins, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + ], + ), + SizedBox(height: 15), + Expanded( + child: unspentCoinsListViewModel.items.isEmpty + ? Center(child: Text('No unspent coins available\ntry to reconnect',textAlign: TextAlign.center)) + : ListView.separated( + itemCount: unspentCoinsListViewModel.items.length, + separatorBuilder: (_, __) => SizedBox(height: 15), + itemBuilder: (_, int index) { + final item = unspentCoinsListViewModel.items[index]; + return Observer( + builder: (_) => GestureDetector( + onTap: () => Navigator.of(context).pushNamed( + Routes.unspentCoinsDetails, + arguments: [item, unspentCoinsListViewModel], + ), + child: UnspentCoinsListItem( + note: item.note, + amount: item.amount, + address: item.address, + isSending: item.isSending, + isFrozen: item.isFrozen, + isChange: item.isChange, + isSilentPayment: item.isSilentPayment, + onCheckBoxTap: item.isFrozen + ? null + : () async { + item.isSending = !item.isSending; + await unspentCoinsListViewModel + .saveUnspentCoinInfo(item); + }, + ), + ), + ); + }, + ), + ), + ], + ), + ), + ); + }, + ), + ); } } diff --git a/lib/src/widgets/alert_with_no_action.dart.dart b/lib/src/widgets/alert_with_no_action.dart.dart index 623656397..75c1785cd 100644 --- a/lib/src/widgets/alert_with_no_action.dart.dart +++ b/lib/src/widgets/alert_with_no_action.dart.dart @@ -3,18 +3,18 @@ import 'package:cake_wallet/src/widgets/base_alert_dialog.dart'; class AlertWithNoAction extends BaseAlertDialog { AlertWithNoAction({ - required this.alertTitle, + this.alertTitle, required this.alertContent, this.alertBarrierDismissible = true, Key? key, }); - final String alertTitle; + final String? alertTitle; final String alertContent; final bool alertBarrierDismissible; @override - String get titleText => alertTitle; + String? get titleText => alertTitle; @override String get contentText => alertContent; @@ -26,5 +26,5 @@ class AlertWithNoAction extends BaseAlertDialog { bool get isBottomDividerExists => false; @override - Widget actionButtons(BuildContext context) => Container(height: 60); + Widget actionButtons(BuildContext context) => Container(); } diff --git a/lib/src/widgets/base_alert_dialog.dart b/lib/src/widgets/base_alert_dialog.dart index 1b521a427..53b7a9cbf 100644 --- a/lib/src/widgets/base_alert_dialog.dart +++ b/lib/src/widgets/base_alert_dialog.dart @@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; class BaseAlertDialog extends StatelessWidget { String? get headerText => ''; - String get titleText => ''; + String? get titleText => ''; String get contentText => ''; @@ -43,7 +43,7 @@ class BaseAlertDialog extends StatelessWidget { Widget title(BuildContext context) { return Text( - titleText, + titleText!, textAlign: TextAlign.center, style: TextStyle( fontSize: 20, @@ -191,10 +191,11 @@ class BaseAlertDialog extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ if (headerText?.isNotEmpty ?? false) headerTitle(context), + titleText != null ? Padding( padding: EdgeInsets.fromLTRB(24, 20, 24, 0), child: title(context), - ), + ) : SizedBox(height: 16), isDividerExists ? Padding( padding: EdgeInsets.only(top: 16, bottom: 8), diff --git a/lib/view_model/unspent_coins/unspent_coins_item.dart b/lib/view_model/unspent_coins/unspent_coins_item.dart index 4ca5a10a2..70488f8ee 100644 --- a/lib/view_model/unspent_coins/unspent_coins_item.dart +++ b/lib/view_model/unspent_coins/unspent_coins_item.dart @@ -1,10 +1,11 @@ +import 'package:cw_core/unspent_comparable_mixin.dart'; import 'package:mobx/mobx.dart'; part 'unspent_coins_item.g.dart'; class UnspentCoinsItem = UnspentCoinsItemBase with _$UnspentCoinsItem; -abstract class UnspentCoinsItemBase with Store { +abstract class UnspentCoinsItemBase with Store, UnspentComparable { UnspentCoinsItemBase({ required this.address, required this.amount, @@ -13,7 +14,7 @@ abstract class UnspentCoinsItemBase with Store { required this.note, required this.isSending, required this.isChange, - required this.amountRaw, + required this.value, required this.vout, required this.keyImage, required this.isSilentPayment, @@ -41,7 +42,7 @@ abstract class UnspentCoinsItemBase with Store { bool isChange; @observable - int amountRaw; + int value; @observable int vout; diff --git a/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart b/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart index f16b8390f..6c15511b5 100644 --- a/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart +++ b/lib/view_model/unspent_coins/unspent_coins_list_view_model.dart @@ -10,6 +10,7 @@ import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/cupertino.dart'; import 'package:hive/hive.dart'; +import 'package:collection/collection.dart'; import 'package:mobx/mobx.dart'; part 'unspent_coins_list_view_model.g.dart'; @@ -22,55 +23,66 @@ abstract class UnspentCoinsListViewModelBase with Store { required Box unspentCoinsInfo, this.coinTypeToSpendFrom = UnspentCoinType.any, }) : _unspentCoinsInfo = unspentCoinsInfo, - _items = ObservableList() { - _updateUnspentCoinsInfo(); - _updateUnspents(); - } + items = ObservableList(), + _originalState = {}; - WalletBase wallet; + final WalletBase wallet; final Box _unspentCoinsInfo; final UnspentCoinType coinTypeToSpendFrom; @observable - ObservableList _items; + ObservableList items; + + final Map> _originalState; + + @observable + bool isDisposing = false; @computed - ObservableList get items => _items; + bool get isAllSelected => items.every((element) => element.isFrozen || element.isSending); - Future saveUnspentCoinInfo(UnspentCoinsItem item) async { - try { - final info = - getUnspentCoinInfo(item.hash, item.address, item.amountRaw, item.vout, item.keyImage); + Future initialSetup() async { + await _updateUnspents(); + _storeOriginalState(); + } - if (info == null) { - return; - } - - info.isFrozen = item.isFrozen; - info.isSending = item.isSending; - info.note = item.note; - - await info.save(); - await _updateUnspents(); - await wallet.updateBalance(); - } catch (e) { - print(e.toString()); + void _storeOriginalState() { + _originalState.clear(); + for (final item in items) { + _originalState[item.hash] = { + 'isFrozen': item.isFrozen, + 'note': item.note, + 'isSending': item.isSending, + }; } } - UnspentCoinsInfo? getUnspentCoinInfo( - String hash, String address, int value, int vout, String? keyImage) { + bool _hasAdjustableFieldChanged(UnspentCoinsItem item) { + final original = _originalState[item.hash]; + if (original == null) return false; + return original['isFrozen'] != item.isFrozen || + original['note'] != item.note || + original['isSending'] != item.isSending; + } + + bool get hasAdjustableFieldChanged => items.any(_hasAdjustableFieldChanged); + + + Future saveUnspentCoinInfo(UnspentCoinsItem item) async { try { - return _unspentCoinsInfo.values.firstWhere((element) => - element.walletId == wallet.id && - element.hash == hash && - element.address == address && - element.value == value && - element.vout == vout && - element.keyImage == keyImage); + final existingInfo = _unspentCoinsInfo.values + .firstWhereOrNull((element) => element.walletId == wallet.id && element == item); + if (existingInfo == null) return; + + existingInfo.isFrozen = item.isFrozen; + existingInfo.isSending = item.isSending; + existingInfo.note = item.note; + + + await existingInfo.save(); + _updateUnspentCoinsInfo(); } catch (e) { - print("UnspentCoinsInfo not found for coin: $e"); - return null; + print('Error saving coin info: $e'); } } @@ -115,37 +127,60 @@ abstract class UnspentCoinsListViewModelBase with Store { @action void _updateUnspentCoinsInfo() { - _items.clear(); + items.clear(); - List unspents = []; - _getUnspents().forEach((Unspent elem) { - try { - final info = - getUnspentCoinInfo(elem.hash, elem.address, elem.value, elem.vout, elem.keyImage); - if (info == null) { - return; - } + final unspents = _getUnspents() + .map((elem) { + try { + final existingItem = _unspentCoinsInfo.values + .firstWhereOrNull((item) => item.walletId == wallet.id && item == elem); - unspents.add(UnspentCoinsItem( - address: elem.address, - amount: '${formatAmountToString(elem.value)} ${wallet.currency.title}', - hash: elem.hash, - isFrozen: info.isFrozen, - note: info.note, - isSending: info.isSending, - amountRaw: elem.value, - vout: elem.vout, - keyImage: elem.keyImage, - isChange: elem.isChange, - isSilentPayment: info.isSilentPayment ?? false, - )); - } catch (e, s) { - print(s); - print(e.toString()); - ExceptionHandler.onError(FlutterErrorDetails(exception: e, stack: s)); - } - }); + if (existingItem == null) return null; - _items.addAll(unspents); + return UnspentCoinsItem( + address: elem.address, + amount: '${formatAmountToString(elem.value)} ${wallet.currency.title}', + hash: elem.hash, + isFrozen: existingItem.isFrozen, + note: existingItem.note, + isSending: existingItem.isSending, + value: elem.value, + vout: elem.vout, + keyImage: elem.keyImage, + isChange: elem.isChange, + isSilentPayment: existingItem.isSilentPayment ?? false, + ); + } catch (e, s) { + print('Error: $e\nStack: $s'); + ExceptionHandler.onError( + FlutterErrorDetails(exception: e, stack: s), + ); + return null; + } + }) + .whereType() + .toList(); + + unspents.sort((a, b) => b.value.compareTo(a.value)); + + items.addAll(unspents); + } + + @action + void toggleSelectAll(bool value) { + for (final item in items) { + if (item.isFrozen || item.isSending == value) continue; + item.isSending = value; + saveUnspentCoinInfo(item); + } + } + + @action + void setIsDisposing(bool value) => isDisposing = value; + + @action + Future dispose() async { + await _updateUnspents(); + await wallet.updateBalance(); } } diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 25a3d5fa5..968f627ca 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -38,6 +38,7 @@ "agree_to": "من خلال إنشاء حساب فإنك توافق على", "alert_notice": "يلاحظ", "all": "الكل", + "all_coins": "كل العملات المعدنية", "all_trades": "جميع عمليات التداول", "all_transactions": "كل التحركات المالية", "alphabetical": "مرتب حسب الحروف الأبجدية", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index ef3dc48df..24a7cf803 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -38,6 +38,7 @@ "agree_to": "Чрез създаването на акаунт вие се съгласявате с ", "alert_notice": "Забележете", "all": "ALL", + "all_coins": "Всички монети", "all_trades": "Всички сделкки", "all_transactions": "Всички транзакции", "alphabetical": "Азбучен ред", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 1e8e9eff6..6626a3119 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -38,6 +38,7 @@ "agree_to": "Vytvořením účtu souhlasíte s ", "alert_notice": "Oznámení", "all": "VŠE", + "all_coins": "Všechny mince", "all_trades": "Všechny obchody", "all_transactions": "Všechny transakce", "alphabetical": "Abecední", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 871301833..78431ff5f 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -38,6 +38,7 @@ "agree_to": "Indem Sie ein Konto erstellen, stimmen Sie den ", "alert_notice": "Beachten", "all": "ALLES", + "all_coins": "Alle Münzen", "all_trades": "Alle Trades", "all_transactions": "Alle Transaktionen", "alphabetical": "Alphabetisch", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 057bc6d6b..8acf49d76 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -38,6 +38,7 @@ "agree_to": "By creating account you agree to the ", "alert_notice": "Notice", "all": "ALL", + "all_coins": "All Coins", "all_trades": "All trades", "all_transactions": "All transactions", "alphabetical": "Alphabetical", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index c9135f054..3c009c5ea 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -38,6 +38,7 @@ "agree_to": "Al crear una cuenta, aceptas ", "alert_notice": "Aviso", "all": "Todos", + "all_coins": "Todas las monedas", "all_trades": "Todos los oficios", "all_transactions": "Todas las transacciones", "alphabetical": "Alfabético", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index eaeac58a9..17408cd44 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -38,6 +38,7 @@ "agree_to": "En créant un compte, vous acceptez les ", "alert_notice": "Avis", "all": "TOUT", + "all_coins": "Toutes les pièces", "all_trades": "Tous échanges", "all_transactions": "Toutes transactions", "alphabetical": "Alphabétique", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 6a0713d6d..2fa206298 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -38,6 +38,7 @@ "agree_to": "Ta hanyar ƙirƙirar asusu kun yarda da", "alert_notice": "Sanarwa", "all": "DUK", + "all_coins": "Duk tsabar kudi", "all_trades": "Duk ciniki", "all_transactions": "Dukan Ma'amaloli", "alphabetical": "Harafi", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index f1e294d22..f31635c75 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -38,6 +38,7 @@ "agree_to": "खाता बनाकर आप इससे सहमत होते हैं ", "alert_notice": "सूचना", "all": "सब", + "all_coins": "सभी सिक्के", "all_trades": "सभी व्यापार", "all_transactions": "सभी लेन - देन", "alphabetical": "वर्णमाला", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 6b9f20259..17f161ce3 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -38,6 +38,7 @@ "agree_to": "Stvaranjem računa pristajete na ", "alert_notice": "Obavijest", "all": "SVE", + "all_coins": "Sve kovanice", "all_trades": "Svi obrti", "all_transactions": "Sve transakcije", "alphabetical": "Abecedno", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index d3d7987d2..8736f1fc2 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -38,6 +38,7 @@ "agree_to": "Ստեղծելով հաշիվ դուք համաձայնում եք ", "alert_notice": "Ծանուցում", "all": "Բոլորը", + "all_coins": "Բոլոր մետաղադրամները", "all_trades": "Բոլոր գործարքները", "all_transactions": "Բոլոր գործառնությունները", "alphabetical": "Այբբենական", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index fae208549..44a04ae9b 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -38,6 +38,7 @@ "agree_to": "Dengan membuat akun Anda setuju dengan ", "alert_notice": "Melihat", "all": "SEMUA", + "all_coins": "Semua koin", "all_trades": "Semua perdagangan", "all_transactions": "Semua transaksi", "alphabetical": "Alfabetis", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index e6e4928c5..44358c450 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -38,6 +38,7 @@ "agree_to": "Creando un account accetti il ​​", "alert_notice": "Avviso", "all": "TUTTO", + "all_coins": "Tutte le monete", "all_trades": "Svi obrti", "all_transactions": "Sve transakcije", "alphabetical": "Alfabetico", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index fd4d83cc8..6bcde5a09 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -38,6 +38,7 @@ "agree_to": "アカウントを作成することにより、", "alert_notice": "知らせ", "all": "すべて", + "all_coins": "すべてのコイン", "all_trades": "すべての取引", "all_transactions": "全取引", "alphabetical": "アルファベット順", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 6fce665ec..b18657bc9 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -38,6 +38,7 @@ "agree_to": "계정을 생성하면 ", "alert_notice": "알아채다", "all": "모든", + "all_coins": "모든 동전", "all_trades": "A모든 거래", "all_transactions": "모든 거래 창구", "alphabetical": "알파벳순", @@ -495,8 +496,8 @@ "placeholder_transactions": "거래가 여기에 표시됩니다", "please_fill_totp": "다른 기기에 있는 8자리 코드를 입력하세요.", "please_make_selection": "아래에서 선택하십시오 지갑 만들기 또는 복구.", - "Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", "please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", + "Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", "please_select": "선택 해주세요:", "please_select_backup_file": "백업 파일을 선택하고 백업 암호를 입력하십시오.", "please_try_to_connect_to_another_node": "다른 노드에 연결을 시도하십시오", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index e933010fd..45bad4d13 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -38,6 +38,7 @@ "agree_to": "အကောင့်ဖန်တီးခြင်းဖြင့် သင်သည် ဤအရာကို သဘောတူပါသည်။", "alert_notice": "မှတ်သား", "all": "အားလုံး", + "all_coins": "အားလုံးဒင်္ဂါးများ", "all_trades": "ကုန်သွယ်မှုအားလုံး", "all_transactions": "အရောင်းအဝယ်အားလုံး", "alphabetical": "အက္ခရာစဉ်", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index fc6496c3f..c332956c6 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -38,6 +38,7 @@ "agree_to": "Door een account aan te maken gaat u akkoord met de ", "alert_notice": "Kennisgeving", "all": "ALLE", + "all_coins": "Alle munten", "all_trades": "Alle transacties", "all_transactions": "Alle transacties", "alphabetical": "Alfabetisch", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index c7cf09cd8..26cbf7ac7 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -38,6 +38,7 @@ "agree_to": "Tworząc konto wyrażasz zgodę na ", "alert_notice": "Ogłoszenie", "all": "WSZYSTKO", + "all_coins": "Wszystkie monety", "all_trades": "Wszystkie operacje", "all_transactions": "Wszystkie transakcje", "alphabetical": "Alfabetyczny", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 50c7f4d6c..74d0d3cf5 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -38,6 +38,7 @@ "agree_to": "Ao criar conta você concorda com ", "alert_notice": "Perceber", "all": "TUDO", + "all_coins": "Todas as moedas", "all_trades": "Todas as negociações", "all_transactions": "Todas as transacções", "alphabetical": "alfabética", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 639ddfe63..d454bddbe 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -38,6 +38,7 @@ "agree_to": "Создавая аккаунт, вы соглашаетесь с ", "alert_notice": "Уведомление", "all": "ВСЕ", + "all_coins": "Все монеты", "all_trades": "Все сделки", "all_transactions": "Все транзакции", "alphabetical": "Алфавитный", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index e0b352fea..b9c51258e 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -38,6 +38,7 @@ "agree_to": "การสร้างบัญชีของคุณยอมรับเงื่อนไขของ", "alert_notice": "สังเกต", "all": "ทั้งหมด", + "all_coins": "เหรียญทั้งหมด", "all_trades": "การซื้อขายทั้งหมด", "all_transactions": "การทำธุรกรรมทั้งหมด", "alphabetical": "ตามตัวอักษร", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 5f05e3d51..45080b80d 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -38,6 +38,7 @@ "agree_to": "Sa pamamagitan ng paggawa ng account sumasang-ayon ka sa ", "alert_notice": "PAUNAWA", "all": "LAHAT", + "all_coins": "Lahat ng mga barya", "all_trades": "Lahat ng mga trade", "all_transactions": "Lahat ng mga transaksyon", "alphabetical": "Alpabeto", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 80990ae2d..6e990ab09 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -38,6 +38,7 @@ "agree_to": "Hesap oluşturarak bunları kabul etmiş olursunuz ", "alert_notice": "Fark etme", "all": "HEPSİ", + "all_coins": "Tüm Paralar", "all_trades": "Tüm takaslar", "all_transactions": "Tüm transferler", "alphabetical": "Alfabetik", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index b2d7a22e5..c66b7e4d7 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -38,6 +38,7 @@ "agree_to": "Створюючи обліковий запис, ви погоджуєтеся з ", "alert_notice": "Ув'язнення", "all": "ВСЕ", + "all_coins": "Всі монети", "all_trades": "Всі операції", "all_transactions": "Всі транзакції", "alphabetical": "Алфавітний", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 289bfb958..3da895eae 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -38,6 +38,7 @@ "agree_to": "اکاؤنٹ بنا کر آپ اس سے اتفاق کرتے ہیں۔", "alert_notice": "نوٹس", "all": "تمام", + "all_coins": "تمام سکے", "all_trades": "تمام تجارت", "all_transactions": "تمام لین دین", "alphabetical": "حروف تہجی کے مطابق", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index e7c95b8ec..9003be56c 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -38,6 +38,7 @@ "agree_to": "Bằng cách tạo tài khoản, bạn đồng ý với ", "alert_notice": "Để ý", "all": "TẤT CẢ", + "all_coins": "Tất cả các đồng tiền", "all_trades": "Tất cả giao dịch", "all_transactions": "Tất cả giao dịch", "alphabetical": "Theo thứ tự chữ cái", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index c9b8c4cbd..fdb574432 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -38,6 +38,7 @@ "agree_to": "Tẹ́ ẹ bá dá àkáǹtì ẹ jọ rò ", "alert_notice": "Akiyesi", "all": "Gbogbo", + "all_coins": "Gbogbo awọn owó", "all_trades": "Gbogbo àwọn pàṣípààrọ̀", "all_transactions": "Gbogbo àwọn àránṣẹ́", "alphabetical": "Labidibi", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 37b35ea6d..b75b4be68 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -38,6 +38,7 @@ "agree_to": "创建账户即表示您同意 ", "alert_notice": "注意", "all": "全部", + "all_coins": "所有硬币", "all_trades": "所有的变化", "all_transactions": "所有交易", "alphabetical": "按字母顺序", From 63f26c034f63012f77e4aa6a9875ed016987d3fb Mon Sep 17 00:00:00 2001 From: Rafael Date: Thu, 28 Nov 2024 13:50:30 -0300 Subject: [PATCH 28/41] [Cakepay] alert iOS availability (#1837) * feat: alert iOS availability * feat: use regex, check iOS --- lib/cake_pay/cake_pay_api.dart | 12 ++-- lib/cake_pay/cake_pay_service.dart | 5 +- .../cards/cake_pay_buy_card_page.dart | 67 ++++++++++++++++++- res/values/strings_ar.arb | 1 + res/values/strings_bg.arb | 1 + res/values/strings_cs.arb | 1 + res/values/strings_de.arb | 1 + res/values/strings_en.arb | 1 + res/values/strings_es.arb | 1 + res/values/strings_fr.arb | 1 + res/values/strings_ha.arb | 1 + res/values/strings_hi.arb | 1 + res/values/strings_hr.arb | 1 + res/values/strings_hy.arb | 1 + res/values/strings_id.arb | 1 + res/values/strings_it.arb | 1 + res/values/strings_ja.arb | 1 + res/values/strings_ko.arb | 1 + res/values/strings_my.arb | 1 + res/values/strings_nl.arb | 1 + res/values/strings_pl.arb | 1 + res/values/strings_pt.arb | 1 + res/values/strings_ru.arb | 1 + res/values/strings_th.arb | 1 + res/values/strings_tl.arb | 1 + res/values/strings_tr.arb | 1 + res/values/strings_uk.arb | 1 + res/values/strings_ur.arb | 1 + res/values/strings_vi.arb | 1 + res/values/strings_yo.arb | 1 + res/values/strings_zh.arb | 1 + 31 files changed, 100 insertions(+), 12 deletions(-) diff --git a/lib/cake_pay/cake_pay_api.dart b/lib/cake_pay/cake_pay_api.dart index a39fbe085..ea44d3335 100644 --- a/lib/cake_pay/cake_pay_api.dart +++ b/lib/cake_pay/cake_pay_api.dart @@ -172,14 +172,12 @@ class CakePayApi { } /// Get Countries - Future> getCountries( - {required String CSRFToken, required String authorization}) async { + Future> getCountries({required String apiKey}) async { final uri = Uri.https(baseCakePayUri, countriesPath); final headers = { 'accept': 'application/json', - 'authorization': authorization, - 'X-CSRFToken': CSRFToken, + 'Authorization': 'Api-Key $apiKey', }; final response = await http.get(uri, headers: headers); @@ -198,8 +196,7 @@ class CakePayApi { /// Get Vendors Future> getVendors({ - required String CSRFToken, - required String authorization, + required String apiKey, int? page, String? country, String? countryCode, @@ -226,8 +223,7 @@ class CakePayApi { var headers = { 'accept': 'application/json; charset=UTF-8', - 'authorization': authorization, - 'X-CSRFToken': CSRFToken, + 'Authorization': 'Api-Key $apiKey', }; var response = await http.get(uri, headers: headers); diff --git a/lib/cake_pay/cake_pay_service.dart b/lib/cake_pay/cake_pay_service.dart index cf2ec254c..9e43c23c7 100644 --- a/lib/cake_pay/cake_pay_service.dart +++ b/lib/cake_pay/cake_pay_service.dart @@ -25,7 +25,7 @@ class CakePayService { /// Get Available Countries Future> getCountries() async => - await cakePayApi.getCountries(CSRFToken: CSRFToken, authorization: authorization); + await cakePayApi.getCountries(apiKey: cakePayApiKey); /// Get Vendors Future> getVendors({ @@ -40,8 +40,7 @@ class CakePayService { bool? custom, }) async { final result = await cakePayApi.getVendors( - CSRFToken: CSRFToken, - authorization: authorization, + apiKey: cakePayApiKey, page: page, country: country, countryCode: countryCode, diff --git a/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart index 6e1af1c32..21e35359b 100644 --- a/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart +++ b/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:auto_size_text/auto_size_text.dart'; import 'package:cake_wallet/cake_pay/cake_pay_card.dart'; import 'package:cake_wallet/cake_pay/cake_pay_payment_credantials.dart'; @@ -7,6 +9,7 @@ import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/cake_pay/widgets/image_placeholder.dart'; import 'package:cake_wallet/src/screens/cake_pay/widgets/link_extractor.dart'; +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/number_text_fild_widget.dart'; @@ -17,6 +20,7 @@ import 'package:cake_wallet/themes/extensions/keyboard_theme.dart'; import 'package:cake_wallet/themes/extensions/send_page_theme.dart'; import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/cake_pay/cake_pay_buy_card_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dropdown_filter_item_widget.dart'; import 'package:flutter/material.dart'; @@ -226,7 +230,9 @@ class CakePayBuyCardPage extends BasePage { return Padding( padding: EdgeInsets.only(bottom: 12), child: PrimaryButton( - onPressed: () => navigateToCakePayBuyCardDetailPage(context, card), + onPressed: () => isIOSUnavailable(card) + ? alertIOSAvailability(context, card) + : navigateToCakePayBuyCardDetailPage(context, card), text: S.of(context).buy_now, isDisabled: !cakePayBuyCardViewModel.isEnablePurchase, color: Theme.of(context).primaryColor, @@ -241,6 +247,65 @@ class CakePayBuyCardPage extends BasePage { ); } + bool isWordInCardsName(CakePayCard card, String word) { + // word must be followed by a space or beginning of the string + final regex = RegExp(r'(^|\s)' + word + r'(\s|$)', caseSensitive: false); + + return regex.hasMatch(card.name.toLowerCase()); + } + + bool isIOSUnavailable(CakePayCard card) { + if (!Platform.isIOS) { + return false; + } + + final isDigitalGameStores = isWordInCardsName(card, 'playstation') || + isWordInCardsName(card, 'xbox') || + isWordInCardsName(card, 'steam') || + isWordInCardsName(card, 'meta quest') || + isWordInCardsName(card, 'kigso') || + isWordInCardsName(card, 'game world') || + isWordInCardsName(card, 'google') || + isWordInCardsName(card, 'nintendo'); + final isGCodes = isWordInCardsName(card, 'gcodes'); + final isApple = isWordInCardsName(card, 'itunes') || isWordInCardsName(card, 'apple'); + final isTidal = isWordInCardsName(card, 'tidal'); + final isVPNServices = isWordInCardsName(card, 'nordvpn') || + isWordInCardsName(card, 'expressvpn') || + isWordInCardsName(card, 'surfshark') || + isWordInCardsName(card, 'proton'); + final isStreamingServices = isWordInCardsName(card, 'netflix') || + isWordInCardsName(card, 'spotify') || + isWordInCardsName(card, 'hulu') || + isWordInCardsName(card, 'hbo') || + isWordInCardsName(card, 'soundcloud') || + isWordInCardsName(card, 'twitch'); + final isDatingServices = isWordInCardsName(card, 'tinder'); + + return isDigitalGameStores || + isGCodes || + isApple || + isTidal || + isVPNServices || + isStreamingServices || + isDatingServices; + } + + Future alertIOSAvailability(BuildContext context, CakePayCard card) async { + return await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithOneAction( + alertTitle: S.of(context).error, + alertContent: S.of(context).cakepay_ios_not_available, + buttonText: S.of(context).ok, + buttonAction: () { + // _walletHardwareRestoreVM.error = null; + Navigator.of(context).pop(); + }); + }); + } + Future navigateToCakePayBuyCardDetailPage(BuildContext context, CakePayCard card) async { final userName = await cakePayService.getUserEmail(); final paymentCredential = PaymentCredential( diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 968f627ca..6a5ecf6ae 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "اشتري بطاقات مدفوعة مسبقا وبطاقات هدايا في جميع أنحاء العالم", "cake_pay_web_cards_title": "بطاقات Cake Pay Web", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "آسف ، بطاقة الهدايا هذه غير متوفرة على iOS. يمكنك شرائه على Android أو من خلال موقعنا بدلاً من ذلك.", "cakepay_prepaid_card": "بطاقة ائتمان CakePay مسبقة الدفع", "camera_consent": ".ﻞﻴﺻﺎﻔﺘﻟﺍ ﻰﻠﻋ ﻝﻮﺼﺤﻠﻟ ﻢﻬﺑ ﺔﺻﺎﺨﻟﺍ ﺔﻴﺻﻮﺼﺨﻟﺍ ﺔﺳﺎﻴﺳ ﻦﻣ ﻖﻘﺤﺘﻟﺍ ﻰﺟﺮﻳ .${provider} ﻝﻮﻠ", "camera_permission_is_required": ".ﺍﺮﻴﻣﺎﻜﻟﺍ ﻥﺫﺇ ﺏﻮﻠﻄﻣ", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 24a7cf803..11182d1d7 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Купете световно признати предплатени и гифт карти", "cake_pay_web_cards_title": "Cake Pay Онлайн Карти", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "За съжаление тази карта за подарък не се предлага в iOS. Можете да го закупите на Android или чрез нашия уебсайт вместо това.", "cakepay_prepaid_card": "CakePay предплатена дебитна карта", "camera_consent": "Вашият фотоапарат ще бъде използван за заснемане на изображение с цел идентификация от ${provider}. Моля, проверете тяхната политика за поверителност за подробности.", "camera_permission_is_required": "Изисква се разрешение за камерата.\nМоля, активирайте го от настройките на приложението.", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 6626a3119..57ab06a61 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Kupte si celosvětové předplacené a dárkové karty", "cake_pay_web_cards_title": "Cake Pay webové karty", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Je nám líto, tato dárková karta není k dispozici na iOS. Místo toho si jej můžete zakoupit na Androidu nebo prostřednictvím našeho webu.", "cakepay_prepaid_card": "CakePay předplacená debetní karta", "camera_consent": "Váš fotoaparát použije k pořízení snímku pro účely identifikace ${provider}. Podrobnosti najdete v jejich Zásadách ochrany osobních údajů.", "camera_permission_is_required": "Vyžaduje se povolení fotoaparátu.\nPovolte jej v nastavení aplikace.", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 78431ff5f..ffdbfb11d 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Kaufen Sie weltweit Prepaid-Karten und Geschenkkarten", "cake_pay_web_cards_title": "Cake Pay-Webkarten", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Entschuldigung, diese Geschenkkarte ist auf iOS nicht erhältlich. Sie können es stattdessen auf Android oder über unsere Website kaufen.", "cakepay_prepaid_card": "CakePay-Prepaid-Debitkarte", "camera_consent": "Mit Ihrer Kamera wird bis zum ${provider} ein Bild zur Identifizierung aufgenommen. Weitere Informationen finden Sie in deren Datenschutzbestimmungen.", "camera_permission_is_required": "Eine Kameraerlaubnis ist erforderlich.\nBitte aktivieren Sie es in den App-Einstellungen.", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 8acf49d76..bbf6e7d8e 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Buy worldwide prepaid cards and gift cards", "cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Sorry, this gift card is not available on iOS. You can purchase it on Android or through our website instead.", "cakepay_prepaid_card": "CakePay Prepaid Debit Card", "camera_consent": "Your camera will be used to capture an image for identification purposes by ${provider}. Please check their Privacy Policy for details.", "camera_permission_is_required": "Camera permission is required. \nPlease enable it from app settings.", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 3c009c5ea..2e9445db5 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Compra tarjetas de prepago y tarjetas de regalo en todo el mundo", "cake_pay_web_cards_title": "Tarjetas Web Cake Pay", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Lo siento, esta tarjeta de regalo no está disponible en iOS. Puede comprarlo en Android o a través de nuestro sitio web.", "cakepay_prepaid_card": "Tarjeta de Débito Prepago CakePay", "camera_consent": "Su cámara será utilizada para capturar una imagen con fines de identificación por ${provider}. Consulta tu Política de privacidad para obtener más detalles.", "camera_permission_is_required": "Se requiere permiso de la cámara.\nHabilítalo desde la configuración de la aplicación.", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 17408cd44..245736406 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Achetez des cartes prépayées et des cartes-cadeaux dans le monde entier", "cake_pay_web_cards_title": "Cartes Web Cake Pay", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Désolé, cette carte-cadeau n'est pas disponible sur iOS. Vous pouvez l'acheter sur Android ou via notre site Web à la place.", "cakepay_prepaid_card": "Carte de débit prépayée Cake Pay", "camera_consent": "Votre appareil photo sera utilisé pour capturer une image à des fins d'identification par ${provider}. Veuillez consulter leur politique de confidentialité pour plus de détails.", "camera_permission_is_required": "L'autorisation de la caméra est requise.\nVeuillez l'activer à partir des paramètres de l'application.", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 2fa206298..6492e5f5f 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Sayi katunan da aka riga aka biya na duniya da katunan kyauta", "cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Yi haƙuri, wannan katin kyautar ba a samuwa akan iOS. Kuna iya sayan shi a kan Android ko ta yanar gizo a maimakon.", "cakepay_prepaid_card": "Katin zare kudi na CakePay", "camera_consent": "Za a yi amfani da kyamarar ku don ɗaukar hoto don dalilai na tantancewa ta ${provider}. Da fatan za a duba Manufar Sirri don cikakkun bayanai.", "camera_permission_is_required": "Ana buƙatar izinin kyamara.\nDa fatan za a kunna shi daga saitunan app.", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index f31635c75..e21f4c418 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "दुनिया भर में प्रीपेड कार्ड और गिफ्ट कार्ड खरीदें", "cake_pay_web_cards_title": "केक भुगतान वेब कार्ड", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "क्षमा करें, यह उपहार कार्ड iOS पर उपलब्ध नहीं है। आप इसे Android पर या हमारी वेबसाइट के बजाय खरीद सकते हैं।", "cakepay_prepaid_card": "केकपे प्रीपेड डेबिट कार्ड", "camera_consent": "आपके कैमरे का उपयोग ${provider} द्वारा पहचान उद्देश्यों के लिए एक छवि कैप्चर करने के लिए किया जाएगा। विवरण के लिए कृपया उनकी गोपनीयता नीति जांचें।", "camera_permission_is_required": "कैमरे की अनुमति आवश्यक है.\nकृपया इसे ऐप सेटिंग से सक्षम करें।", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 17f161ce3..bd0caa15e 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Kupujte prepaid kartice i poklon kartice diljem svijeta", "cake_pay_web_cards_title": "Cake Pay Web kartice", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Oprostite, ova poklon kartica nije dostupna na iOS -u. Umjesto toga, možete ga kupiti na Androidu ili putem naše web stranice.", "cakepay_prepaid_card": "CakePay unaprijed plaćena debitna kartica", "camera_consent": "Vaš će fotoaparat koristiti za snimanje slike u svrhu identifikacije od strane ${provider}. Pojedinosti potražite u njihovoj politici privatnosti.", "camera_permission_is_required": "Potrebno je dopuštenje kamere.\nOmogućite ga u postavkama aplikacije.", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 8736f1fc2..1900ac459 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Գնեք համաշխարհային նախավճարային քարտեր և նվեր քարտեր", "cake_pay_web_cards_title": "Cake Pay Վեբ Քարտեր", "cake_wallet": "Cake Գաղտնապահոց", + "cakepay_ios_not_available": "Ներեցեք, այս նվեր քարտը հասանելի չէ iOS- ում: Փոխարենը կարող եք այն գնել Android- ում կամ մեր կայքում:", "cakepay_prepaid_card": "CakePay Նախավճարային Դեբետային Քարտ", "camera_consent": "Ձեր տեսախցիկը կօգտագործվի ${provider}-ի կողմից ինքնությունը հաստատելու նպատակով: Խնդրում ենք ծանոթանալ նրանց Գաղտնիության Քաղաքականության հետ:", "camera_permission_is_required": "Տեսախցիկի թույլտվություն է պահանջվում: \nԽնդրում ենք այն ակտիվացնել հավելվածի կարգավորումներից:", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 44a04ae9b..04ff42395 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Beli kartu prabayar dan kartu hadiah secara global", "cake_pay_web_cards_title": "Kartu Web Cake Pay", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Maaf, kartu hadiah ini tidak tersedia di iOS. Anda dapat membelinya di Android atau melalui situs web kami sebagai gantinya.", "cakepay_prepaid_card": "Kartu Debit Prabayar CakePay", "camera_consent": "Kamera Anda akan digunakan untuk mengambil gambar untuk tujuan identifikasi oleh ${provider}. Silakan periksa Kebijakan Privasi mereka untuk detailnya.", "camera_permission_is_required": "Izin kamera diperlukan.\nSilakan aktifkan dari pengaturan aplikasi.", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 44358c450..6bac1d008 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Acquista carte prepagate e carte regalo in tutto il mondo", "cake_pay_web_cards_title": "Carte Web Cake Pay", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Mi dispiace, questa carta regalo non è disponibile su iOS. Puoi acquistarlo su Android o tramite il nostro sito Web.", "cakepay_prepaid_card": "Carta di debito prepagata CakePay", "camera_consent": "La tua fotocamera verrà utilizzata per acquisire un'immagine a scopo identificativo da ${provider}. Si prega di controllare la loro Informativa sulla privacy per i dettagli.", "camera_permission_is_required": "È richiesta l'autorizzazione della fotocamera.\nAbilitalo dalle impostazioni dell'app.", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 6bcde5a09..72f9e0203 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "世界中のプリペイド カードとギフト カードを購入する", "cake_pay_web_cards_title": "Cake Pay ウェブカード", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "申し訳ありませんが、このギフトカードはiOSでは利用できません。代わりにAndroidまたは当社のWebサイトから購入できます。", "cakepay_prepaid_card": "CakePayプリペイドデビットカード", "camera_consent": "あなたのカメラは、${provider}_ までに識別目的で画像を撮影するために使用されます。詳細については、プライバシー ポリシーをご確認ください。", "camera_permission_is_required": "カメラの許可が必要です。\nアプリの設定から有効にしてください。", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index b18657bc9..45db37781 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "전 세계 선불 카드 및 기프트 카드 구매", "cake_pay_web_cards_title": "케이크페이 웹카드", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "죄송합니다.이 기프트 카드는 iOS에서 사용할 수 없습니다. Android 또는 웹 사이트를 통해 구매할 수 있습니다.", "cakepay_prepaid_card": "CakePay 선불 직불 카드", "camera_consent": "귀하의 카메라는 ${provider}의 식별 목적으로 이미지를 캡처하는 데 사용됩니다. 자세한 내용은 해당 개인정보 보호정책을 확인하세요.", "camera_permission_is_required": "카메라 권한이 필요합니다.\n앱 설정에서 활성화해 주세요.", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 45bad4d13..76fa28477 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "ကမ္ဘာတစ်ဝှမ်း ကြိုတင်ငွေပေးကတ်များနှင့် လက်ဆောင်ကတ်များကို ဝယ်ယူပါ။", "cake_pay_web_cards_title": "Cake Pay ဝဘ်ကတ်များ", "cake_wallet": "Cake ပိုက်ဆံအိတ်", + "cakepay_ios_not_available": "တောင်းပန်ပါတယ်, ဒီလက်ဆောင်ကဒ်ကို iOS မှာမရနိုင်ပါ။ ၎င်းကို Android တွင်သို့မဟုတ်ကျွန်ုပ်တို့၏ဝက်ဘ်ဆိုက်တွင် 0 ယ်နိုင်သည်။", "cakepay_prepaid_card": "CakePay ကြိုတင်ငွေဖြည့်ဒက်ဘစ်ကတ်", "camera_consent": "မှတ်ပုံတင်ခြင်းရည်ရွယ်ချက်များအတွက် ${provider} တွင် သင့်ကင်မရာကို အသုံးပြုပါမည်။ အသေးစိတ်အတွက် ၎င်းတို့၏ ကိုယ်ရေးကိုယ်တာမူဝါဒကို စစ်ဆေးပါ။", "camera_permission_is_required": "ကင်မရာခွင့်ပြုချက် လိုအပ်ပါသည်။\nအက်ပ်ဆက်တင်များမှ ၎င်းကိုဖွင့်ပါ။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index c332956c6..659f78baa 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Koop wereldwijd prepaidkaarten en cadeaubonnen", "cake_pay_web_cards_title": "Cake Pay-webkaarten", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Sorry, deze cadeaubon is niet beschikbaar op iOS. U kunt het in plaats daarvan kopen op Android of via onze website.", "cakepay_prepaid_card": "CakePay Prepaid Debetkaart", "camera_consent": "Uw camera wordt gebruikt om vóór ${provider} een beeld vast te leggen voor identificatiedoeleinden. Raadpleeg hun privacybeleid voor meer informatie.", "camera_permission_is_required": "Cameratoestemming is vereist.\nSchakel dit in via de app-instellingen.", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 26cbf7ac7..9d8f94651 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Kupuj na całym świecie karty przedpłacone i karty podarunkowe", "cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Przepraszam, ta karta podarunkowa nie jest dostępna na iOS. Zamiast tego możesz go kupić na Android lub za pośrednictwem naszej strony internetowej.", "cakepay_prepaid_card": "Przedpłacona karta debetowa CakePay", "camera_consent": "Twój aparat zostanie użyty do przechwycenia obrazu w celach identyfikacyjnych przez ${provider}. Aby uzyskać szczegółowe informacje, sprawdź ich Politykę prywatności.", "camera_permission_is_required": "Wymagane jest pozwolenie na korzystanie z aparatu.\nWłącz tę funkcję w ustawieniach aplikacji.", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 74d0d3cf5..df03bd405 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Compre cartões pré-pagos e cartões-presente em todo o mundo", "cake_pay_web_cards_title": "Cartões Cake Pay Web", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Desculpe, este cartão -presente não está disponível no iOS. Você pode comprá -lo no Android ou através do nosso site.", "cakepay_prepaid_card": "Cartão de débito pré-pago CakePay", "camera_consent": "Sua câmera será usada para capturar uma imagem para fins de identificação por ${provider}. Por favor, verifique a Política de Privacidade para obter detalhes.", "camera_permission_is_required": "É necessária permissão da câmera.\nAtive-o nas configurações do aplicativo.", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index d454bddbe..5197bd29c 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Покупайте карты предоплаты и подарочные карты по всему миру", "cake_pay_web_cards_title": "Веб-карты Cake Pay", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Извините, эта подарочная карта недоступна на iOS. Вместо этого вы можете приобрести его на Android или через наш веб -сайт.", "cakepay_prepaid_card": "Предоплаченная дебетовая карта CakePay", "camera_consent": "Ваша камера будет использоваться для захвата изображения в целях идентификации ${provider}. Пожалуйста, ознакомьтесь с их Политикой конфиденциальности для получения подробной информации.", "camera_permission_is_required": "Требуется разрешение камеры.\nПожалуйста, включите его в настройках приложения.", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index b9c51258e..dabd90506 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "ซื้อบัตรพร้อมเงินระดับโลกและบัตรของขวัญ", "cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "ขออภัยบัตรของขวัญนี้ไม่มีใน iOS คุณสามารถซื้อได้บน Android หรือผ่านเว็บไซต์ของเราแทน", "cakepay_prepaid_card": "บัตรเดบิตเติมเงินของ CakePay", "camera_consent": "กล้องของคุณจะถูกนำมาใช้เพื่อจับภาพเพื่อวัตถุประสงค์ในการระบุตัวตนภายใน ${provider} โปรดตรวจสอบนโยบายความเป็นส่วนตัวเพื่อดูรายละเอียด", "camera_permission_is_required": "ต้องได้รับอนุญาตจากกล้อง\nโปรดเปิดใช้งานจากการตั้งค่าแอป", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 45080b80d..94be4ca80 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Bumili ng mga pandaigdigang prepaid card at gift card", "cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Paumanhin, ang gift card na ito ay hindi magagamit sa iOS. Maaari mo itong bilhin sa Android o sa pamamagitan ng aming website sa halip.", "cakepay_prepaid_card": "CakePay Prepaid Debit Card", "camera_consent": "Gagamitin ang iyong camera upang kumuha ng larawan para sa mga layunin ng pagkakakilanlan sa pamamagitan ng ${provider}. Pakisuri ang kanilang Patakaran sa Privacy para sa mga detalye.", "camera_permission_is_required": "Kinakailangan ang pahintulot sa camera.\nMangyaring paganahin ito mula sa mga setting ng app.", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 6e990ab09..e02d7cf25 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Dünya çapında ön ödemeli kartlar ve hediye kartları satın alın", "cake_pay_web_cards_title": "Cake Pay Web Kartları", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Üzgünüm, bu hediye kartı iOS'ta mevcut değil. Bunun yerine Android'de veya web sitemizden satın alabilirsiniz.", "cakepay_prepaid_card": "CakePay Ön Ödemeli Kart", "camera_consent": "Kameranız ${provider} tarihine kadar tanımlama amacıyla bir görüntü yakalamak için kullanılacaktır. Ayrıntılar için lütfen Gizlilik Politikalarını kontrol edin.", "camera_permission_is_required": "Kamera izni gereklidir.\nLütfen uygulama ayarlarından etkinleştirin.", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index c66b7e4d7..bfa4475ae 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Купуйте передоплачені та подарункові картки по всьому світу", "cake_pay_web_cards_title": "Веб-картки Cake Pay", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Вибачте, ця подарункова карта недоступна на iOS. Ви можете придбати його на Android або через наш веб -сайт.", "cakepay_prepaid_card": "Передплачена дебетова картка CakePay", "camera_consent": "Ваша камера використовуватиметься для зйомки зображення з метою ідентифікації ${provider}. Будь ласка, ознайомтеся з їхньою політикою конфіденційності, щоб дізнатися більше.", "camera_permission_is_required": "Потрібен дозвіл камери.\nУвімкніть його в налаштуваннях програми.", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 3da895eae..27f66c57a 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "دنیا بھر میں پری پیڈ کارڈز اور گفٹ کارڈز خریدیں۔", "cake_pay_web_cards_title": "Cake پے ویب کارڈز", "cake_wallet": "Cake والیٹ", + "cakepay_ios_not_available": "معذرت ، یہ گفٹ کارڈ iOS پر دستیاب نہیں ہے۔ اس کے بجائے آپ اسے اینڈروئیڈ پر یا ہماری ویب سائٹ کے ذریعے خرید سکتے ہیں۔", "cakepay_prepaid_card": "Cake پے پری پیڈ ڈیبٹ کارڈ", "camera_consent": "۔ﮟﯿﮭﮑﯾﺩ ﯽﺴﯿﻟﺎﭘ ﯽﺴﯾﻮﯿﺋﺍﺮﭘ ﯽﮐ ﻥﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ﮯﯿﻟ ﮯﮐ ﺕﻼ${provider}ﯿﺼﻔﺗ ۔ﺎﮔ ﮯﺋﺎﺟ ﺎﯿﮐ ﻝﺎﻤﻌﺘﺳﺍ ﮯﯿﻟ", "camera_permission_is_required": "۔ﮯﮨ ﺭﺎﮐﺭﺩ ﺕﺯﺎﺟﺍ ﯽﮐ ﮮﺮﻤﯿﮐ", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index 9003be56c..949e40c09 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Mua thẻ trả trước toàn cầu và thẻ quà tặng", "cake_pay_web_cards_title": "Thẻ Cake Pay Web", "cake_wallet": "Ví Cake", + "cakepay_ios_not_available": "Xin lỗi, thẻ quà tặng này không có sẵn trên iOS. Thay vào đó, bạn có thể mua nó trên Android hoặc thông qua trang web của chúng tôi.", "cakepay_prepaid_card": "Thẻ Ghi Nợ Trả Trước CakePay", "camera_consent": "Máy ảnh của bạn sẽ được sử dụng để chụp hình nhằm mục đích xác minh danh tính bởi ${provider}. Vui lòng kiểm tra Chính sách quyền riêng tư của họ để biết thêm chi tiết.", "camera_permission_is_required": "Cần có quyền truy cập máy ảnh. \nVui lòng bật nó từ cài đặt ứng dụng.", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index fdb574432..5a206afb2 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "Ra àwọn káàdì ìrajà t'á lò nínú ìtajà kan àti àwọn káàdì náà t'á lè lò níbikíbi", "cake_pay_web_cards_title": "Àwọn káàdì wẹ́ẹ̀bù ti Cake Pay", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "Ma binu, kaadi ẹbun yii ko wa lori iOS. O le ra lori Android tabi nipasẹ oju opo wẹẹbu wa dipo.", "cakepay_prepaid_card": "Káàdì ìrajà ti CakePay", "camera_consent": "Kamẹra rẹ yoo ṣee lo lati ya aworan kan fun awọn idi idanimọ nipasẹ ${provider}. Jọwọ ṣayẹwo Ilana Aṣiri wọn fun awọn alaye.", "camera_permission_is_required": "A nilo igbanilaaye kamẹra.\nJọwọ jeki o lati app eto.", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index b75b4be68..83c86bda8 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -102,6 +102,7 @@ "cake_pay_web_cards_subtitle": "购买全球预付卡和礼品卡", "cake_pay_web_cards_title": "蛋糕支付网络卡", "cake_wallet": "Cake Wallet", + "cakepay_ios_not_available": "抱歉,这张礼品卡在iOS上不可用。您可以在Android或通过我们的网站上购买它。", "cakepay_prepaid_card": "CakePay 预付借记卡", "camera_consent": "${provider} 将使用您的相机拍摄图像以供识别之用。请查看他们的隐私政策了解详情。", "camera_permission_is_required": "需要相机许可。\n请从应用程序设置中启用它。", From d8d41906084d2ee6ef0bcc1e5fcd18da024eeac1 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 28 Nov 2024 21:02:10 +0200 Subject: [PATCH 29/41] prevent calling unsupported payment method (#1836) --- lib/buy/robinhood/robinhood_buy_provider.dart | 3 ++- lib/view_model/buy/buy_sell_view_model.dart | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/buy/robinhood/robinhood_buy_provider.dart b/lib/buy/robinhood/robinhood_buy_provider.dart index e8de5a59c..a64c9d736 100644 --- a/lib/buy/robinhood/robinhood_buy_provider.dart +++ b/lib/buy/robinhood/robinhood_buy_provider.dart @@ -145,7 +145,7 @@ class RobinhoodBuyProvider extends BuyProvider { if (paymentType != null && paymentType != PaymentType.all) { paymentMethod = normalizePaymentMethod(paymentType); - if (paymentMethod == null) paymentMethod = paymentType.name; + if (paymentMethod == null) return null; } final action = isBuyAction ? 'buy' : 'sell'; @@ -185,6 +185,7 @@ class RobinhoodBuyProvider extends BuyProvider { return null; } + // Supported payment methods: // ● buying_power // ● crypto_balance // ● debit_card diff --git a/lib/view_model/buy/buy_sell_view_model.dart b/lib/view_model/buy/buy_sell_view_model.dart index 4d7151fac..d16307134 100644 --- a/lib/view_model/buy/buy_sell_view_model.dart +++ b/lib/view_model/buy/buy_sell_view_model.dart @@ -155,13 +155,11 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S final hasSelectedPaymentMethod = selectedPaymentMethod != null; final isPaymentMethodLoaded = paymentMethodState is PaymentMethodLoaded; final isBuySellQuotLoaded = buySellQuotState is BuySellQuotLoaded; - final isBuySellQuotFailed = buySellQuotState is BuySellQuotFailed; return hasSelectedQuote && hasSelectedPaymentMethod && isPaymentMethodLoaded && - isBuySellQuotLoaded && - !isBuySellQuotFailed; + isBuySellQuotLoaded; } @computed From 17d34beae95e5caf4942a5a177331b604a96a1e4 Mon Sep 17 00:00:00 2001 From: cyan Date: Thu, 28 Nov 2024 20:28:31 +0100 Subject: [PATCH 30/41] CW-782: Show error report popup without cooldown (#1739) * improve exception throwing on broken wallets - put _lastOpenedWallet to avoid issues on windows (file is currently open by) - don't throw corruptedWalletsSeed - instead store it inside of secureStorage - await ExceptionHandler.onError calls where possible to makse sure that popup won't be canceled by some UI element - adjust BaseAlertDialog to be scrollable if the text is too long - add ExceptionHandler.resetLastPopupDate - that can be called when we want to show error report screen (bypassing cooldown) * fix: HiveError: Box has already been closed. * await the alerts to be sure that each one of them is being shown fix typo in secure storage * Update lib/core/backup_service.dart Co-authored-by: Omar Hatem * address comments on github * don't store seeds in secure storage * fix wallet password * update monero_c update corrupted seeds UI prevent app from crashing when wallet is corrupted * show alert with seeds * Update corrupted wallet UI Fix wallet opening cache * remove unused code --------- Co-authored-by: Omar Hatem --- cw_monero/lib/api/wallet_manager.dart | 15 +++- cw_monero/lib/monero_wallet_service.dart | 2 +- cw_monero/pubspec.lock | 4 +- cw_monero/pubspec.yaml | 2 +- cw_wownero/pubspec.lock | 4 +- cw_wownero/pubspec.yaml | 2 +- lib/anypay/anypay_api.dart | 2 +- lib/core/backup_service.dart | 18 ++--- lib/core/wallet_loading_service.dart | 64 +++++++++++++--- lib/di.dart | 6 +- lib/main.dart | 2 +- .../on_authentication_state_change.dart | 6 +- lib/src/screens/auth/auth_page.dart | 23 +++++- lib/src/screens/backup/backup_page.dart | 2 +- .../desktop_wallet_selection_dropdown.dart | 1 + .../screens/wallet_list/wallet_list_page.dart | 5 ++ lib/src/widgets/base_alert_dialog.dart | 25 ++++--- lib/utils/exception_handler.dart | 73 +++++++++++-------- .../restore_from_backup_view_model.dart | 2 +- linux/flutter/generated_plugins.cmake | 1 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 - res/values/strings_ar.arb | 1 + res/values/strings_bg.arb | 1 + res/values/strings_cs.arb | 1 + res/values/strings_de.arb | 1 + res/values/strings_en.arb | 1 + res/values/strings_es.arb | 1 + res/values/strings_fr.arb | 1 + res/values/strings_ha.arb | 1 + res/values/strings_hi.arb | 1 + res/values/strings_hr.arb | 1 + res/values/strings_hy.arb | 1 + res/values/strings_id.arb | 1 + res/values/strings_it.arb | 1 + res/values/strings_ja.arb | 1 + res/values/strings_ko.arb | 1 + res/values/strings_my.arb | 1 + res/values/strings_nl.arb | 1 + res/values/strings_pl.arb | 1 + res/values/strings_pt.arb | 1 + res/values/strings_ru.arb | 1 + res/values/strings_th.arb | 1 + res/values/strings_tl.arb | 1 + res/values/strings_tr.arb | 1 + res/values/strings_uk.arb | 1 + res/values/strings_ur.arb | 1 + res/values/strings_vi.arb | 1 + res/values/strings_yo.arb | 1 + res/values/strings_zh.arb | 1 + scripts/prepare_moneroc.sh | 2 +- windows/flutter/generated_plugins.cmake | 1 - 51 files changed, 205 insertions(+), 87 deletions(-) diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart index d10f7e25a..3a47132c5 100644 --- a/cw_monero/lib/api/wallet_manager.dart +++ b/cw_monero/lib/api/wallet_manager.dart @@ -81,6 +81,7 @@ void createWalletSync( wptr = newWptr; monero.Wallet_store(wptr!, path: path); openedWalletsByPath[path] = wptr!; + _lastOpenedWallet = path; // is the line below needed? // setupNodeSync(address: "node.moneroworld.com:18089"); @@ -116,6 +117,7 @@ void restoreWalletFromSeedSync( wptr = newWptr; openedWalletsByPath[path] = wptr!; + _lastOpenedWallet = path; } void restoreWalletFromKeysSync( @@ -183,6 +185,7 @@ void restoreWalletFromKeysSync( wptr = newWptr; openedWalletsByPath[path] = wptr!; + _lastOpenedWallet = path; } void restoreWalletFromSpendKeySync( @@ -231,6 +234,7 @@ void restoreWalletFromSpendKeySync( storeSync(); openedWalletsByPath[path] = wptr!; + _lastOpenedWallet = path; } String _lastOpenedWallet = ""; @@ -260,7 +264,7 @@ Future restoreWalletFromHardwareWallet( throw WalletRestoreFromSeedException(message: error); } wptr = newWptr; - + _lastOpenedWallet = path; openedWalletsByPath[path] = wptr!; } @@ -295,6 +299,11 @@ Future loadWallet( password: password, kdfRounds: 1, ); + final status = monero.WalletManager_errorString(wmPtr); + if (status != "") { + print("loadWallet:"+status); + throw WalletOpeningException(message: status); + } } else { deviceType = 0; } @@ -314,15 +323,15 @@ Future loadWallet( final newWptr = Pointer.fromAddress(newWptrAddr); - _lastOpenedWallet = path; final status = monero.Wallet_status(newWptr); if (status != 0) { final err = monero.Wallet_errorString(newWptr); - print(err); + print("loadWallet:"+err); throw WalletOpeningException(message: err); } wptr = newWptr; + _lastOpenedWallet = path; openedWalletsByPath[path] = wptr!; } } diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart index 6f49640be..0fb2e9aee 100644 --- a/cw_monero/lib/monero_wallet_service.dart +++ b/cw_monero/lib/monero_wallet_service.dart @@ -168,7 +168,7 @@ class MoneroWalletService extends WalletService< } await restoreOrResetWalletFiles(name); - return openWallet(name, password, retryOnFailure: false); + return await openWallet(name, password, retryOnFailure: false); } } diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index 551108adc..f4be439b7 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -503,8 +503,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 - resolved-ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 + ref: c41c4dad9aa5003a914cfb2c528c76386f952665 + resolved-ref: c41c4dad9aa5003a914cfb2c528c76386f952665 url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml index d8e506f58..36b002988 100644 --- a/cw_monero/pubspec.yaml +++ b/cw_monero/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: monero: git: url: https://github.com/mrcyjanek/monero_c - ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 + ref: c41c4dad9aa5003a914cfb2c528c76386f952665 # ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash path: impls/monero.dart mutex: ^3.1.0 diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock index 7e2c3c76f..c565348e1 100644 --- a/cw_wownero/pubspec.lock +++ b/cw_wownero/pubspec.lock @@ -463,8 +463,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 - resolved-ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 + ref: c41c4dad9aa5003a914cfb2c528c76386f952665 + resolved-ref: c41c4dad9aa5003a914cfb2c528c76386f952665 url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" diff --git a/cw_wownero/pubspec.yaml b/cw_wownero/pubspec.yaml index 48e65453a..fc5782645 100644 --- a/cw_wownero/pubspec.yaml +++ b/cw_wownero/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: monero: git: url: https://github.com/mrcyjanek/monero_c - ref: d72c15f4339791a7bbdf17e9d827b7b56ca144e4 + ref: c41c4dad9aa5003a914cfb2c528c76386f952665 # ref: 6eb571ea498ed7b854934785f00fabfd0dadf75b # monero_c hash path: impls/monero.dart mutex: ^3.1.0 diff --git a/lib/anypay/anypay_api.dart b/lib/anypay/anypay_api.dart index 8af3be08c..0b81d24c2 100644 --- a/lib/anypay/anypay_api.dart +++ b/lib/anypay/anypay_api.dart @@ -56,7 +56,7 @@ class AnyPayApi { final response = await post(url, headers: headers, body: utf8.encode(json.encode(body))); if (response.statusCode != 200) { - ExceptionHandler.onError(FlutterErrorDetails(exception: response)); + await ExceptionHandler.onError(FlutterErrorDetails(exception: response)); throw Exception('Unexpected response http code: ${response.statusCode}'); } diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart index 992ed6288..3413ec1d3 100644 --- a/lib/core/backup_service.dart +++ b/lib/core/backup_service.dart @@ -230,17 +230,15 @@ class BackupService { json.decode(transactionDescriptionFile.readAsStringSync()) as Map; final descriptionsMap = jsonData.map((key, value) => MapEntry(key, TransactionDescription.fromJson(value as Map))); - - if (!_transactionDescriptionBox.isOpen) { - final transactionDescriptionsBoxKey = await getEncryptionKey(secureStorage: secureStorageShared, forKey: TransactionDescription.boxKey); - final transactionDescriptionBox = await CakeHive.openBox( + var box = _transactionDescriptionBox; + if (!box.isOpen) { + final transactionDescriptionsBoxKey = + await getEncryptionKey(secureStorage: _secureStorage, forKey: TransactionDescription.boxKey); + box = await CakeHive.openBox( TransactionDescription.boxName, - encryptionKey: transactionDescriptionsBoxKey, - ); - await transactionDescriptionBox.putAll(descriptionsMap); - return; - } - await _transactionDescriptionBox.putAll(descriptionsMap); + encryptionKey: transactionDescriptionsBoxKey); + } + await box.putAll(descriptionsMap); } Future _importPreferencesDump() async { diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart index 10e438e0c..3a60197de 100644 --- a/lib/core/wallet_loading_service.dart +++ b/lib/core/wallet_loading_service.dart @@ -2,15 +2,22 @@ import 'dart:async'; import 'package:cake_wallet/core/generate_wallet_password.dart'; import 'package:cake_wallet/core/key_service.dart'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/reactions/on_authentication_state_change.dart'; +import 'package:cake_wallet/src/screens/auth/auth_page.dart'; +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/utils/exception_handler.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:shared_preferences/shared_preferences.dart'; class WalletLoadingService { @@ -58,24 +65,25 @@ class WalletLoadingService { return wallet; } catch (error, stack) { - ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); + await ExceptionHandler.resetLastPopupDate(); + await ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); // try fetching the seeds of the corrupted wallet to show it to the user String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):"; try { corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type); } catch (e) { - corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e"; + corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e"; } // try opening another wallet that is not corrupted to give user access to the app final walletInfoSource = await CakeHive.openBox(WalletInfo.boxName); - + WalletBase? wallet; for (var walletInfo in walletInfoSource.values) { try { final walletService = walletServiceFactory.call(walletInfo.type); - final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name)); - final wallet = await walletService.openWallet(walletInfo.name, walletPassword); + final walletPassword = await keyService.getWalletPassword(walletName: walletInfo.name); + wallet = await walletService.openWallet(walletInfo.name, walletPassword); if (walletInfo.type == WalletType.monero) { await updateMoneroWalletPassword(wallet); @@ -88,8 +96,6 @@ class WalletLoadingService { // if found a wallet that is not corrupted, then still display the seeds of the corrupted ones authenticatedErrorStreamController.add(corruptedWalletsSeeds); - - return wallet; } catch (e) { print(e); // save seeds and show corrupted wallets' seeds to the user @@ -99,16 +105,56 @@ class WalletLoadingService { corruptedWalletsSeeds += seeds; } } catch (e) { - corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e"; + corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e"; } } } // if all user's wallets are corrupted throw exception - throw error.toString() + "\n\n" + corruptedWalletsSeeds; + final msg = error.toString() + "\n" + corruptedWalletsSeeds; + if (navigatorKey.currentContext != null) { + await showPopUp( + context: navigatorKey.currentContext!, + builder: (BuildContext context) { + return AlertWithTwoActions( + alertTitle: "Corrupted seeds", + alertContent: S.of(context).corrupted_seed_notice, + leftButtonText: S.of(context).cancel, + rightButtonText: S.of(context).show_seed, + actionLeftButton: () => Navigator.of(context).pop(), + actionRightButton: () => showSeedsPopup(context, msg), + ); + }); + } else { + throw msg; + } + if (wallet == null) { + throw Exception("Wallet is null"); + } + return wallet; } } + Future showSeedsPopup(BuildContext context, String message) async { + Navigator.of(context).pop(); + await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithTwoActions( + alertTitle: "Corrupted seeds", + alertContent: message, + leftButtonText: S.of(context).copy, + rightButtonText: S.of(context).ok, + actionLeftButton: () async { + await Clipboard.setData(ClipboardData(text: message)); + }, + actionRightButton: () async { + Navigator.of(context).pop(); + }, + ); + }); + } + Future updateMoneroWalletPassword(WalletBase wallet) async { final key = PreferencesKey.moneroWalletUpdateV1Key(wallet.name); var isPasswordUpdated = sharedPreferences.getBool(key) ?? false; diff --git a/lib/di.dart b/lib/di.dart index 7b1cf3d07..6531c411f 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -575,7 +575,7 @@ Future setup({ totpAuthPageState.changeProcessText('Loading the wallet'); if (loginError != null) { - totpAuthPageState.changeProcessText('ERROR: ${loginError.toString()}'); + totpAuthPageState.changeProcessText('ERROR: ${loginError.toString()}'.trim()); } ReactionDisposer? _reaction; @@ -604,7 +604,7 @@ Future setup({ authPageState.changeProcessText('Loading the wallet'); if (loginError != null) { - authPageState.changeProcessText('ERROR: ${loginError.toString()}'); + authPageState.changeProcessText('ERROR: ${loginError.toString()}'.trim()); loginError = null; } @@ -624,7 +624,7 @@ Future setup({ } if (loginError != null) { - authPageState.changeProcessText('ERROR: ${loginError.toString()}'); + authPageState.changeProcessText('ERROR: ${loginError.toString()}'.trim()); timer.cancel(); } }); diff --git a/lib/main.dart b/lib/main.dart index d67fda098..72818a1d4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -89,7 +89,7 @@ Future runAppWithZone({Key? topLevelKey}) async { ); } - ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace)); + await ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace)); }); } diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart index b411c5a15..88b03ca59 100644 --- a/lib/reactions/on_authentication_state_change.dart +++ b/lib/reactions/on_authentication_state_change.dart @@ -43,8 +43,8 @@ void startAuthenticationStateChange( if (!requireHardwareWalletConnection()) await loadCurrentWallet(); } catch (error, stack) { loginError = error; - ExceptionHandler.onError( - FlutterErrorDetails(exception: error, stack: stack)); + await ExceptionHandler.resetLastPopupDate(); + await ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); } return; } @@ -81,7 +81,7 @@ void startAuthenticationStateChange( .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false); } if (!(await authenticatedErrorStreamController.stream.isEmpty)) { - ExceptionHandler.showError( + await ExceptionHandler.showError( (await authenticatedErrorStreamController.stream.first).toString()); authenticatedErrorStreamController.stream.drain(); } diff --git a/lib/src/screens/auth/auth_page.dart b/lib/src/screens/auth/auth_page.dart index d14a12527..e2bc1f075 100644 --- a/lib/src/screens/auth/auth_page.dart +++ b/lib/src/screens/auth/auth_page.dart @@ -1,5 +1,6 @@ import 'package:another_flushbar/flushbar.dart'; import 'package:cake_wallet/utils/show_bar.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:mobx/mobx.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; @@ -9,6 +10,8 @@ import 'package:cake_wallet/view_model/auth_view_model.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; import 'package:cake_wallet/core/execution_state.dart'; +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; +import 'package:flutter/services.dart'; typedef OnAuthenticationFinished = void Function(bool, AuthPageState); @@ -66,7 +69,6 @@ class AuthPagePinCodeStateImpl extends AuthPageState { dismissFlushBar(_authBar); showBar( context, S.of(context).failed_authentication(state.error)); - widget.onAuthenticationFinished(false, this); }); } @@ -77,12 +79,12 @@ class AuthPagePinCodeStateImpl extends AuthPageState { dismissFlushBar(_authBar); showBar( context, S.of(context).failed_authentication(state.error)); - widget.onAuthenticationFinished(false, this); }); } }); + if (widget.authViewModel.isBiometricalAuthenticationAllowed) { WidgetsBinding.instance.addPostFrameCallback((_) async { await Future.delayed(Duration(milliseconds: 100)); @@ -93,6 +95,23 @@ class AuthPagePinCodeStateImpl extends AuthPageState { super.initState(); } + Future _showSeedsPopup(BuildContext context, String message) async { + await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithTwoActions( + alertTitle: "Corrupted seeds", + alertContent: message, + leftButtonText: S.of(context).copy, + rightButtonText: S.of(context).ok, + actionLeftButton: () async { + await Clipboard.setData(ClipboardData(text: message)); + }, + actionRightButton: () => Navigator.of(context).pop(), + ); + }); + } + @override void dispose() { _reaction?.reaction.dispose(); diff --git a/lib/src/screens/backup/backup_page.dart b/lib/src/screens/backup/backup_page.dart index d17702724..b8065cf36 100644 --- a/lib/src/screens/backup/backup_page.dart +++ b/lib/src/screens/backup/backup_page.dart @@ -154,7 +154,7 @@ class BackupPage extends BasePage { File returnedFile = File(outputFile!); await returnedFile.writeAsBytes(backup.content); } catch (exception, stackTrace) { - ExceptionHandler.onError(FlutterErrorDetails( + await ExceptionHandler.onError(FlutterErrorDetails( exception: exception, stack: stackTrace, library: "Export Backup", diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart index 0fb629685..e5f38010d 100644 --- a/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart +++ b/lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart @@ -11,6 +11,7 @@ import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.da import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/themes/extensions/menu_theme.dart'; +import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart'; diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index 46eaa6143..f7e6515de 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -1,6 +1,7 @@ import 'package:another_flushbar/flushbar.dart'; import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/new_wallet_arguments.dart'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart'; import 'package:cake_wallet/entities/wallet_list_order_types.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -20,6 +21,7 @@ import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart'; +import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; @@ -459,6 +461,9 @@ class WalletListBodyState extends State { }); } } catch (e) { + await ExceptionHandler.resetLastPopupDate(); + final err = e.toString(); + await ExceptionHandler.onError(FlutterErrorDetails(exception: err)); if (this.mounted) { changeProcessText(S .of(context) diff --git a/lib/src/widgets/base_alert_dialog.dart b/lib/src/widgets/base_alert_dialog.dart index 53b7a9cbf..bede33ebf 100644 --- a/lib/src/widgets/base_alert_dialog.dart +++ b/lib/src/widgets/base_alert_dialog.dart @@ -73,15 +73,22 @@ class BaseAlertDialog extends StatelessWidget { } Widget content(BuildContext context) { - return Text( - contentText, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, - fontFamily: 'Lato', - color: Theme.of(context).extension()!.titleColor, - decoration: TextDecoration.none, + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + contentText, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + fontFamily: 'Lato', + color: Theme.of(context).extension()!.titleColor, + decoration: TextDecoration.none, + ), + ), + ], ), ); } diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart index 41ae91d41..6f1ed35a0 100644 --- a/lib/utils/exception_handler.dart +++ b/lib/utils/exception_handler.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/main.dart'; @@ -20,7 +21,7 @@ class ExceptionHandler { static const _coolDownDurationInDays = 7; static File? _file; - static void _saveException(String? error, StackTrace? stackTrace, {String? library}) async { + static Future _saveException(String? error, StackTrace? stackTrace, {String? library}) async { final appDocDir = await getAppDir(); if (_file == null) { @@ -90,7 +91,12 @@ class ExceptionHandler { } } - static void onError(FlutterErrorDetails errorDetails) async { + static Future resetLastPopupDate() async { + final sharedPrefs = await SharedPreferences.getInstance(); + await sharedPrefs.setString(PreferencesKey.lastPopupDate, DateTime(1971).toString()); + } + + static Future onError(FlutterErrorDetails errorDetails) async { if (kDebugMode || kProfileMode) { FlutterError.presentError(errorDetails); debugPrint(errorDetails.toString()); @@ -124,35 +130,40 @@ class ExceptionHandler { } _hasError = true; - sharedPrefs.setString(PreferencesKey.lastPopupDate, DateTime.now().toString()); + await sharedPrefs.setString(PreferencesKey.lastPopupDate, DateTime.now().toString()); - WidgetsBinding.instance.addPostFrameCallback( - (timeStamp) async { - if (navigatorKey.currentContext != null) { - await showPopUp( - context: navigatorKey.currentContext!, - builder: (context) { - return AlertWithTwoActions( - isDividerExist: true, - alertTitle: S.of(context).error, - alertContent: S.of(context).error_dialog_content, - rightButtonText: S.of(context).send, - leftButtonText: S.of(context).do_not_send, - actionRightButton: () { - Navigator.of(context).pop(); - _sendExceptionFile(); - }, - actionLeftButton: () { - Navigator.of(context).pop(); - }, - ); + // Instead of using WidgetsBinding.instance.addPostFrameCallback we + // await Future.delayed(Duration.zero), which does essentially the same ( + // but doesn't wait for actual frame to be rendered), but it allows us to + // properly await the execution - which is what we want, without awaiting + // other code may call functions like Navigator.pop(), and close the alert + // instead of the intended UI. + // WidgetsBinding.instance.addPostFrameCallback( + // (timeStamp) async { + await Future.delayed(Duration.zero); + if (navigatorKey.currentContext != null) { + await showPopUp( + context: navigatorKey.currentContext!, + builder: (context) { + return AlertWithTwoActions( + isDividerExist: true, + alertTitle: S.of(context).error, + alertContent: S.of(context).error_dialog_content, + rightButtonText: S.of(context).send, + leftButtonText: S.of(context).do_not_send, + actionRightButton: () { + Navigator.of(context).pop(); + _sendExceptionFile(); + }, + actionLeftButton: () { + Navigator.of(context).pop(); }, ); - } + }, + ); + } - _hasError = false; - }, - ); + _hasError = false; } /// Ignore User related errors or system errors @@ -272,20 +283,18 @@ class ExceptionHandler { }; } - static void showError(String error, {int? delayInSeconds}) async { + static Future showError(String error, {int? delayInSeconds}) async { if (_hasError) { return; } _hasError = true; - if (delayInSeconds != null) { Future.delayed(Duration(seconds: delayInSeconds), () => _showCopyPopup(error)); return; } - WidgetsBinding.instance.addPostFrameCallback( - (_) async => _showCopyPopup(error), - ); + await Future.delayed(Duration.zero); + await _showCopyPopup(error); } static Future _showCopyPopup(String content) async { diff --git a/lib/view_model/restore_from_backup_view_model.dart b/lib/view_model/restore_from_backup_view_model.dart index 432cac67e..247e6d43d 100644 --- a/lib/view_model/restore_from_backup_view_model.dart +++ b/lib/view_model/restore_from_backup_view_model.dart @@ -68,7 +68,7 @@ abstract class RestoreFromBackupViewModelBase with Store { if (msg.toLowerCase().contains("message authentication code (mac)")) { msg = 'Incorrect backup password'; } else { - ExceptionHandler.onError(FlutterErrorDetails( + await ExceptionHandler.onError(FlutterErrorDetails( exception: e, stack: s, library: this.toString(), diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index f52be7481..4b9eb3b2d 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 42b9fa84c..52b44e53e 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,6 @@ import FlutterMacOS import Foundation import connectivity_plus -import cw_mweb import device_info_plus import devicelocale import fast_scanner @@ -24,7 +23,6 @@ import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) - CwMwebPlugin.register(with: registry.registrar(forPlugin: "CwMwebPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 6a5ecf6ae..9c0774155 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -177,6 +177,7 @@ "copy_address": "نسخ العنوان", "copy_id": "نسخ معرف العملية", "copyWalletConnectLink": "ﺎﻨﻫ ﻪﻘﺼﻟﺍﻭ dApp ﻦﻣ WalletConnect ﻂﺑﺍﺭ ﺦﺴﻧﺍ", + "corrupted_seed_notice": "تالف ملفات هذه المحفظة ولا يمكن فتحها. يرجى الاطلاع على عبارة البذور وحفظها واستعادة المحفظة.\n\nإذا كانت القيمة فارغة ، لم تتمكن البذور من استردادها بشكل صحيح.", "countries": "بلدان", "create_account": "إنشاء حساب", "create_backup": "انشئ نسخة احتياطية", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 11182d1d7..dc57086c4 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -177,6 +177,7 @@ "copy_address": "Copy Address", "copy_id": "Копиране на ID", "copyWalletConnectLink": "Копирайте връзката WalletConnect от dApp и я поставете тук", + "corrupted_seed_notice": "Файловете за този портфейл са повредени и не могат да бъдат отворени. Моля, прегледайте фразата за семена, запазете я и възстановете портфейла.\n\nАко стойността е празна, тогава семето не успя да бъде правилно възстановено.", "countries": "Държави", "create_account": "Създаване на профил", "create_backup": "Създаване на резервно копие", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 57ab06a61..8702f8fe1 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -177,6 +177,7 @@ "copy_address": "Zkopírovat adresu", "copy_id": "Kopírovat ID", "copyWalletConnectLink": "Zkopírujte odkaz WalletConnect z dApp a vložte jej sem", + "corrupted_seed_notice": "Soubory pro tuto peněženku jsou poškozeny a nemohou být otevřeny. Podívejte se prosím na osivo, uložte ji a obnovte peněženku.\n\nPokud je hodnota prázdná, pak semeno nebylo možné správně obnovit.", "countries": "Země", "create_account": "Vytvořit účet", "create_backup": "Vytvořit zálohu", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index ffdbfb11d..c2dde5521 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -177,6 +177,7 @@ "copy_address": "Adresse kopieren", "copy_id": "ID kopieren", "copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein", + "corrupted_seed_notice": "Die Dateien für diese Brieftasche sind beschädigt und können nicht geöffnet werden. Bitte sehen Sie sich die Saatgutphrase an, speichern Sie sie und stellen Sie die Brieftasche wieder her.\n\nWenn der Wert leer ist, konnte der Samen nicht korrekt wiederhergestellt werden.", "countries": "Länder", "create_account": "Konto erstellen", "create_backup": "Backup erstellen", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index bbf6e7d8e..a971b797e 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -177,6 +177,7 @@ "copy_address": "Copy Address", "copy_id": "Copy ID", "copyWalletConnectLink": "Copy the WalletConnect link from dApp and paste here", + "corrupted_seed_notice": "The files for this wallet are corrupted and are unable to be opened. Please view the seed phrase, save it, and restore the wallet.\n\nIf the value is empty, then the seed was unable to be correctly recovered.", "countries": "Countries", "create_account": "Create Account", "create_backup": "Create backup", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 2e9445db5..990e3c154 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -177,6 +177,7 @@ "copy_address": "Copiar dirección ", "copy_id": "Copiar ID", "copyWalletConnectLink": "Copie el enlace de WalletConnect de dApp y péguelo aquí", + "corrupted_seed_notice": "Los archivos para esta billetera están dañados y no pueden abrirse. Vea la frase de semillas, guárdela y restaura la billetera.\n\nSi el valor está vacío, entonces la semilla no pudo recuperarse correctamente.", "countries": "Países", "create_account": "Crear Cuenta", "create_backup": "Crear copia de seguridad", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 245736406..6b0e58846 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -177,6 +177,7 @@ "copy_address": "Copier l'Adresse", "copy_id": "Copier l'ID", "copyWalletConnectLink": "Copiez le lien WalletConnect depuis l'application décentralisée (dApp) et collez-le ici", + "corrupted_seed_notice": "Les fichiers de ce portefeuille sont corrompus et ne peuvent pas être ouverts. Veuillez consulter la phrase de graines, sauver et restaurer le portefeuille.\n\nSi la valeur est vide, la graine n'a pas pu être correctement récupérée.", "countries": "Des pays", "create_account": "Créer un compte", "create_backup": "Créer une sauvegarde", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 6492e5f5f..8d2a66062 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -177,6 +177,7 @@ "copy_address": "Kwafi Adireshin", "copy_id": "Kwafi ID", "copyWalletConnectLink": "Kwafi hanyar haɗin WalletConnect daga dApp kuma liƙa a nan", + "corrupted_seed_notice": "Fayilolin don wannan walat ɗin sun lalata kuma ba za a iya buɗe su ba. Da fatan za a duba kalmar iri, adana shi, da dawo da walat.\n\nIdan darajar ta kasance fanko, to sai zuriyar da ba ta iya murmurewa daidai ba.", "countries": "Kasashe", "create_account": "Kirkira ajiya", "create_backup": "Ƙirƙiri madadin", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index e21f4c418..ceede03fb 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -177,6 +177,7 @@ "copy_address": "पता कॉपी करें", "copy_id": "प्रतिलिपि ID", "copyWalletConnectLink": "dApp से वॉलेटकनेक्ट लिंक को कॉपी करें और यहां पेस्ट करें", + "corrupted_seed_notice": "इस वॉलेट की फाइलें दूषित हैं और उन्हें खोलने में असमर्थ हैं। कृपया बीज वाक्यांश देखें, इसे बचाएं, और बटुए को पुनर्स्थापित करें।\n\nयदि मूल्य खाली है, तो बीज सही ढंग से पुनर्प्राप्त करने में असमर्थ था।", "countries": "देशों", "create_account": "खाता बनाएं", "create_backup": "बैकअप बनाएँ", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index bd0caa15e..f0ee38a9e 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -177,6 +177,7 @@ "copy_address": "Kopiraj adresu", "copy_id": "Kopirati ID", "copyWalletConnectLink": "Kopirajte vezu WalletConnect iz dApp-a i zalijepite je ovdje", + "corrupted_seed_notice": "Datoteke za ovaj novčanik su oštećene i nisu u mogućnosti otvoriti. Molimo pogledajte sjemensku frazu, spremite je i vratite novčanik.\n\nAko je vrijednost prazna, tada sjeme nije bilo u stanju ispravno oporaviti.", "countries": "Zemalja", "create_account": "Stvori račun", "create_backup": "Stvori sigurnosnu kopiju", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 1900ac459..d4abeaace 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -177,6 +177,7 @@ "copy_address": "Պատճենել հասցեն", "copy_id": "Պատճենել ID", "copyWalletConnectLink": "Պատճենել WalletConnect հղումը dApp-ից և տեղադրել այստեղ", + "corrupted_seed_notice": "Այս դրամապանակի համար ֆայլերը կոռումպացված են եւ չեն կարողանում բացվել: Խնդրում ենք դիտել սերմերի արտահայտությունը, պահպանել այն եւ վերականգնել դրամապանակը:\n\nԵթե ​​արժեքը դատարկ է, ապա սերմը չկարողացավ ճիշտ վերականգնվել:", "countries": "Երկրներ", "create_account": "Ստեղծել հաշիվ", "create_backup": "Ստեղծել կրկնօրինակ", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 04ff42395..022d31989 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -177,6 +177,7 @@ "copy_address": "Salin Alamat", "copy_id": "Salin ID", "copyWalletConnectLink": "Salin tautan WalletConnect dari dApp dan tempel di sini", + "corrupted_seed_notice": "File untuk dompet ini rusak dan tidak dapat dibuka. Silakan lihat frasa benih, simpan, dan kembalikan dompet.\n\nJika nilainya kosong, maka benih tidak dapat dipulihkan dengan benar.", "countries": "Negara", "create_account": "Buat Akun", "create_backup": "Buat cadangan", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 6bac1d008..62da65a1e 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -178,6 +178,7 @@ "copy_address": "Copia Indirizzo", "copy_id": "Copia ID", "copyWalletConnectLink": "Copia il collegamento WalletConnect dalla dApp e incollalo qui", + "corrupted_seed_notice": "I file per questo portafoglio sono corrotti e non sono in grado di essere aperti. Visualizza la frase del seme, salvala e ripristina il portafoglio.\n\nSe il valore è vuoto, il seme non è stato in grado di essere recuperato correttamente.", "countries": "Paesi", "create_account": "Crea account", "create_backup": "Crea backup", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 72f9e0203..e3f6dfb30 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -177,6 +177,7 @@ "copy_address": "住所をコピー", "copy_id": "IDをコピー", "copyWalletConnectLink": "dApp から WalletConnect リンクをコピーし、ここに貼り付けます", + "corrupted_seed_notice": "このウォレットのファイルは破損しており、開くことができません。シードフレーズを表示し、保存し、財布を復元してください。\n\n値が空の場合、種子を正しく回復することができませんでした。", "countries": "国", "create_account": "アカウントの作成", "create_backup": "バックアップを作成", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 45db37781..55174df01 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -177,6 +177,7 @@ "copy_address": "주소 복사", "copy_id": "부 ID", "copyWalletConnectLink": "dApp에서 WalletConnect 링크를 복사하여 여기에 붙여넣으세요.", + "corrupted_seed_notice": "이 지갑의 파일은 손상되어 열 수 없습니다. 씨앗 문구를보고 저장하고 지갑을 복원하십시오.\n\n값이 비어 있으면 씨앗을 올바르게 회수 할 수 없었습니다.", "countries": "국가", "create_account": "계정 만들기", "create_backup": "백업 생성", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 76fa28477..7da19d093 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -177,6 +177,7 @@ "copy_address": "လိပ်စာကို ကူးယူပါ။", "copy_id": "ID ကူးယူပါ။", "copyWalletConnectLink": "dApp မှ WalletConnect လင့်ခ်ကို ကူးယူပြီး ဤနေရာတွင် ကူးထည့်ပါ။", + "corrupted_seed_notice": "ဤပိုက်ဆံအိတ်အတွက်ဖိုင်များသည်အကျင့်ပျက်ခြစားမှုများနှင့်မဖွင့်နိုင်ပါ။ ကျေးဇူးပြု. မျိုးစေ့များကိုကြည့်ပါ, ၎င်းကိုသိမ်းဆည်းပါ, ပိုက်ဆံအိတ်ကိုပြန်ယူပါ။\n\nအကယ်. တန်ဖိုးသည်အချည်းနှီးဖြစ်ပါကမျိုးစေ့ကိုမှန်ကန်စွာပြန်လည်ကောင်းမွန်မရရှိနိုင်ပါ။", "countries": "နိုင်ငံများ", "create_account": "အကောင့်ပြုလုပ်ပါ", "create_backup": "အရန်သိမ်းခြင်းကို ဖန်တီးပါ။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 659f78baa..38fedd52f 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -177,6 +177,7 @@ "copy_address": "Adres kopiëren", "copy_id": "ID kopiëren", "copyWalletConnectLink": "Kopieer de WalletConnect-link van dApp en plak deze hier", + "corrupted_seed_notice": "De bestanden voor deze portemonnee zijn beschadigd en kunnen niet worden geopend. Bekijk de zaadzin, bewaar deze en herstel de portemonnee.\n\nAls de waarde leeg is, kon het zaad niet correct worden hersteld.", "countries": "Landen", "create_account": "Account aanmaken", "create_backup": "Maak een back-up", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 9d8f94651..c1f805790 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -177,6 +177,7 @@ "copy_address": "Skopiuj adress", "copy_id": "skopiuj ID", "copyWalletConnectLink": "Skopiuj link do WalletConnect z dApp i wklej tutaj", + "corrupted_seed_notice": "Pliki dla tego portfela są uszkodzone i nie można ich otworzyć. Zobacz wyrażenie nasion, zapisz je i przywróć portfel.\n\nJeśli wartość jest pusta, ziarno nie można było poprawnie odzyskać.", "countries": "Kraje", "create_account": "Utwórz konto", "create_backup": "Utwórz kopię zapasową", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index df03bd405..534af19a9 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -177,6 +177,7 @@ "copy_address": "Copiar endereço", "copy_id": "Copiar ID", "copyWalletConnectLink": "Copie o link WalletConnect do dApp e cole aqui", + "corrupted_seed_notice": "Os arquivos para esta carteira estão corrompidos e não podem ser abertos. Veja a frase das sementes, salve -a e restaure a carteira.\n\nSe o valor estiver vazio, a semente não pôde ser recuperada corretamente.", "countries": "Países", "create_account": "Criar conta", "create_backup": "Criar backup", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 5197bd29c..b292ab8f6 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -177,6 +177,7 @@ "copy_address": "Cкопировать адрес", "copy_id": "Скопировать ID", "copyWalletConnectLink": "Скопируйте ссылку WalletConnect из dApp и вставьте сюда.", + "corrupted_seed_notice": "Файлы для этого кошелька повреждены и не могут быть открыты. Пожалуйста, просмотрите семенную фразу, сохраните ее и восстановите кошелек.\n\nЕсли значение пустое, то семя не смог правильно восстановить.", "countries": "Страны", "create_account": "Создать аккаунт", "create_backup": "Создать резервную копию", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index dabd90506..7647d51a3 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -177,6 +177,7 @@ "copy_address": "คัดลอกที่อยู่", "copy_id": "คัดลอก ID", "copyWalletConnectLink": "คัดลอกลิงก์ WalletConnect จาก dApp แล้ววางที่นี่", + "corrupted_seed_notice": "ไฟล์สำหรับกระเป๋าเงินนี้เสียหายและไม่สามารถเปิดได้ โปรดดูวลีเมล็ดบันทึกและกู้คืนกระเป๋าเงิน\n\nหากค่าว่างเปล่าเมล็ดก็ไม่สามารถกู้คืนได้อย่างถูกต้อง", "countries": "ประเทศ", "create_account": "สร้างบัญชี", "create_backup": "สร้างการสำรองข้อมูล", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 94be4ca80..1d8897507 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -177,6 +177,7 @@ "copy_address": "Kopyahin ang Address", "copy_id": "Kopyahin ang ID", "copyWalletConnectLink": "Kopyahin ang link ng WalletConnect mula sa dApp at i-paste dito", + "corrupted_seed_notice": "Ang mga file para sa pitaka na ito ay nasira at hindi mabubuksan. Mangyaring tingnan ang parirala ng binhi, i -save ito, at ibalik ang pitaka.\n\nKung ang halaga ay walang laman, kung gayon ang binhi ay hindi ma -recover nang tama.", "countries": "Mga bansa", "create_account": "Lumikha ng Account", "create_backup": "Lumikha ng backup", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index e02d7cf25..b69a957fb 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -177,6 +177,7 @@ "copy_address": "Adresi kopyala", "copy_id": "ID'yi kopyala", "copyWalletConnectLink": "WalletConnect bağlantısını dApp'ten kopyalayıp buraya yapıştırın", + "corrupted_seed_notice": "Bu cüzdanın dosyaları bozuk ve açılamıyor. Lütfen tohum ifadesini görüntüleyin, kaydedin ve cüzdanı geri yükleyin.\n\nDeğer boşsa, tohum doğru bir şekilde geri kazanılamadı.", "countries": "Ülkeler", "create_account": "Hesap oluştur", "create_backup": "Yedek oluştur", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index bfa4475ae..12dcd2af9 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -177,6 +177,7 @@ "copy_address": "Cкопіювати адресу", "copy_id": "Скопіювати ID", "copyWalletConnectLink": "Скопіюйте посилання WalletConnect із dApp і вставте сюди", + "corrupted_seed_notice": "Файли для цього гаманця пошкоджені і не можуть бути відкриті. Перегляньте насіннєву фразу, збережіть її та відновіть гаманець.\n\nЯкщо значення порожнє, то насіння не могло бути правильно відновленим.", "countries": "Країни", "create_account": "Створити обліковий запис", "create_backup": "Створити резервну копію", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 27f66c57a..28194915f 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -177,6 +177,7 @@ "copy_address": "ایڈریس کاپی کریں۔", "copy_id": "کاپی ID", "copyWalletConnectLink": "dApp ﮯﺳ WalletConnect ۔ﮟﯾﺮﮐ ﭧﺴﯿﭘ ﮞﺎﮩﯾ ﺭﻭﺍ ﮟﯾﺮﮐ ﯽﭘﺎﮐ ﻮﮐ ﮏﻨﻟ", + "corrupted_seed_notice": "اس پرس کے لئے فائلیں خراب ہیں اور کھولنے سے قاصر ہیں۔ براہ کرم بیج کے فقرے کو دیکھیں ، اسے بچائیں ، اور بٹوے کو بحال کریں۔\n\nاگر قیمت خالی ہے ، تو بیج صحیح طور پر بازیافت کرنے سے قاصر تھا۔", "countries": "ممالک", "create_account": "اکاؤنٹ بنائیں", "create_backup": "بیک اپ بنائیں", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index 949e40c09..762b5989a 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -176,6 +176,7 @@ "copy_address": "Sao chép Địa chỉ", "copy_id": "Sao chép ID", "copyWalletConnectLink": "Sao chép liên kết WalletConnect từ dApp và dán vào đây", + "corrupted_seed_notice": "Các tệp cho ví này bị hỏng và không thể mở. Vui lòng xem cụm từ hạt giống, lưu nó và khôi phục ví.\n\nNếu giá trị trống, thì hạt giống không thể được phục hồi chính xác.", "countries": "Quốc gia", "create_account": "Tạo tài khoản", "create_backup": "Tạo sao lưu", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index 5a206afb2..9bb2142b5 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -177,6 +177,7 @@ "copy_address": "Ṣẹ̀dà àdírẹ́sì", "copy_id": "Ṣẹ̀dà àmì ìdánimọ̀", "copyWalletConnectLink": "Daakọ ọna asopọ WalletConnect lati dApp ki o si lẹẹmọ nibi", + "corrupted_seed_notice": "Awọn faili fun apamọwọ yii jẹ ibajẹ ati pe ko lagbara lati ṣii. Jọwọ wo ọrọ iseda, fipamọ rẹ, ki o mu apamọwọ naa pada.\n\nTi iye ba ṣofo, lẹhinna irugbin naa ko lagbara lati gba pada ni deede.", "countries": "Awọn orilẹ-ede", "create_account": "Dá àkáǹtì", "create_backup": "Ṣẹ̀dà nípamọ́", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 83c86bda8..cb8f89d3c 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -177,6 +177,7 @@ "copy_address": "复制地址", "copy_id": "复制ID", "copyWalletConnectLink": "从 dApp 复制 WalletConnect 链接并粘贴到此处", + "corrupted_seed_notice": "该钱包的文件被损坏,无法打开。请查看种子短语,保存并恢复钱包。\n\n如果该值为空,则种子无法正确恢复。", "countries": "国家", "create_account": "创建账户", "create_backup": "创建备份", diff --git a/scripts/prepare_moneroc.sh b/scripts/prepare_moneroc.sh index 3596bd18b..41b12570c 100755 --- a/scripts/prepare_moneroc.sh +++ b/scripts/prepare_moneroc.sh @@ -8,7 +8,7 @@ if [[ ! -d "monero_c" ]]; then git clone https://github.com/mrcyjanek/monero_c --branch master cd monero_c - git checkout d72c15f4339791a7bbdf17e9d827b7b56ca144e4 + git checkout c41c4dad9aa5003a914cfb2c528c76386f952665 git reset --hard git submodule update --init --force --recursive ./apply_patches.sh monero diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index e0f2c11c0..f8f89611c 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -14,7 +14,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) From 79f20c28478d44e26de015034ebd949247b1c919 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Fri, 29 Nov 2024 12:43:10 +0200 Subject: [PATCH 31/41] update versions (#1835) * update versions * android fix trial * minor translation fix [skip ci] * update monero_c --- android/app/build.gradle | 2 +- android/app/src/main/AndroidManifestBase.xml | 3 +- assets/text/Monerocom_Release_Notes.txt | 5 +- assets/text/Release_Notes.txt | 7 +-- ios/Podfile.lock | 59 +++++++++++++++++--- macos/Runner/AppDelegate.swift | 2 +- res/values/strings_ar.arb | 2 +- res/values/strings_bg.arb | 2 +- res/values/strings_cs.arb | 2 +- res/values/strings_de.arb | 2 +- res/values/strings_en.arb | 2 +- res/values/strings_es.arb | 2 +- res/values/strings_fr.arb | 2 +- res/values/strings_ha.arb | 2 +- res/values/strings_hi.arb | 2 +- res/values/strings_hr.arb | 2 +- res/values/strings_hy.arb | 2 +- res/values/strings_id.arb | 2 +- res/values/strings_it.arb | 2 +- res/values/strings_ja.arb | 2 +- res/values/strings_ko.arb | 2 +- res/values/strings_my.arb | 2 +- res/values/strings_nl.arb | 2 +- res/values/strings_pl.arb | 2 +- res/values/strings_pt.arb | 2 +- res/values/strings_ru.arb | 2 +- res/values/strings_th.arb | 2 +- res/values/strings_tl.arb | 2 +- res/values/strings_tr.arb | 2 +- res/values/strings_uk.arb | 2 +- res/values/strings_ur.arb | 2 +- res/values/strings_vi.arb | 2 +- res/values/strings_yo.arb | 2 +- res/values/strings_zh.arb | 2 +- scripts/android/app_env.sh | 8 +-- scripts/ios/app_env.sh | 8 +-- scripts/linux/app_env.sh | 4 +- scripts/windows/build_exe_installer.iss | 2 +- 38 files changed, 97 insertions(+), 59 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 628e2ffe6..c19211117 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,7 @@ android { disable 'InvalidPackage' } - namespace 'com.cakewallet.cake_wallet' + namespace appProperties['id'] defaultConfig { applicationId appProperties['id'] diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index 5b080e3ec..a92f493df 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -1,5 +1,4 @@ - + diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt index 46f21e172..556010062 100644 --- a/assets/text/Monerocom_Release_Notes.txt +++ b/assets/text/Monerocom_Release_Notes.txt @@ -1,3 +1,2 @@ -Add airgapped Monero wallet support (best used with our new offline app Cupcake) -New Buy & Sell flow -Bug fixes \ No newline at end of file +UI/UX enhancements +Bug fixes and app improvements \ No newline at end of file diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index 6764826a7..556010062 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1,5 +1,2 @@ -Add Litecoin Ledger support -Add airgapped Monero wallet support (best used with our new offline app Cupcake) -MWEB fixes and enhancements -New Buy & Sell flow -Bug fixes \ No newline at end of file +UI/UX enhancements +Bug fixes and app improvements \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index bb55b01c6..8046ba307 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3,6 +3,38 @@ PODS: - Flutter - ReachabilitySwift - CryptoSwift (1.8.3) + - cw_haven (0.0.1): + - cw_haven/Boost (= 0.0.1) + - cw_haven/Haven (= 0.0.1) + - cw_haven/OpenSSL (= 0.0.1) + - cw_haven/Sodium (= 0.0.1) + - cw_shared_external + - Flutter + - cw_haven/Boost (0.0.1): + - cw_shared_external + - Flutter + - cw_haven/Haven (0.0.1): + - cw_shared_external + - Flutter + - cw_haven/OpenSSL (0.0.1): + - cw_shared_external + - Flutter + - cw_haven/Sodium (0.0.1): + - cw_shared_external + - Flutter + - cw_mweb (0.0.1): + - Flutter + - cw_shared_external (0.0.1): + - cw_shared_external/Boost (= 0.0.1) + - cw_shared_external/OpenSSL (= 0.0.1) + - cw_shared_external/Sodium (= 0.0.1) + - Flutter + - cw_shared_external/Boost (0.0.1): + - Flutter + - cw_shared_external/OpenSSL (0.0.1): + - Flutter + - cw_shared_external/Sodium (0.0.1): + - Flutter - device_display_brightness (0.0.1): - Flutter - device_info_plus (0.0.1): @@ -62,11 +94,10 @@ PODS: - fluttertoast (0.0.2): - Flutter - Toast - - in_app_review (0.2.0): + - in_app_review (2.0.0): - Flutter - integration_test (0.0.1): - Flutter - - MTBBarcodeScanner (5.0.11) - OrderedSet (6.0.3) - package_info_plus (0.4.5): - Flutter @@ -86,7 +117,6 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS - - SwiftProtobuf (1.28.2) - sp_scanner (0.0.1): - Flutter - SwiftyGif (5.4.5) @@ -106,6 +136,9 @@ PODS: DEPENDENCIES: - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - CryptoSwift + - cw_haven (from `.symlinks/plugins/cw_haven/ios`) + - cw_mweb (from `.symlinks/plugins/cw_mweb/ios`) + - cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`) - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`) @@ -125,6 +158,7 @@ DEPENDENCIES: - sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sp_scanner (from `.symlinks/plugins/sp_scanner/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`) - universal_ble (from `.symlinks/plugins/universal_ble/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) @@ -145,6 +179,12 @@ SPEC REPOS: EXTERNAL SOURCES: connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" + cw_haven: + :path: ".symlinks/plugins/cw_haven/ios" + cw_mweb: + :path: ".symlinks/plugins/cw_mweb/ios" + cw_shared_external: + :path: ".symlinks/plugins/cw_shared_external/ios" device_display_brightness: :path: ".symlinks/plugins/device_display_brightness/ios" device_info_plus: @@ -183,6 +223,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sp_scanner: + :path: ".symlinks/plugins/sp_scanner/ios" uni_links: :path: ".symlinks/plugins/uni_links/ios" universal_ble: @@ -197,9 +239,12 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483 + cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a + cw_mweb: 87af74f9659fed0c1a2cbfb44413f1070e79e3ae + cw_shared_external: 2972d872b8917603478117c9957dfca611845a92 device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7 device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 - devicelocale: b22617f40038496deffba44747101255cee005b0 + devicelocale: 35ba84dc7f45f527c3001535d8c8d104edd5d926 DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 fast_scanner: 44c00940355a51258cd6c2085734193cd23d95bc @@ -209,10 +254,9 @@ SPEC CHECKSUMS: flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83 flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be - fluttertoast: 48c57db1b71b0ce9e6bba9f31c940ff4b001293c - in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d + fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c + in_app_review: a31b5257259646ea78e0e35fc914979b0031d011 integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 - MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 @@ -222,7 +266,6 @@ SPEC CHECKSUMS: sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986 share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - SwiftProtobuf: 4dbaffec76a39a8dc5da23b40af1a5dc01a4c02d sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index cd7f006e6..42212fdc0 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -2,7 +2,7 @@ import Cocoa import FlutterMacOS import IOKit.pwr_mgt -@NSApplicationMain +@main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 9c0774155..308427296 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -259,7 +259,7 @@ "enterTokenID": "ﺰﻴﻤﻤﻟﺍ ﺰﻣﺮﻟﺍ ﻑﺮﻌﻣ ﻞﺧﺩﺃ", "enterWalletConnectURI": "WalletConnect ـﻟ URI ﻞﺧﺩﺃ", "error": "خطأ", - "error_dialog_content": "عفوًا ، لقد حصلنا على بعض الخطأ.\n\nيرجى إرسال تقرير التعطل إلى فريق الدعم لدينا لتحسين التطبيق.", + "error_dialog_content": "عفوًا ، حصلنا على بعض الخطأ.\n\nيرجى إرسال تقرير الخطأ إلى فريق الدعم الخاص بنا لجعل التطبيق أفضل.", "error_text_account_name": "يجب أن يحتوي اسم الحساب على أحرف وأرقام فقط\nويجب أن يتراوح بين حرف واحد و 15 حرفًا", "error_text_address": "يجب أن يتوافق عنوان المحفظة مع نوع\nالعملة المشفرة", "error_text_amount": "يجب أن يحتوي المبلغ على أرقام فقط", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index dc57086c4..a2a5e6485 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -259,7 +259,7 @@ "enterTokenID": "Въведете идентификатора на токена", "enterWalletConnectURI": "Въведете URI на WalletConnect", "error": "Грешка", - "error_dialog_content": "Получихме грешка.\n\nМоля, изпратете доклада до нашия отдел поддръжка, за да подобрим приложението.", + "error_dialog_content": "Ами сега, получихме някаква грешка.\n\nМоля, изпратете отчета за грешки до нашия екип за поддръжка, за да подобрите приложението.", "error_text_account_name": "Името на профила може да съдържа само букви и числа \nи трябва да е между 1 и 15 символа", "error_text_address": "Адресът на портфейла трябва да отговаря \n на вида криптовалута", "error_text_amount": "Сумата може да съдържа само числа", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 8702f8fe1..0234be2b6 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -259,7 +259,7 @@ "enterTokenID": "Zadejte ID tokenu", "enterWalletConnectURI": "Zadejte identifikátor URI WalletConnect", "error": "Chyba", - "error_dialog_content": "Nastala chyba.\n\nProsím odešlete zprávu o chybě naší podpoře, aby mohli zajistit opravu.", + "error_dialog_content": "Jejda, dostali jsme nějakou chybu.\n\nZašlete prosím chybovou zprávu našemu týmu podpory, abyste aplikaci vylepšili.", "error_text_account_name": "Název účtu může obsahovat jen písmena a čísla\na musí mít délku 1 až 15 znaků", "error_text_address": "Adresa peněženky musí odpovídat typu\nkryptoměny", "error_text_amount": "Částka může obsahovat pouze čísla", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index c2dde5521..55c26e4db 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -259,7 +259,7 @@ "enterTokenID": "Geben Sie die Token-ID ein", "enterWalletConnectURI": "Geben Sie den WalletConnect-URI ein", "error": "Fehler", - "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie den Absturzbericht an unser Support-Team, um die Anwendung zu verbessern.", + "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie den Fehlerbericht an unser Support -Team, um die Anwendung zu verbessern.", "error_text_account_name": "Der Kontoname darf nur Buchstaben und Zahlen enthalten\nund muss zwischen 1 und 15 Zeichen lang sein", "error_text_address": "Die Walletadresse muss dem Typ der Kryptowährung\nentsprechen", "error_text_amount": "Betrag darf nur Zahlen enthalten", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index a971b797e..f2ddb3c9b 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -259,7 +259,7 @@ "enterTokenID": "Enter the token ID", "enterWalletConnectURI": "Enter WalletConnect URI", "error": "Error", - "error_dialog_content": "Oops, we got some error.\n\nPlease send the crash report to our support team to make the application better.", + "error_dialog_content": "Oops, we got some error.\n\nPlease send the error report to our support team to make the application better.", "error_text_account_name": "Account name can only contain letters, numbers\nand must be between 1 and 15 characters long", "error_text_address": "Wallet address must correspond to the type\nof cryptocurrency", "error_text_amount": "Amount can only contain numbers", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 990e3c154..32ee3d8d1 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -259,7 +259,7 @@ "enterTokenID": "Ingresa el ID del token", "enterWalletConnectURI": "Ingresa el URI de WalletConnect", "error": "Error", - "error_dialog_content": "Vaya, tenemos un error.\n\nEnvía el informe de error a nuestro equipo de soporte para mejorar la aplicación.", + "error_dialog_content": "Vaya, recibimos algo de error.\n\nEnvíe el informe de error a nuestro equipo de soporte para mejorar la aplicación.", "error_text_account_name": "El nombre de la cuenta solo puede contener letras, números \ny debe tener entre 1 y 15 caracteres de longitud", "error_text_address": "La dirección de la billetera debe corresponder al tipo \nde criptomoneda", "error_text_amount": "La cantidad solo puede contener números", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 6b0e58846..c03682ada 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -259,7 +259,7 @@ "enterTokenID": "Entrez l'ID du jeton", "enterWalletConnectURI": "Saisissez l'URI de WalletConnect.", "error": "Erreur", - "error_dialog_content": "Oups, nous avons rencontré une erreur.\n\nMerci d'envoyer le rapport d'erreur à notre équipe d'assistance afin de nous permettre d'améliorer l'application.", + "error_dialog_content": "Oups, nous avons eu une erreur.\n\nVeuillez envoyer le rapport d'erreur à notre équipe d'assistance pour améliorer l'application.", "error_text_account_name": "Le nom de compte ne peut contenir que des lettres et des chiffres\net sa longueur doit être comprise entre 1 et 15 caractères", "error_text_address": "L'adresse du portefeuille (wallet) doit correspondre au type de\ncryptomonnaie", "error_text_amount": "Le montant ne peut comporter que des nombres", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 8d2a66062..3586998af 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -259,7 +259,7 @@ "enterTokenID": "Shigar da alamar alama", "enterWalletConnectURI": "Shigar da WalletConnect URI", "error": "Kuskure", - "error_dialog_content": "Ai, yanzu muka ga alamar kuskure. \n\nDa fatan, aika rahoton kuskuren da muka kira zuwa gasar tsarinmu don gaskiyar shirya.", + "error_dialog_content": "Oops, mun sami kuskure.\n\nDon Allah a aika rahoton kuskuren zuwa ga ƙungiyar goyon bayanmu don yin aikace-aikacen da kyau.", "error_text_account_name": "Sunan ajiya zai iya ɗauka ne kawai da haruffa, lambobi\nkuma ya zama tsakanin 1 zuwa 15 haruffa", "error_text_address": "Adireshin hujja ya kamata ya dace da irin\nna cryptocurrency", "error_text_amount": "Adadin biya zai iya ƙunsar lambobi kawai", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index ceede03fb..f812caf0e 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -259,7 +259,7 @@ "enterTokenID": "टोकन आईडी दर्ज करें", "enterWalletConnectURI": "वॉलेटकनेक्ट यूआरआई दर्ज करें", "error": "त्रुटि", - "error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया क्रैश रिपोर्ट हमारी सहायता टीम को भेजें।", + "error_dialog_content": "उफ़, हमें कुछ त्रुटि मिली।\n\nकृपया आवेदन को बेहतर बनाने के लिए हमारी सहायता टीम को त्रुटि रिपोर्ट भेजें।", "error_text_account_name": "खाता नाम में केवल अक्षर, संख्याएं हो सकती हैं\nऔर 1 और 15 वर्णों के बीच लंबा होना चाहिए", "error_text_address": "वॉलेट पता प्रकार के अनुरूप होना चाहिए\nक्रिप्टोकरेंसी का", "error_text_amount": "राशि में केवल संख्याएँ हो सकती हैं", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index f0ee38a9e..9252b19bf 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -259,7 +259,7 @@ "enterTokenID": "Unesite ID tokena", "enterWalletConnectURI": "Unesite WalletConnect URI", "error": "Greška", - "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju.", + "error_dialog_content": "Ups, dobili smo pogrešku.\n\nMolimo pošaljite izvještaj o pogrešci našem timu za podršku kako biste poboljšali aplikaciju.", "error_text_account_name": "Ime računa smije sadržavati samo slova i brojeve\nte mora biti dužine između 1 i 15 znakova", "error_text_address": "Adresa novčanika mora odgovarati\nvrsti kriptovalute", "error_text_amount": "Iznos smije sadržavati samo brojeve", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index d4abeaace..b442defbc 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -259,7 +259,7 @@ "enterTokenID": "Մուտքագրեք Token ID֊ն", "enterWalletConnectURI": "Մուտքագրեք WalletConnect URI", "error": "Սխալ", - "error_dialog_content": "Օպս, մենք սխալ ենք ստացել: \n\nԽնդրում ենք ուղարկել սխալի հաշվետվությունը մեր աջակցության թիմին ծրագիրը բարելավելու համար:", + "error_dialog_content": "Վայ, մենք որոշակի սխալ ստացանք:\n\nԽնդրում ենք ուղարկել սխալի մասին զեկույցը մեր աջակցության թիմին `դիմումը ավելի լավ դարձնելու համար:", "error_text_account_name": "Հաշվի անունը կարող է պարունակել միայն տառեր և թվեր և պետք է լինի 1-15 նիշ", "error_text_address": "Դրամապանակի հասցեն պետք է համապատասխանի կրիպտոարժույթի տեսակին", "error_text_amount": "Գումարը կարող է պարունակել միայն թվեր", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 022d31989..a730832dc 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -259,7 +259,7 @@ "enterTokenID": "Masukkan ID tokennya", "enterWalletConnectURI": "Masukkan URI WalletConnect", "error": "Kesalahan", - "error_dialog_content": "Ups, kami mendapat kesalahan.\n\nSilakan kirim laporan crash ke tim dukungan kami untuk membuat aplikasi lebih baik.", + "error_dialog_content": "Ups, kami mendapat kesalahan.\n\nSilakan kirim laporan kesalahan ke tim dukungan kami untuk membuat aplikasi lebih baik.", "error_text_account_name": "Nama akun hanya dapat berisi huruf, angka\ndan harus antara 1 dan 15 karakter panjang", "error_text_address": "Alamat dompet harus sesuai dengan tipe\nmata uang kripto", "error_text_amount": "Jumlah hanya dapat berisi angka", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 62da65a1e..00b9810b2 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -260,7 +260,7 @@ "enterTokenID": "Inserisci l'ID del token", "enterWalletConnectURI": "Inserisci l'URI di WalletConnect", "error": "Errore", - "error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare il rapporto sull'arresto anomalo al nostro team di supporto per migliorare l'applicazione.", + "error_dialog_content": "Oops, abbiamo ricevuto qualche errore.\n\nSi prega di inviare il rapporto di errore al nostro team di supporto per migliorare l'applicazione.", "error_text_account_name": "Il nome del conto può contenere solo lettere, numeri\ne deve avere una lunghezza compresa tra 1 e 15 caratteri", "error_text_address": "L'indirizzo del Portafoglio deve corrispondere alla tipologia\ndi criptovaluta", "error_text_amount": "L'ammontare può contenere solo numeri", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index e3f6dfb30..df1a47c51 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -259,7 +259,7 @@ "enterTokenID": "トークンIDを入力してください", "enterWalletConnectURI": "WalletConnect URI を入力してください", "error": "エラー", - "error_dialog_content": "エラーが発生しました。\n\nアプリケーションを改善するために、クラッシュ レポートをサポート チームに送信してください。", + "error_dialog_content": "おっと、エラーが発生しました。\n\nサポートチームにエラーレポートを送信して、アプリケーションを改善してください。", "error_text_account_name": "アカウント名には文字のみを含めることができます \n1〜15文字である必要があります", "error_text_address": "ウォレットアドレスは、\n暗号通貨", "error_text_amount": "金額には数字のみを含めることができます", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 55174df01..bea17fb4b 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -259,7 +259,7 @@ "enterTokenID": "토큰 ID를 입력하세요", "enterWalletConnectURI": "WalletConnect URI를 입력하세요.", "error": "오류", - "error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n응용 프로그램을 개선하려면 지원 팀에 충돌 보고서를 보내주십시오.", + "error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n오류 보고서를 지원 팀에 보내 응용 프로그램을 개선하십시오.", "error_text_account_name": "계정 이름은 문자, 숫자 만 포함 할 수 있습니다\n1 ~ 15 자 사이 여야합니다", "error_text_address": "지갑 주소는 유형과 일치해야합니다\n암호 화폐", "error_text_amount": "금액은 숫자 만 포함 할 수 있습니다", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 7da19d093..05ed163c4 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -259,7 +259,7 @@ "enterTokenID": "တိုကင် ID ကိုထည့်ပါ။", "enterWalletConnectURI": "WalletConnect URI ကိုရိုက်ထည့်ပါ။", "error": "အမှား", - "error_dialog_content": "အိုး၊ ကျွန်ုပ်တို့တွင် အမှားအယွင်းအချို့ရှိသည်။\n\nအပလီကေးရှင်းကို ပိုမိုကောင်းမွန်စေရန်အတွက် ပျက်စီးမှုအစီရင်ခံစာကို ကျွန်ုပ်တို့၏ပံ့ပိုးကူညီရေးအဖွဲ့ထံ ပေးပို့ပါ။", + "error_dialog_content": "အိုး, ငါတို့အမှားအယွင်းတွေရတယ်။\n\nလျှောက်လွှာကိုပိုကောင်းအောင်လုပ်ရန်ကျွန်ုပ်တို့၏ထောက်ခံမှုအဖွဲ့သို့အမှားအယွင်းများပေးပို့ပါ။", "error_text_account_name": "အကောင့်အမည်သည် အက္ခရာများ၊ နံပါတ်များသာ ပါဝင်နိုင်သည်\nနှင့် စာလုံးရေ 1 နှင့် 15 ကြားရှိရပါမည်။", "error_text_address": "Wallet လိပ်စာသည် အမျိုးအစား\no cryptocurrency နှင့် ကိုက်ညီရပါမည်။", "error_text_amount": "ပမာဏသည် နံပါတ်များသာ ပါဝင်နိုင်သည်။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 38fedd52f..449e1ad27 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -259,7 +259,7 @@ "enterTokenID": "Voer de token-ID in", "enterWalletConnectURI": "Voer WalletConnect-URI in", "error": "Fout", - "error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur het crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren.", + "error_dialog_content": "Oeps, we hebben wat fout.\n\nStuur het foutrapport naar ons ondersteuningsteam om de applicatie beter te maken.", "error_text_account_name": "Accountnaam mag alleen letters, cijfers bevatten\nen moet tussen de 1 en 15 tekens lang zijn", "error_text_address": "Portemonnee-adres moet overeenkomen met het type\nvan cryptocurrency", "error_text_amount": "Bedrag kan alleen cijfers bevatten", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index c1f805790..67ef4f50c 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -259,7 +259,7 @@ "enterTokenID": "Wprowadź identyfikator tokena", "enterWalletConnectURI": "Wprowadź identyfikator URI WalletConnect", "error": "Błąd", - "error_dialog_content": "Ups, wystąpił błąd.\n\nPrześlij raport o awarii do naszego zespołu wsparcia, aby ulepszyć aplikację.", + "error_dialog_content": "Ups, mamy trochę błędu.\n\nProszę o przesłanie raportu o błędach do naszego zespołu wsparcia, aby aplikacja była lepsza.", "error_text_account_name": "Nazwa konta może zawierać tylko litery, cyfry\ni musi mieć od 1 do 15 znaków", "error_text_address": "Adres musi odpowiadać typowi kryptowaluty", "error_text_amount": "Kwota może zawierać tylko liczby", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 534af19a9..b910d49b2 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -259,7 +259,7 @@ "enterTokenID": "Insira o ID do token", "enterWalletConnectURI": "Insira o URI do WalletConnect", "error": "Erro", - "error_dialog_content": "Ops, houve algum erro.\n\nPor favor, envie o relatório de falha para nossa equipe de suporte para melhorar o aplicativo.", + "error_dialog_content": "Opa, recebemos algum erro.\n\nEnvie o relatório de erro à nossa equipe de suporte para melhorar o aplicativo.", "error_text_account_name": "O nome da conta só pode conter letras, números\ne deve ter entre 1 e 15 caracteres", "error_text_address": "O endereço da carteira deve corresponder à\ncriptomoeda selecionada", "error_text_amount": "A quantia deve conter apenas números", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index b292ab8f6..daa615f6c 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -259,7 +259,7 @@ "enterTokenID": "Введите идентификатор токена", "enterWalletConnectURI": "Введите URI WalletConnect", "error": "Ошибка", - "error_dialog_content": "Ой, у нас какая-то ошибка.\n\nПожалуйста, отправьте отчет о сбое в нашу службу поддержки, чтобы сделать приложение лучше.", + "error_dialog_content": "Упс, мы получили некоторую ошибку.\n\nПожалуйста, отправьте отчет об ошибках в нашу команду поддержки, чтобы сделать приложение лучше.", "error_text_account_name": "Имя аккаунта может содержать только буквы, цифры\nи должно быть от 1 до 15 символов в длину", "error_text_address": "Адрес кошелька должен соответствовать типу\nкриптовалюты", "error_text_amount": "Баланс может содержать только цифры", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 7647d51a3..28a25d88b 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -259,7 +259,7 @@ "enterTokenID": "ป้อนรหัสโทเค็น", "enterWalletConnectURI": "เข้าสู่ WalletConnect URI", "error": "ข้อผิดพลาด", - "error_dialog_content": "อ๊ะ เราพบข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อขัดข้องไปยังทีมสนับสนุนของเราเพื่อปรับปรุงแอปพลิเคชันให้ดียิ่งขึ้น", + "error_dialog_content": "อ๊ะเรามีข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อผิดพลาดไปยังทีมสนับสนุนของเราเพื่อให้แอปพลิเคชันดีขึ้น", "error_text_account_name": "ชื่อบัญชีสามารถเป็นเพียงตัวอักษรหรือตัวเลขเท่านั้น\nและต้องมีความยาวระหว่าง 1 ถึง 15 ตัวอักษร", "error_text_address": "ที่อยู่กระเป๋าจะต้องสอดคล้องกับประเภท\nของเหรียญคริปโตเนียม", "error_text_amount": "จำนวนจะต้องประกอบด้วยตัวเลขเท่านั้น", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 1d8897507..e0ac804a5 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -259,7 +259,7 @@ "enterTokenID": "Ipasok ang token ID", "enterWalletConnectURI": "Ipasok ang WalletConnect URI", "error": "Error", - "error_dialog_content": "Oops, nakakuha kami ng ilang error.\n\nMangyaring ipadala ang crash report sa aming koponan ng suporta upang maging mas mahusay ang application.", + "error_dialog_content": "Oops, nakakuha kami ng ilang error.\n\nMangyaring ipadala ang ulat ng error sa aming koponan ng suporta upang maging mas mahusay ang application.", "error_text_account_name": "Ang pangalan ng account ay maaari lamang maglaman ng mga titik, numero\nat dapat sa pagitan ng 1 at 15 character ang haba", "error_text_address": "Ang wallet address ay dapat na tumutugma sa uri\nng cryptocurrency", "error_text_amount": "Ang halaga ay maaari lamang maglaman ng mga numero", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index b69a957fb..87ad65450 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -259,7 +259,7 @@ "enterTokenID": "Belirteç kimliğini girin", "enterWalletConnectURI": "WalletConnect URI'sini girin", "error": "Hata", - "error_dialog_content": "Hay aksi, bir hatamız var.\n\nUygulamayı daha iyi hale getirmek için lütfen kilitlenme raporunu destek ekibimize gönderin.", + "error_dialog_content": "Oops, biraz hata aldık.\n\nLütfen uygulamayı daha iyi hale getirmek için hata raporunu destek ekibimize gönderin.", "error_text_account_name": "Hesap ismi yalnızca harf, rakam \nve 1 ile 15 uzunluğunda karakter içermelidir.", "error_text_address": "Cüzdan adresi kripto para biriminin\ntürüne karşılık gelmelidir", "error_text_amount": "Miktar sadece sayı içerebilir", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 12dcd2af9..876ae8993 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -259,7 +259,7 @@ "enterTokenID": "Введіть ідентифікатор токена", "enterWalletConnectURI": "Введіть URI WalletConnect", "error": "Помилка", - "error_dialog_content": "На жаль, ми отримали помилку.\n\nБудь ласка, надішліть звіт про збій нашій команді підтримки, щоб покращити додаток.", + "error_dialog_content": "На жаль, ми отримали певну помилку.\n\nБудь ласка, надішліть звіт про помилку нашій команді підтримки, щоб зробити заявку кращим.", "error_text_account_name": "Ім'я акаунту може містити тільки букви, цифри\nі повинно бути від 1 до 15 символів в довжину", "error_text_address": "Адреса гаманця повинна відповідати типу\nкриптовалюти", "error_text_amount": "Баланс може містити тільки цифри", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 28194915f..7bb22a0d0 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -259,7 +259,7 @@ "enterTokenID": " ۔ﮟﯾﺮﮐ ﺝﺭﺩ ID ﻦﮐﻮﭨ", "enterWalletConnectURI": "WalletConnect URI ۔ﮟﯾﺮﮐ ﺝﺭﺩ", "error": "خرابی", - "error_dialog_content": "افوہ، ہمیں کچھ خرابی ملی۔\n\nایپلی کیشن کو بہتر بنانے کے لیے براہ کرم کریش رپورٹ ہماری سپورٹ ٹیم کو بھیجیں۔", + "error_dialog_content": "افوہ ، ہمیں کچھ غلطی ہوئی۔\n\nبراہ کرم درخواست کو بہتر بنانے کے لئے ہماری سپورٹ ٹیم کو غلطی کی رپورٹ بھیجیں۔", "error_text_account_name": "اکاؤنٹ کا نام صرف حروف، اعداد پر مشتمل ہو سکتا ہے\\nاور 1 سے 15 حروف کے درمیان ہونا چاہیے۔", "error_text_address": "والیٹ کا پتہ cryptocurrency کی قسم\\nکے مطابق ہونا چاہیے۔", "error_text_amount": "رقم صرف اعداد پر مشتمل ہو سکتی ہے۔", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index 762b5989a..6eeed916e 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -258,7 +258,7 @@ "enterTokenID": "Nhập ID token", "enterWalletConnectURI": "Nhập URI WalletConnect", "error": "Lỗi", - "error_dialog_content": "Oops, chúng tôi gặp một số lỗi.\n\nVui lòng gửi báo cáo sự cố cho nhóm hỗ trợ của chúng tôi để cải thiện ứng dụng.", + "error_dialog_content": "Rất tiếc, chúng tôi đã gặp một số lỗi.\n\nVui lòng gửi báo cáo lỗi cho nhóm hỗ trợ của chúng tôi để làm cho ứng dụng tốt hơn.", "error_text_account_name": "Tên tài khoản chỉ được chứa chữ cái, số\nvà phải từ 1 đến 15 ký tự", "error_text_address": "Địa chỉ ví phải tương ứng với loại tiền điện tử", "error_text_amount": "Số tiền chỉ được chứa số", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index 9bb2142b5..cb446b421 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -260,7 +260,7 @@ "enterTokenID": "Tẹ ID ami sii", "enterWalletConnectURI": "Tẹ WalletConnect URI sii", "error": "Àṣìṣe", - "error_dialog_content": "Àṣìṣe ti dé.\n\nẸ jọ̀wọ́, fi àkọsílẹ̀ àṣìṣe ránṣẹ́ sí ẹgbẹ́ ìranlọ́wọ́ wa kí áàpù wa bá túbọ̀ dára.", + "error_dialog_content": "Oops, a ni aṣiṣe diẹ.\n\nJọwọ fi aṣiṣe naa ranṣẹ si ẹgbẹ atilẹyin wa lati jẹ ki ohun elo naa dara julọ.", "error_text_account_name": "Orúkọ àkáǹtì lè ni nìkan nínú ẹyọ ọ̀rọ̀ àti òǹkà\nGígun rẹ̀ kò gbọ́dọ̀ kéré ju oókan. Gígun rẹ̀ sì kò gbọ́dọ̀ tóbi ju márùndínlógún.", "error_text_address": "Àdírẹ́sì àpamọ́wọ́ gbọ́dọ̀ báramu irú owó", "error_text_amount": "Iye lè ni nìkan nínú àwọn òǹkà", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index cb8f89d3c..86090f11f 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -259,7 +259,7 @@ "enterTokenID": "输入令牌 ID", "enterWalletConnectURI": "输入 WalletConnect URI", "error": "错误", - "error_dialog_content": "糟糕,我们遇到了一些错误。\n\n请将崩溃报告发送给我们的支持团队,以改进应用程序。", + "error_dialog_content": "糟糕,我们有一些错误。\n\n请将错误报告发送给我们的支持团队,以使应用程序更好。", "error_text_account_name": "帐户名称只能包含字母数字\n且必须介于1到15个字符之间", "error_text_address": "钱包地址必须与类型对应\n加密货币", "error_text_amount": "金额只能包含数字", diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 7eee6d6ae..a11df5503 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.18.0" -MONERO_COM_BUILD_NUMBER=105 +MONERO_COM_VERSION="1.18.1" +MONERO_COM_BUILD_NUMBER=106 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.21.0" -CAKEWALLET_BUILD_NUMBER=236 +CAKEWALLET_VERSION="4.21.1" +CAKEWALLET_BUILD_NUMBER=237 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 fe18758c8..d4cc7cbe7 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.18.0" -MONERO_COM_BUILD_NUMBER=103 +MONERO_COM_VERSION="1.18.1" +MONERO_COM_BUILD_NUMBER=104 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.21.0" -CAKEWALLET_BUILD_NUMBER=281 +CAKEWALLET_VERSION="4.21.1" +CAKEWALLET_BUILD_NUMBER=282 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh index 1cdb43ced..77a33ccfd 100755 --- a/scripts/linux/app_env.sh +++ b/scripts/linux/app_env.sh @@ -14,8 +14,8 @@ if [ -n "$1" ]; then fi CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.11.0" -CAKEWALLET_BUILD_NUMBER=38 +CAKEWALLET_VERSION="1.11.1" +CAKEWALLET_BUILD_NUMBER=39 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then echo "Wrong app type." diff --git a/scripts/windows/build_exe_installer.iss b/scripts/windows/build_exe_installer.iss index 25f94cb1f..2cdd8c47c 100644 --- a/scripts/windows/build_exe_installer.iss +++ b/scripts/windows/build_exe_installer.iss @@ -1,5 +1,5 @@ #define MyAppName "Cake Wallet" -#define MyAppVersion "0.2.0" +#define MyAppVersion "0.2.1" #define MyAppPublisher "Cake Labs LLC" #define MyAppURL "https://cakewallet.com/" #define MyAppExeName "CakeWallet.exe" From de970fcb805bb9003bd460fa0660c294e715dcb6 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Fri, 29 Nov 2024 13:16:59 +0200 Subject: [PATCH 32/41] test (#1838) * update versions * android fix trial * minor translation fix [skip ci] * update monero_c * minor --- cw_bitcoin/pubspec.lock | 4 +-- cw_core/pubspec.lock | 4 +-- .../.plugin_symlinks/path_provider_linux | 2 +- cw_monero/pubspec.lock | 4 +-- cw_wownero/pubspec.lock | 4 +-- linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 ++ macos/Podfile.lock | 27 ++++++++++++------- scripts/ios/app_env.sh | 2 +- windows/flutter/generated_plugins.cmake | 1 + 10 files changed, 31 insertions(+), 20 deletions(-) diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index aa9f3ba05..c65f056bb 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -1031,10 +1031,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.4" watcher: dependency: "direct overridden" description: diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock index 44ef15a41..c12839a19 100644 --- a/cw_core/pubspec.lock +++ b/cw_core/pubspec.lock @@ -722,10 +722,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.4" watcher: dependency: "direct overridden" description: diff --git a/cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux b/cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux index a2b4915e7..17553f81e 120000 --- a/cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux +++ b/cw_monero/linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux @@ -1 +1 @@ -/Users/user/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/ \ No newline at end of file +/Users/omarhatem/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/ \ No newline at end of file diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index f4be439b7..d8a3a4ff8 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -829,10 +829,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.4" watcher: dependency: "direct overridden" description: diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock index c565348e1..70f1f1e1d 100644 --- a/cw_wownero/pubspec.lock +++ b/cw_wownero/pubspec.lock @@ -757,10 +757,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.4" watcher: dependency: "direct overridden" description: diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 4b9eb3b2d..f52be7481 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 52b44e53e..42b9fa84c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import connectivity_plus +import cw_mweb import device_info_plus import devicelocale import fast_scanner @@ -23,6 +24,7 @@ import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + CwMwebPlugin.register(with: registry.registrar(forPlugin: "CwMwebPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 001d75696..4445e5976 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -12,21 +12,21 @@ PODS: - FlutterMacOS - flutter_inappwebview_macos (0.0.1): - FlutterMacOS - - OrderedSet (~> 5.0) + - OrderedSet (~> 6.0.3) - flutter_local_authentication (1.2.0): - FlutterMacOS - flutter_secure_storage_macos (6.1.1): - FlutterMacOS - FlutterMacOS (1.0.0) - - in_app_review (0.2.0): + - in_app_review (2.0.0): - FlutterMacOS - - OrderedSet (5.0.0) + - OrderedSet (6.0.3) - package_info_plus (0.0.1): - FlutterMacOS - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - ReachabilitySwift (5.0.0) + - ReachabilitySwift (5.2.4) - share_plus (0.0.1): - FlutterMacOS - shared_preferences_foundation (0.0.1): @@ -34,6 +34,9 @@ PODS: - FlutterMacOS - sp_scanner (0.0.1): - FlutterMacOS + - universal_ble (0.0.1): + - Flutter + - FlutterMacOS - url_launcher_macos (0.0.1): - FlutterMacOS - wakelock_plus (0.0.1): @@ -55,6 +58,7 @@ DEPENDENCIES: - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - sp_scanner (from `Flutter/ephemeral/.symlinks/plugins/sp_scanner/macos`) + - universal_ble (from `Flutter/ephemeral/.symlinks/plugins/universal_ble/darwin`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`) @@ -94,6 +98,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin sp_scanner: :path: Flutter/ephemeral/.symlinks/plugins/sp_scanner/macos + universal_ble: + :path: Flutter/ephemeral/.symlinks/plugins/universal_ble/darwin url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos wakelock_plus: @@ -105,18 +111,19 @@ SPEC CHECKSUMS: device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 fast_scanner: d31bae07e2653403a69dac99fb710c1722b16a97 - flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d + flutter_inappwebview_macos: bdf207b8f4ebd58e86ae06cd96b147de99a67c9b flutter_local_authentication: 85674893931e1c9cfa7c9e4f5973cb8c56b018b0 flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0 - OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c - package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c + in_app_review: a6a031b9acd03c7d103e341aa334adf2c493fb93 + OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 + package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 - share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf + ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda + share_plus: 1fa619de8392a4398bfaf176d441853922614e89 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 sp_scanner: 269d96e0ec3173e69156be7239b95182be3b8303 + universal_ble: cf52a7b3fd2e7c14d6d7262e9fdadb72ab6b88a6 url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index d4cc7cbe7..2ca0df21d 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -19,7 +19,7 @@ MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_VERSION="4.21.1" -CAKEWALLET_BUILD_NUMBER=282 +CAKEWALLET_BUILD_NUMBER=283 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index f8f89611c..e0f2c11c0 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -14,6 +14,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + sp_scanner ) set(PLUGIN_BUNDLED_LIBRARIES) From bd38393acff73eb891eea84e073595580a13025d Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Fri, 29 Nov 2024 22:15:55 +0200 Subject: [PATCH 33/41] fix sending issue (#1840) * fix sending issue * Update pr_test_build_android.yml --- .github/workflows/pr_test_build_android.yml | 2 +- android/app/src/main/AndroidManifestBase.xml | 3 ++- lib/view_model/send/send_view_model.dart | 10 ---------- scripts/android/app_env.sh | 8 ++++---- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index e3617f81e..9df11f7ab 100644 --- a/.github/workflows/pr_test_build_android.yml +++ b/.github/workflows/pr_test_build_android.yml @@ -53,7 +53,7 @@ jobs: - name: Flutter action uses: subosito/flutter-action@v1 with: - flutter-version: "3.24.4" + flutter-version: "3.24.0" channel: stable - name: Install package dependencies diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index a92f493df..5b080e3ec 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -1,4 +1,5 @@ - + diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 69a500c9b..fb96b2545 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -534,16 +534,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor throw Exception('Priority is null for wallet type: ${wallet.type}'); } - if (hasCoinControl) { - bool isCoinSelected = false; - for (var coin in unspentCoinsListViewModel.items) { - isCoinSelected = isCoinSelected || (coin.isSending && !coin.isFrozen); - } - if (!isCoinSelected) { - throw Exception("No coin selected in coin control, you need to select a coin in order to spend"); - } - } - switch (wallet.type) { case WalletType.bitcoin: case WalletType.litecoin: diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index a11df5503..79afc5c78 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.18.1" -MONERO_COM_BUILD_NUMBER=106 +MONERO_COM_VERSION="1.18.2" +MONERO_COM_BUILD_NUMBER=107 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.21.1" -CAKEWALLET_BUILD_NUMBER=237 +CAKEWALLET_VERSION="4.21.2" +CAKEWALLET_BUILD_NUMBER=238 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_SCHEME="cakewallet" From de15c400b5d1ee45e2ba1d003db612986831b049 Mon Sep 17 00:00:00 2001 From: tuxsudo Date: Sat, 30 Nov 2024 15:49:48 -0500 Subject: [PATCH 34/41] Add APK verification to readme --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 078c4437e..ea8f34624 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,17 @@ Cake Wallet includes support for several cryptocurrencies, including: * F-Droid: https://fdroid.cakelabs.com * APK: https://github.com/cake-tech/cake_wallet/releases +### APK Verification + +APK releases on GitHub, Accrescent, and F-Droid use the same key. They can easily be verified using [apksigner](https://developer.android.com/tools/apksigner#options-verify) or [AppVerifier](https://github.com/soupslurpr/AppVerifier). + +See below for Cake Wallet's SHA-256 signing certificate hash: + +``` +com.cakewallet.cake_wallet +C5:40:53:AB:0F:10:D9:54:17:62:A3:DA:76:65:AE:3D:BA:5E:7C:74:3A:B4:F1:08:A5:34:9D:62:AC:10:6E:F5 +``` + # Support We have 24/7 free support. Please contact support@cakewallet.com From 5b162c54daf16a0f0f0a0d82671c86f6d4375961 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Mon, 2 Dec 2024 20:24:01 +0300 Subject: [PATCH 35/41] Update AndroidManifestBase.xml --- android/app/src/main/AndroidManifestBase.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index 5b080e3ec..a92f493df 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -1,5 +1,4 @@ - + From 3e1cb3905e9e2843860326e5748cb67d801cf078 Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 3 Dec 2024 00:26:33 +0200 Subject: [PATCH 36/41] fix infinity values in LetsExchange fixed rate (#1849) Co-authored-by: Omar Hatem --- lib/exchange/provider/letsexchange_exchange_provider.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/exchange/provider/letsexchange_exchange_provider.dart b/lib/exchange/provider/letsexchange_exchange_provider.dart index 1d4da55cb..0a2f81317 100644 --- a/lib/exchange/provider/letsexchange_exchange_provider.dart +++ b/lib/exchange/provider/letsexchange_exchange_provider.dart @@ -97,6 +97,8 @@ class LetsExchangeExchangeProvider extends ExchangeProvider { final amountToGet = double.tryParse(responseJSON['amount'] as String) ?? 0.0; + if (amountToGet == 0.0) return 0.0; + return isFixedRateMode ? amount / amountToGet : amountToGet / amount; } catch (e) { log(e.toString()); From 2e6dbe71affe3df2e42d7fd6ce66782ecae34cfc Mon Sep 17 00:00:00 2001 From: MyEcoria <103332030+MyEcoria@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:02:50 +0100 Subject: [PATCH 37/41] (fix)[translations]: update French translations for wallet (#1850) --- res/values/strings_fr.arb | 100 +++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index c03682ada..47c6addb6 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -39,8 +39,8 @@ "alert_notice": "Avis", "all": "TOUT", "all_coins": "Toutes les pièces", - "all_trades": "Tous échanges", - "all_transactions": "Toutes transactions", + "all_trades": "Tous les échanges", + "all_transactions": "Toutes les transactions", "alphabetical": "Alphabétique", "already_have_account": "Vous avez déjà un compte ?", "always": "toujours", @@ -55,7 +55,7 @@ "arrive_in_this_address": "${currency} ${tag}arrivera à cette adresse", "ascending": "Ascendant", "ask_each_time": "Demander à chaque fois", - "auth_store_ban_timeout": "délai de bannisement", + "auth_store_ban_timeout": "expulsion_temporaire", "auth_store_banned_for": "Banni pour ", "auth_store_banned_minutes": " minutes", "auth_store_incorrect_password": "Mauvais code PIN", @@ -85,7 +85,7 @@ "Blocks_remaining": "Blocs Restants : ${status}", "bluetooth": "Bluetooth", "bright_theme": "Vif", - "bump_fee": "Frais de bosse", + "bump_fee": "Augmenter les frais", "buy": "Acheter", "buy_alert_content": "Actuellement, nous ne prenons en charge que l'achat de Bitcoin, Ethereum, Litecoin et Monero. Veuillez créer ou basculer vers votre portefeuille Bitcoin, Ethereum, Litecoin ou Monero.", "buy_bitcoin": "Acheter du Bitcoin", @@ -94,7 +94,7 @@ "buy_with": "Acheter avec", "by_cake_pay": "par Cake Pay", "cake_2fa_preset": "Cake 2FA prédéfini", - "cake_dark_theme": "Thème sombre du gâteau", + "cake_dark_theme": "Thème sombre Cake", "cake_pay_account_note": "Inscrivez-vous avec juste une adresse e-mail pour voir et acheter des cartes. Certaines sont même disponibles à prix réduit !", "cake_pay_learn_more": "Achetez et utilisez instantanément des cartes-cadeaux dans l'application !\nBalayer de gauche à droite pour en savoir plus.", "cake_pay_save_order": "La carte doit être envoyée à votre e-mail dans un jour ouvrable \n Enregistrez votre identifiant de commande:", @@ -107,7 +107,7 @@ "camera_consent": "Votre appareil photo sera utilisé pour capturer une image à des fins d'identification par ${provider}. Veuillez consulter leur politique de confidentialité pour plus de détails.", "camera_permission_is_required": "L'autorisation de la caméra est requise.\nVeuillez l'activer à partir des paramètres de l'application.", "cancel": "Annuler", - "card_address": "Adresse :", + "card_address": "Adresse:", "cardholder_agreement": "Contrat de titulaire de carte", "cards": "Cartes", "chains": "Chaînes", @@ -128,13 +128,13 @@ "choose_a_payment_method": "Choisissez un mode de paiement", "choose_a_provider": "Choisissez un fournisseur", "choose_account": "Choisir le compte", - "choose_address": "\n\nMerci de choisir l'adresse :", + "choose_address": "\n\nMerci de choisir l'adresse:", "choose_card_value": "Choisissez une valeur de carte", - "choose_derivation": "Choisissez le chemin de dérivation du portefeuille", - "choose_from_available_options": "Choisissez parmi les options disponibles :", + "choose_derivation": "Choisir la dérivation du portefeuille", + "choose_from_available_options": "Choisissez parmi les options disponibles:", "choose_one": "Choisissez-en un", "choose_relay": "Veuillez choisir un relais à utiliser", - "choose_wallet_currency": "Merci de choisir la devise du portefeuille (wallet) :", + "choose_wallet_currency": "Merci de choisir la devise du portefeuille (wallet):", "choose_wallet_group": "Choisissez un groupe de portefeuille", "clear": "Effacer", "clearnet_link": "Lien Clearnet", @@ -145,12 +145,12 @@ "commit_transaction_amount_fee": "Valider la transaction\nMontant : ${amount}\nFrais : ${fee}", "confirm": "Confirmer", "confirm_delete_template": "Cette action va supprimer ce modèle. Souhaitez-vous continuer ?", - "confirm_delete_wallet": "Cette action va supprimer ce portefeuille (wallet). Souhaitez-vous contnuer ?", + "confirm_delete_wallet": "Cette action va supprimer ce portefeuille (wallet). Souhaitez-vous continuer ?", "confirm_fee_deduction": "Confirmer la déduction des frais", "confirm_fee_deduction_content": "Acceptez-vous de déduire les frais de la production?", "confirm_passphrase": "Confirmer la phrase passante", "confirm_sending": "Confirmer l'envoi", - "confirm_silent_payments_switch_node": "Votre nœud actuel ne prend pas en charge les paiements silencieux \\ ncake qui passera à un nœud compatible, juste pour la numérisation", + "confirm_silent_payments_switch_node": "Votre nœud actuel ne prend pas en charge les paiements silencieux.\n\nCake Wallet passera à un nœud compatible pendant l'analyse.", "confirmations": "Confirmations", "confirmed": "Solde confirmé", "confirmed_tx": "Confirmé", @@ -178,7 +178,7 @@ "copy_id": "Copier l'ID", "copyWalletConnectLink": "Copiez le lien WalletConnect depuis l'application décentralisée (dApp) et collez-le ici", "corrupted_seed_notice": "Les fichiers de ce portefeuille sont corrompus et ne peuvent pas être ouverts. Veuillez consulter la phrase de graines, sauver et restaurer le portefeuille.\n\nSi la valeur est vide, la graine n'a pas pu être correctement récupérée.", - "countries": "Des pays", + "countries": "Pays", "create_account": "Créer un compte", "create_backup": "Créer une sauvegarde", "create_donation_link": "Créer un lien de don", @@ -189,8 +189,8 @@ "creating_new_wallet": "Création d'un nouveau portefeuille (wallet)", "creating_new_wallet_error": "Erreur : ${description}", "creation_date": "Date de création", - "custom": "personnalisé", - "custom_drag": "Custom (maintenir et traîner)", + "custom": "Personnalisé", + "custom_drag": "Personnalisé (Maintenir et Glisser)", "custom_redeem_amount": "Montant d'échange personnalisé", "custom_value": "Valeur personnalisée", "dark_theme": "Sombre", @@ -245,7 +245,7 @@ "enable": "Activer", "enable_mempool_api": "API Mempool pour les frais et dates précis", "enable_replace_by_fee": "Activer Remplace-by-Fee", - "enable_silent_payments_scanning": "Commencez à scanner les paiements silencieux, jusqu'à ce que la pointe soit atteinte", + "enable_silent_payments_scanning": "Commencez à analyser les transactions envoyées à votre adresse de paiement silencieux.", "enabled": "Activé", "enter_amount": "Entrez le montant", "enter_backup_password": "Entrez le mot de passe de sauvegarde ici", @@ -289,7 +289,7 @@ "event": "Événement", "events": "Événements", "exchange": "Échanger", - "exchange_incorrect_current_wallet_for_xmr": "Si vous souhaitez échanger XMR à partir de votre balance monero portefeuille de gâteau, veuillez d'abord passer à votre portefeuille Monero.", + "exchange_incorrect_current_wallet_for_xmr": "Si vous souhaitez échanger des XMR depuis le solde Monero de votre Cake Wallet, veuillez d'abord passer à votre portefeuille Monero.", "exchange_new_template": "Nouveau modèle d'échange", "exchange_provider_unsupported": "${providerName} n'est plus pris en charge !", "exchange_result_confirm": "En pressant confirmer, vous enverrez ${fetchingLabel} ${from} depuis votre portefeuille (wallet) nommé ${walletName} vers l'adresse ci-dessous. Vous pouvez aussi envoyer depuis votre portefeuille externe vers l'adresse/QR code ci-dessous.\n\nMerci d'appuyer sur confirmer pour continuer ou retournez en arrière pour modifier les montants.", @@ -370,11 +370,11 @@ "is_percentage": "est", "last_30_days": "30 derniers jours", "learn_more": "En savoir plus", - "ledger_connection_error": "Impossible de se connecter à votre grand livre. Veuillez réessayer.", - "ledger_error_device_locked": "Le grand livre est verrouillé", + "ledger_connection_error": "Impossible de se connecter à votre Ledger. Veuillez réessayer.", + "ledger_error_device_locked": "La Ledger est verrouillé", "ledger_error_tx_rejected_by_user": "Transaction rejetée sur l'appareil", - "ledger_error_wrong_app": "Veuillez vous assurer d'ouvrir la bonne application sur votre grand livre", - "ledger_please_enable_bluetooth": "Veuillez activer Bluetooth pour détecter votre grand livre", + "ledger_error_wrong_app": "Veuillez vous assurer d'ouvrir la bonne application sur votre Ledger", + "ledger_please_enable_bluetooth": "Veuillez activer le Bluetooth pour détecter votre Ledger", "light_theme": "Clair", "litecoin_enable_mweb_sync": "Activer la numérisation MWEB", "litecoin_mweb": "Mweb", @@ -386,8 +386,8 @@ "litecoin_mweb_enable_later": "Vous pouvez choisir d'activer à nouveau MWEB sous Paramètres d'affichage.", "litecoin_mweb_logs": "Journaux MWEB", "litecoin_mweb_node": "Node MWEB", - "litecoin_mweb_pegin": "Entraver", - "litecoin_mweb_pegout": "Crever", + "litecoin_mweb_pegin": "Dépôt Peg", + "litecoin_mweb_pegout": "Retrait Peg", "litecoin_mweb_scanning": "Scann mweb", "litecoin_mweb_settings": "Paramètres MWEB", "litecoin_mweb_warning": "L'utilisation de MWEB téléchargera initialement ~ 600 Mo de données et peut prendre jusqu'à 30 minutes en fonction de la vitesse du réseau. Ces données initiales ne téléchargeront qu'une seule fois et seront disponibles pour tous les portefeuilles litecoin", @@ -395,9 +395,9 @@ "live_fee_rates": "Taux de frais en direct via l'API", "load_more": "Charger plus", "loading_your_wallet": "Chargement de votre portefeuille (wallet)", - "login": "Utilisateur", + "login": "Connexion", "logout": "Déconnexion", - "low_fee": "Frais modiques", + "low_fee": "Frais faibles", "low_fee_alert": "Vous utilisez actuellement une priorité de frais de réseau peu élevés. Cela pourrait entraîner de longues attentes, des taux différents ou des transactions annulées. Nous vous recommandons de fixer des frais plus élevés pour une meilleure expérience.", "manage_nodes": "Gérer les nœuds", "manage_pow_nodes": "Gérer les nœuds PoW", @@ -428,9 +428,9 @@ "nano_current_rep": "Représentant actuel", "nano_gpt_thanks_message": "Merci d'avoir utilisé Nanogpt! N'oubliez pas de retourner au navigateur une fois votre transaction terminée!", "nano_pick_new_rep": "Choisissez un nouveau représentant", - "nanogpt_subtitle": "Tous les modèles les plus récents (GPT-4, Claude). \\ NNO abonnement, payez avec crypto.", - "narrow": "Étroit", - "new_first_wallet_text": "Garder votre crypto en sécurité est un morceau de gâteau", + "nanogpt_subtitle": "Tous les modèles les plus récents (GPT-4, Claude).\nPas d'abonnement, payez avec vos crypto-monnaies.", + "narrow": "Rédruit", + "new_first_wallet_text": "Garder vos crypto-monnaies en sécurité est un jeu d'enfant.", "new_node_testing": "Test du nouveau nœud", "new_subaddress_create": "Créer", "new_subaddress_label_name": "Nom", @@ -459,7 +459,7 @@ "note_optional": "Note (optionnelle)", "note_tap_to_change": "Note (appuyez pour changer)", "nullURIError": "L'URI est nul", - "offer_expires_in": "L'Offre expire dans : ", + "offer_expires_in": "L'Offre expire dans: ", "offline": "Hors ligne", "ok": "OK", "old_fee": "Anciens", @@ -517,7 +517,7 @@ "private_key": "Clef privée", "proceed_after_one_minute": "Si l'écran ne s'affiche pas après 1 minute, vérifiez vos e-mails.", "proceed_on_device": "Continuez sur votre appareil", - "proceed_on_device_description": "Veuillez suivre les instructions invitées sur votre portefeuille matériel", + "proceed_on_device_description": "Veuillez suivre les instructions affichées sur votre portefeuille physique.", "profile": "Profil", "provider_error": "Erreur de ${provider}", "public_key": "Clef publique", @@ -535,8 +535,8 @@ "reconnect": "Reconnecter", "reconnect_alert_text": "Êtes vous certain de vouloir vous reconnecter ?", "reconnection": "Reconnexion", - "red_dark_theme": "Thème rouge noir", - "red_light_theme": "Thème de la lumière rouge", + "red_dark_theme": "Thème rouge sombre", + "red_light_theme": "Thème rouge clair", "redeemed": "Converties", "refund_address": "Adresse de Remboursement", "reject": "Rejeter", @@ -567,9 +567,9 @@ "restore_address": "Adresse", "restore_bitcoin_description_from_keys": "Restaurer votre portefeuille (wallet) d'après la chaîne WIF générée d'après vos clefs privées", "restore_bitcoin_description_from_seed": "Restaurer votre portefeuille (wallet) à l'aide d'une phrase secrète (seed) de 24 mots", - "restore_bitcoin_title_from_keys": "Restaurer depuis la chaîne WIF", + "restore_bitcoin_title_from_keys": "Restaurer à partir de WIF", "restore_description_from_backup": "Vous pouvez restaurer l'intégralité de l'application Cake Wallet depuis un fichier de sauvegarde", - "restore_description_from_hardware_wallet": "Restaurer à partir d'un portefeuille matériel de grand livre", + "restore_description_from_hardware_wallet": "Restaurer depuis un portefeuille matériel Ledger", "restore_description_from_keys": "Restaurer votre portefeuille (wallet) d'après les séquences de touches générées d'après vos clefs privées", "restore_description_from_seed": "Restaurer votre portefeuille (wallet) depuis une phrase secrète (seed) de 25 ou 13 mots", "restore_description_from_seed_keys": "Restaurez votre portefeuille (wallet) depuis une phrase secrète (seed) ou des clefs que vous avez stockées en lieu sûr", @@ -636,10 +636,10 @@ "seed_reminder": "Merci d'écrire votre phrase secrète (seed) au cas où vous perdriez ou effaceriez votre téléphone", "seed_share": "Partager la phrase secrète (seed)", "seed_title": "Phrase secrète (seed)", - "seedtype": "Type de type graine", - "seedtype_alert_content": "Le partage de graines avec d'autres portefeuilles n'est possible qu'avec Bip39 SeedType.", - "seedtype_alert_title": "Alerte de type SeedType", - "seedtype_legacy": "Héritage (25 mots)", + "seedtype": "Type de graine", + "seedtype_alert_content": "Le partage de graines avec d'autres portefeuilles n'est possible qu'avec le type de graine BIP39.", + "seedtype_alert_title": "Alerte Type de Graine", + "seedtype_legacy": "Legacy (25 words)", "seedtype_polyseed": "Polyseed (16 mots)", "seedtype_wownero": "WOWNERO (14 mots)", "select_backup_file": "Sélectionnez le fichier de sauvegarde", @@ -652,13 +652,13 @@ "sell_monero_com_alert_content": "La vente de Monero n'est pas encore prise en charge", "send": "Envoyer", "send_address": "adresse ${cryptoCurrency}", - "send_amount": "Montant :", + "send_amount": "Montant:", "send_change_to_you": "Changer, pour vous:", "send_creating_transaction": "Création de la transaction", "send_error_currency": "La monnaie ne peut contenir que des nombres", "send_error_minimum_value": "La valeur minimale du montant est 0.01", "send_estimated_fee": "Estimation des frais :", - "send_fee": "Frais :", + "send_fee": "Frais:", "send_name": "Nom", "send_new": "Nouveau", "send_payment_id": "ID de paiement (optionnel)", @@ -672,9 +672,9 @@ "send_your_wallet": "Votre portefeuille (wallet)", "sending": "Envoi", "sent": "Envoyés", - "service_health_disabled": "Le bulletin de santé du service est handicapé", + "service_health_disabled": "Le bulletin de santé du service est désactivé.", "service_health_disabled_message": "Ceci est la page du Bulletin de santé du service, vous pouvez activer cette page sous Paramètres -> Confidentialité", - "set_a_pin": "Régler une goupille", + "set_a_pin": "Définir un code PIN", "settings": "Paramètres", "settings_all": "TOUT", "settings_allow_biometrical_authentication": "Autoriser l'authentification biométrique", @@ -704,7 +704,7 @@ "setup_pin": "Configurer le code PIN", "setup_successful": "Votre code PIN a été configuré avec succès !", "setup_totp_recommended": "Configurer TOTP", - "setup_warning_2fa_text": "Vous devrez restaurer votre portefeuille à partir de la graine mnémonique.\n\nLe support Cake ne pourra pas vous aider si vous perdez l'accès à vos graines 2FA ou mnémoniques.\nCake 2FA est une seconde authentification pour certaines actions dans le portefeuille. Avant d'utiliser Cake 2FA, nous vous recommandons de lire le guide.Ce n’est PAS aussi sécurisé que l’entreposage frigorifique.\n\nSi vous perdez l'accès à votre application 2FA ou à vos clés TOTP, vous perdrez l'accès à ce portefeuille. ", + "setup_warning_2fa_text": "Vous devrez restaurer votre portefeuille à partir de la graine mnémotechnique.\n\nLe support Cake ne pourra pas vous aider si vous perdez l'accès à vos graines 2FA ou mnémotechniques.\nCake 2FA est une seconde authentification pour certaines actions dans le portefeuille. Avant d'utiliser Cake 2FA, nous vous recommandons de lire le guide.Ce n’est PAS aussi sécurisé que l’entreposage frigorifique.\n\nSi vous perdez l'accès à votre application 2FA ou à vos clés TOTP, vous perdrez l'accès à ce portefeuille. ", "setup_your_debit_card": "Configurer votre carte de débit", "share": "Partager", "share_address": "Partager l'adresse", @@ -731,15 +731,15 @@ "silent_payments_scan_from_date": "Analyser à partir de la date", "silent_payments_scan_from_date_or_blockheight": "Veuillez saisir la hauteur du bloc que vous souhaitez commencer à scanner pour les paiements silencieux entrants, ou utilisez la date à la place. Vous pouvez choisir si le portefeuille continue de numériser chaque bloc ou ne vérifie que la hauteur spécifiée.", "silent_payments_scan_from_height": "Scan à partir de la hauteur du bloc", - "silent_payments_scanned_tip": "Scanné à la pointe! (${tip})", - "silent_payments_scanning": "Payments silencieux SCANNING", + "silent_payments_scanned_tip": "SCANNEZ POUR DONNER ! (${tip})", + "silent_payments_scanning": "Scan des paiements silencieux", "silent_payments_settings": "Paramètres de paiement silencieux", "single_seed_wallets_group": "Portefeuilles de semences simples", "slidable": "Glissable", "sort_by": "Trier par", "spend_key_private": "Clef de dépense (spend key) (privée)", "spend_key_public": "Clef de dépense (spend key) (publique)", - "status": "Statut : ", + "status": "Statut: ", "string_default": "Défaut", "subaddress_title": "Liste des sous-adresses", "subaddresses": "Sous-adresses", @@ -752,7 +752,7 @@ "support_title_live_chat": "Support en direct", "support_title_other_links": "Autres liens d'assistance", "sweeping_wallet": "Portefeuille (wallet) de consolidation", - "sweeping_wallet_alert": "Cette opération ne devrait pas prendre longtemps. NE QUITTEZ PAS CET ÉCRAN OU LES FONDS CONSOLIDÉS POURRAIENT ÊTRE PERDUS", + "sweeping_wallet_alert": "Cela ne devrait pas prendre longtemps. NE QUITTEZ PAS CET ÉCRAN OU LES FONDS TRANSFÉRÉS POURRAIENT ÊTRE PERDUS.", "switchToETHWallet": "Veuillez passer à un portefeuille (wallet) Ethereum et réessayer", "switchToEVMCompatibleWallet": "Veuillez passer à un portefeuille compatible EVM et réessayer (Ethereum, Polygon)", "symbol": "Symbole", @@ -779,7 +779,7 @@ "thorchain_contract_address_not_supported": "Thorchain ne prend pas en charge l'envoi à une adresse de contrat", "thorchain_taproot_address_not_supported": "Le fournisseur de Thorchain ne prend pas en charge les adresses de tapoot. Veuillez modifier l'adresse ou sélectionner un autre fournisseur.", "time": "${minutes}m ${seconds}s", - "tip": "Pourboire :", + "tip": "Pourboire:", "today": "Aujourd'hui", "token_contract_address": "Adresse du contrat de token", "token_decimal": "Décimales de token", @@ -928,8 +928,8 @@ "wallets": "Portefeuilles", "warning": "Avertissement", "welcome": "Bienvenue sur", - "welcome_subtitle_new_wallet": "Si vous souhaitez recommencer à créer un nouveau portefeuille ci-dessous et vous serez parti pour les courses.", - "welcome_subtitle_restore_wallet": "Si vous avez un portefeuille existant que vous souhaitez apporter dans le gâteau, choisissez simplement restaurer le portefeuille existant et nous vous guiderons tout au long du processus.", + "welcome_subtitle_new_wallet": "Si vous souhaitez repartir de zéro, appuyez sur Créer un nouveau portefeuille ci-dessous et vous serez prêt à commencer.", + "welcome_subtitle_restore_wallet": "Si vous avez un portefeuille existant que vous souhaitez importer dans Cake, choisissez simplement Restaurer un portefeuille existant et nous vous guiderons à travers le processus.", "welcome_to_cakepay": "Bienvenue sur Cake Pay !", "what_is_silent_payments": "Qu'est-ce que les paiements silencieux?", "widgets_address": "Adresse", From 0691b9ddb35fb2443bccf8fd395e67920d091012 Mon Sep 17 00:00:00 2001 From: ArTombado <45319004+ArTombado@users.noreply.github.com> Date: Tue, 3 Dec 2024 08:03:24 -0300 Subject: [PATCH 38/41] NanoGPT portuguese string fix (#1839) --- res/values/strings_pt.arb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index b910d49b2..6bf05ae46 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -429,7 +429,7 @@ "nano_current_rep": "Representante atual", "nano_gpt_thanks_message": "Obrigado por usar o Nanogpt! Lembre -se de voltar para o navegador após a conclusão da transação!", "nano_pick_new_rep": "Escolha um novo representante", - "nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude). \\ Nno assinatura, pagam com criptografia.", + "nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude). \\nSem assinatura, pague com criptomoeda.", "narrow": "Estreito", "new_first_wallet_text": "Manter sua cripto segura é um pedaço de bolo", "new_node_testing": "Teste de novo nó", @@ -963,4 +963,4 @@ "you_will_get": "Converter para", "you_will_send": "Converter de", "yy": "aa" -} \ No newline at end of file +} From 01faeabefeb449800ea8049a3801771de8184914 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Tue, 3 Dec 2024 14:04:11 +0300 Subject: [PATCH 39/41] test (#1842) * test * macos new build --- .github/workflows/pr_test_build_linux.yml | 2 +- lib/core/address_validator.dart | 2 +- .../screens/cake_pay/cards/cake_pay_buy_card_page.dart | 7 ++----- scripts/android/app_env.sh | 4 ++-- scripts/ios/app_env.sh | 8 ++++---- scripts/macos/app_env.sh | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml index 9e25f9f7a..c37b11582 100644 --- a/.github/workflows/pr_test_build_linux.yml +++ b/.github/workflows/pr_test_build_linux.yml @@ -38,7 +38,7 @@ jobs: - name: Flutter action uses: subosito/flutter-action@v1 with: - flutter-version: "3.24.4" + flutter-version: "3.24.0" channel: stable - name: Install package dependencies diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index 9ca8a41ad..c122a872b 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -134,7 +134,7 @@ class AddressValidator extends TextValidator { case CryptoCurrency.btcln: pattern = '(lnbc|LNBC)([0-9]{1,}[a-zA-Z0-9]+)'; default: - pattern = '[0-9a-zA-Z]+'; + return ''; } return '$BEFORE_REGEX($pattern)$AFTER_REGEX'; diff --git a/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart b/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart index 21e35359b..bd1840974 100644 --- a/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart +++ b/lib/src/screens/cake_pay/cards/cake_pay_buy_card_page.dart @@ -248,14 +248,11 @@ class CakePayBuyCardPage extends BasePage { } bool isWordInCardsName(CakePayCard card, String word) { - // word must be followed by a space or beginning of the string - final regex = RegExp(r'(^|\s)' + word + r'(\s|$)', caseSensitive: false); - - return regex.hasMatch(card.name.toLowerCase()); + return card.name.toLowerCase().contains(word.toLowerCase()); } bool isIOSUnavailable(CakePayCard card) { - if (!Platform.isIOS) { + if (!Platform.isIOS && !Platform.isMacOS) { return false; } diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 79afc5c78..24f1f5a51 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -16,14 +16,14 @@ APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" MONERO_COM_VERSION="1.18.2" -MONERO_COM_BUILD_NUMBER=107 +MONERO_COM_BUILD_NUMBER=108 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.21.2" -CAKEWALLET_BUILD_NUMBER=238 +CAKEWALLET_BUILD_NUMBER=239 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 2ca0df21d..816ddd29a 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.18.1" -MONERO_COM_BUILD_NUMBER=104 +MONERO_COM_VERSION="1.18.2" +MONERO_COM_BUILD_NUMBER=105 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.21.1" -CAKEWALLET_BUILD_NUMBER=283 +CAKEWALLET_VERSION="4.21.2" +CAKEWALLET_BUILD_NUMBER=284 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index 930a1e5ed..c9fa6d81e 100755 --- a/scripts/macos/app_env.sh +++ b/scripts/macos/app_env.sh @@ -22,7 +22,7 @@ MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_VERSION="1.14.1" -CAKEWALLET_BUILD_NUMBER=96 +CAKEWALLET_BUILD_NUMBER=97 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then From ad6eb7db150a873de54ac4bcc82f174f3e93727a Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Tue, 3 Dec 2024 21:29:40 +0300 Subject: [PATCH 40/41] macos new build linux new build --- android/app/build.gradle | 2 +- .../screens/dashboard/pages/cake_features_page.dart | 12 ++++++++++-- scripts/linux/app_env.sh | 4 ++-- scripts/macos/app_env.sh | 4 ++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index c19211117..238dc769d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,7 @@ android { disable 'InvalidPackage' } - namespace appProperties['id'] + namespace "com.cakewallet.cake_wallet" defaultConfig { applicationId appProperties['id'] diff --git a/lib/src/screens/dashboard/pages/cake_features_page.dart b/lib/src/screens/dashboard/pages/cake_features_page.dart index 775cb6c3f..07d023b28 100644 --- a/lib/src/screens/dashboard/pages/cake_features_page.dart +++ b/lib/src/screens/dashboard/pages/cake_features_page.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; @@ -40,7 +42,13 @@ class CakeFeaturesPage extends StatelessWidget { children: [ SizedBox(height: 20), DashBoardRoundedCardWidget( - onTap: () => _navigatorToGiftCardsPage(context), + onTap: () { + if (Platform.isMacOS) { + _launchUrl("buy.cakepay.com"); + } else { + _navigatorToGiftCardsPage(context); + } + }, title: 'Cake Pay', subTitle: S.of(context).cake_pay_subtitle, image: Image.asset( @@ -75,7 +83,7 @@ class CakeFeaturesPage extends StatelessWidget { icon: Icon( Icons.speaker_notes_rounded, color: - Theme.of(context).extension()!.pageTitleTextColor, + Theme.of(context).extension()!.pageTitleTextColor, size: 75, ), ); diff --git a/scripts/linux/app_env.sh b/scripts/linux/app_env.sh index 77a33ccfd..12f4cf8be 100755 --- a/scripts/linux/app_env.sh +++ b/scripts/linux/app_env.sh @@ -14,8 +14,8 @@ if [ -n "$1" ]; then fi CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.11.1" -CAKEWALLET_BUILD_NUMBER=39 +CAKEWALLET_VERSION="1.11.2" +CAKEWALLET_BUILD_NUMBER=40 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then echo "Wrong app type." diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index c9fa6d81e..bed3eb326 100755 --- a/scripts/macos/app_env.sh +++ b/scripts/macos/app_env.sh @@ -21,8 +21,8 @@ MONERO_COM_BUILD_NUMBER=37 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.14.1" -CAKEWALLET_BUILD_NUMBER=97 +CAKEWALLET_VERSION="1.14.2" +CAKEWALLET_BUILD_NUMBER=98 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then From 9fcbc4d72a9d1b763f8fdfc21071f6024e1b4630 Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 4 Dec 2024 07:01:49 -0500 Subject: [PATCH 41/41] CW-846: Correctly display balance (#1848) * Correctly display balance even with frozen coins * remove package= from AndroidMainfest.xml * update namespace --- android/app/src/debug/AndroidManifest.xml | 3 +-- android/app/src/profile/AndroidManifest.xml | 3 +-- cw_core/lib/monero_balance.dart | 4 ++-- cw_monero/lib/monero_wallet.dart | 5 +++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index dc767a55d..f880684a6 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml index dc767a55d..f880684a6 100644 --- a/android/app/src/profile/AndroidManifest.xml +++ b/android/app/src/profile/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/cw_core/lib/monero_balance.dart b/cw_core/lib/monero_balance.dart index 98a7f134a..9a63c407e 100644 --- a/cw_core/lib/monero_balance.dart +++ b/cw_core/lib/monero_balance.dart @@ -3,8 +3,8 @@ import 'package:cw_core/monero_amount_format.dart'; class MoneroBalance extends Balance { MoneroBalance({required this.fullBalance, required this.unlockedBalance, this.frozenBalance = 0}) - : formattedFullBalance = moneroAmountToString(amount: fullBalance), - formattedUnlockedBalance = moneroAmountToString(amount: unlockedBalance - frozenBalance), + : formattedFullBalance = moneroAmountToString(amount: frozenBalance + fullBalance), + formattedUnlockedBalance = moneroAmountToString(amount: unlockedBalance), formattedLockedBalance = moneroAmountToString(amount: frozenBalance + fullBalance - unlockedBalance), super(unlockedBalance, fullBalance); diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index 2b302e745..d7a67c47d 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -725,8 +725,9 @@ abstract class MoneroWalletBase extends WalletBase