Squashed commit of the following:

commit 1ca09e692d
Author: Serhii <borodenko.sv@gmail.com>
Date:   Thu Jun 29 16:44:31 2023 +0300

    Revert "Merge branch 'linux/password-direct-input' of https://github.com/cake-tech/cake_wallet into linux/password-direct-input"

    This reverts commit 424cf2e635, reversing
    changes made to e1fe03ca28.

commit 02eead0014
Author: Serhii <borodenko.sv@gmail.com>
Date:   Thu Jun 29 16:38:36 2023 +0300

    Revert " fix routing and context issue"

    This reverts commit e1fe03ca28.

commit 424cf2e635
Merge: e1fe03ca fc18b2dc
Author: Serhii <borodenko.sv@gmail.com>
Date:   Thu Jun 29 14:01:18 2023 +0300

    Merge branch 'linux/password-direct-input' of https://github.com/cake-tech/cake_wallet into linux/password-direct-input

commit e1fe03ca28
Author: Serhii <borodenko.sv@gmail.com>
Date:   Thu Jun 29 14:00:12 2023 +0300

     fix routing and context issue

commit fc18b2dc52
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jun 16 22:25:27 2023 +0300

    - Pump Linux version
    - Fix conflicts with main

commit 2da9112aa2
Merge: e592c892 3f2af133
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jun 16 22:14:52 2023 +0300

    Merge branch 'v4.6.7_v1.3.8' of https://github.com/cake-tech/cake_wallet into linux/password-direct-input

     Conflicts:
    	cw_bitcoin/lib/electrum_wallet.dart
    	lib/di.dart
    	lib/main.dart
    	lib/src/screens/dashboard/widgets/market_place_page.dart

commit 3f2af1334d
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jun 16 21:43:33 2023 +0300

    Pump app versions and update release notes

commit 8ffad4bf80
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jun 16 19:54:34 2023 +0300

    Revert removing swipe to delete wallet feature

commit 337bfd0527
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jun 16 17:05:00 2023 +0300

    - Replace payfura widget with direct browser link
    - Remove Payfura widget class as it is duplicate for the web view page

commit e592c892cc
Author: Rafael Saes <76502841+saltrafael@users.noreply.github.com>
Date:   Fri May 26 17:16:36 2023 -0300

    fix: theme refactor for wallet_unlock_page.dart (#951)

commit 76559e50d6
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri May 26 21:52:02 2023 +0300

    Remove secure storage

commit 825c99094f
Merge: 5ba313cb 19cbc40e
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri May 26 21:16:08 2023 +0300

    Merge branch 'main' of https://github.com/cake-tech/cake_wallet into linux/password-direct-input

commit 5ba313cb13
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri May 26 16:43:30 2023 +0300

    Fix Conflicts with main

commit 53d3db5340
Merge: 3ddb6c0a 75c65d67
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri May 26 15:09:55 2023 +0300

    Merge branch 'main' of https://github.com/cake-tech/cake_wallet into linux/password-direct-input

     Conflicts:
    	cw_core/lib/wallet_base.dart
    	lib/core/auth_service.dart
    	lib/di.dart
    	lib/main.dart
    	lib/router.dart
    	lib/routes.dart
    	lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
    	lib/src/screens/restore/restore_wallet_from_seed_page.dart
    	lib/src/screens/settings/security_backup_page.dart
    	lib/src/screens/wallet_list/wallet_list_page.dart
    	lib/store/settings_store.dart
    	lib/view_model/wallet_creation_vm.dart
    	macos/Podfile.lock
    	pubspec_base.yaml
    	res/values/strings_bg.arb
    	res/values/strings_en.arb
    	res/values/strings_id.arb
    	res/values/strings_my.arb
    	res/values/strings_nl.arb
    	res/values/strings_pt.arb
    	res/values/strings_ru.arb
    	res/values/strings_th.arb
    	res/values/strings_tr.arb
    	res/values/strings_uk.arb
    	res/values/strings_ur.arb
    	res/values/strings_zh.arb

commit 3ddb6c0a40
Author: M <m@cakewallet.com>
Date:   Thu Apr 27 21:17:41 2023 -0400

    Add flatpak section to Linux build guide.

commit 89980cac5a
Author: M <m@cakewallet.com>
Date:   Thu Apr 27 20:51:35 2023 -0400

    Add flatpak manifest. Add desktop file for Linux.

commit 0dc2effe41
Author: M <m@cakewallet.com>
Date:   Tue Apr 25 16:44:14 2023 -0400

    Add check gcc and troubleshooting section to Linux build guide.

commit d4b96d6f98
Author: M <m@cakewallet.com>
Date:   Fri Apr 21 18:08:42 2023 -0400

    Add build guide for Linux.

commit c7138a9124
Author: M <m@cakewallet.com>
Date:   Fri Apr 21 18:06:05 2023 -0400

    Make `model_generator.sh` executable.

commit d45df36238
Author: M <m@cakewallet.com>
Date:   Fri Apr 21 18:02:19 2023 -0400

    Add ability to get random bytes on Linux. Used same method as in cake backups.

commit 5c2490e721
Author: M <m@cakewallet.com>
Date:   Fri Apr 21 15:55:26 2023 -0400

    Update boost version for Linux to 1.82. Update monero for Linux to 0.18.2.2.

commit d251539f13
Author: M <m@cakewallet.com>
Date:   Fri Apr 21 11:48:02 2023 -0400

    Change package_info to package_info_plus

commit a90966b640
Author: M <m@cakewallet.com>
Date:   Wed Apr 19 17:20:04 2023 -0400

    Remove unused constant MONERO_BLOCK_SIZE in ios/Classes/monero_api.cpp

commit d34dca99ed
Author: M <m@cakewallet.com>
Date:   Wed Apr 19 16:11:01 2023 -0400

    Remove duplication for routes. Removed unused constant and fixed TransactionInfoRow iterator for macos/Classes/monero_api.cpp.

commit 2ff6cf43b3
Merge: 2e19e9d2 27961f2f
Author: M <m@cakewallet.com>
Date:   Wed Apr 19 15:18:43 2023 -0400

    Merge branch 'main' of github.com:cake-tech/cake_wallet into linux/password-direct-input

commit 2e19e9d2b6
Author: M <m@cakewallet.com>
Date:   Tue Apr 18 16:45:32 2023 -0400

    Fixes for Linux build scripts. Fixes for load cw_monero on Linux. Catch exception for get PackageInfo in SettingsStore. Add `excludeFlutterSecureStorage` to app_config.sh for Linux. Add FUNCTION_VISABILITY_ATTRIBUTE for monero_api.cpp.

commit 9cd02b7541
Merge: 8efedbcc 786ba3b0
Author: M <m@cakewallet.com>
Date:   Tue Apr 18 15:45:32 2023 -0400

    Merge branch 'desktop-linux' of github.com:cake-tech/cake_wallet into linux/password-direct-input

commit 8efedbccf6
Author: M <m@cakewallet.com>
Date:   Thu Apr 13 19:48:51 2023 -0400

    Add ability to set custom data application directory

commit f52c45b167
Author: M <m@cakewallet.com>
Date:   Mon Apr 10 19:16:13 2023 -0400

    Change encryption method for electrum wallets is wallet password provides directly. Add ability to user for repeat wallets password and compare with original wallet password before wallet creation for cases when wallet password provides directly.

commit 3b82a390c1
Author: M <m@cakewallet.com>
Date:   Thu Mar 30 18:33:59 2023 -0400

    Add ability to enter wallet password directly. Add ability to build without flutter secure storage. Add `excludeFlutterSecureStorage` flag to too/configure.dart for settings for secure storage. Add wallet unlock screen.

commit a70b6f298c
Merge: f0164db4 14a4d413
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Mon Feb 27 15:11:54 2023 +0200

    Merge pull request #804 from cake-tech/desktop-ui-enhancements

    Desktop UI enhancements

commit 14a4d41339
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Sat Feb 25 00:07:15 2023 +0200

    Fixate MobX version to fix restore issue

commit e8fa3953b5
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 17:17:30 2023 +0200

    Fix Navigation animation for settings screens

commit 89aaa9bfef
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:49:37 2023 +0200

    Add back wallet settings page to desktop settings actions

commit 26a7bfcee5
Merge: f00dc913 f0164db4
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:39:01 2023 +0200

    Merge branch 'dashboard-desktop-view' of https://github.com/cake-tech/cake_wallet into desktop-ui-enhancements

commit f0164db47f
Merge: f050f022 143a6eec
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:38:35 2023 +0200

    Merge pull request #802 from cake-tech/CW-321-lock-app-feature-on-mac

    Add app lock feature on mac

commit 143a6eecf5
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:38:05 2023 +0200

    pop only PIN screen after successful auth

commit a210a1e325
Merge: 538220f7 f050f022
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:23:36 2023 +0200

    Merge branch 'dashboard-desktop-view' of https://github.com/cake-tech/cake_wallet into CW-321-lock-app-feature-on-mac

commit f00dc9132c
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:19:59 2023 +0200

    Fix UI issues
    Add missing translation

commit 05b1bb05c4
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:18:31 2023 +0200

    Enable adding contact from send screen

commit b7e9237963
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 15:18:01 2023 +0200

    Add Nano currency image

commit 538220f7bc
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 24 14:50:19 2023 +0200

    Add assertion to avoid null

commit 770ed710d7
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 24 14:24:40 2023 +0200

    Add app lock feature on mac

commit f050f022b6
Merge: f8acc1c0 ac099075
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 24 00:40:19 2023 +0200

    Merge branch 'main' of https://github.com/cake-tech/cake_wallet into dashboard-desktop-view

     Conflicts:
    	lib/src/screens/buy/onramper_page.dart
    	lib/src/screens/seed/wallet_seed_page.dart
    	pubspec_base.yaml
    	res/values/strings_de.arb
    	res/values/strings_en.arb
    	res/values/strings_es.arb
    	res/values/strings_fr.arb
    	res/values/strings_hi.arb
    	res/values/strings_hr.arb
    	res/values/strings_it.arb
    	res/values/strings_ja.arb
    	res/values/strings_ko.arb
    	res/values/strings_nl.arb
    	res/values/strings_pl.arb
    	res/values/strings_pt.arb
    	res/values/strings_ru.arb
    	res/values/strings_uk.arb
    	res/values/strings_zh.arb

commit f8acc1c007
Merge: 67503f39 d3eb22e1
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 23 21:56:50 2023 +0200

    Merge pull request #791 from cake-tech/fix-desktop-colors-addressbook

    Fix desktop background color and address book view issues

commit d3eb22e1d4
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 23 21:16:28 2023 +0200

    Replace removed code

commit 8d482464d9
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 23 18:56:20 2023 +0200

    Fix ionia input field alignment

commit 67503f393d
Merge: 99344600 016bca01
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 23 18:24:32 2023 +0200

    Merge pull request #797 from cake-tech/align-create-restore-screens

    Fix alignment in create and restore wallet screens

commit 016bca01f4
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 23 18:18:40 2023 +0200

    remove unused code

commit 9934460004
Merge: 7a504abc bba0ce2e
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 23 18:06:27 2023 +0200

    Merge pull request #796 from cake-tech/fix-popup-width-constraints

    Fix Popup width constraint and add focus orders

commit bba0ce2ec6
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 23 18:03:44 2023 +0200

    Remove autofocus

commit 28c599e68a
Merge: d5e9982e 7a504abc
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 23 17:51:26 2023 +0200

    Merge branch 'dashboard-desktop-view' of https://github.com/cake-tech/cake_wallet into align-create-restore-screens

commit d5e9982e91
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 23 16:03:20 2023 +0200

    override navbar with desktopnavbar

commit 7a504abc01
Merge: c05d70b1 9616974d
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 22 19:31:37 2023 +0200

    Merge pull request #787 from cake-tech/macos-fix-settings-create-wallet

    Fix wallet create in settings

commit 9616974d33
Merge: 75d52794 24dc9bea
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 22 19:05:20 2023 +0200

    Merge pull request #790 from cake-tech/add-create-restore-dropdown

    Add create and restore wallet options to dropdown menu

commit 24dc9bea27
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 22 18:47:00 2023 +0200

    remove space

commit 6dc4eafff4
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 22 18:44:49 2023 +0200

    Fix dropdown change state bug

    Hide scanner for desktop

commit c41b6b7f89
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 22 16:17:26 2023 +0200

    Fix alignment in create and restore wallet screens

commit 07f6f43e0b
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Tue Feb 21 22:05:02 2023 +0200

    refactor dropdown items

commit 88e245e480
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Tue Feb 21 12:22:32 2023 +0200

    Fix issues from code review

commit c05d70b118
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Feb 21 01:52:47 2023 +0200

    Fix variable name

commit 44b1eec81d
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Mon Feb 20 23:24:19 2023 +0200

    Fix Popup width constraint and add focus orders

commit 17aa72e460
Merge: 1b892288 c920b62a
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Mon Feb 20 14:48:22 2023 +0200

    Merge pull request #792 from cake-tech/add-keyboard-control

    Add keyboard control for desktop

commit cf125d1e06
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Sat Feb 18 14:23:48 2023 +0200

    Fix issue from code review

commit c920b62aa0
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Sat Feb 18 00:13:51 2023 +0200

    Add onFieldSubmitted to allow "enter" button interaction

commit 59a79242af
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 17 19:06:41 2023 +0200

    Fix input field

commit 52468e1331
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 17 18:19:26 2023 +0200

    Fix desktop background color and address book view issues

commit 4bc81242fc
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 17 16:41:49 2023 +0200

    Add create and restore wallet options to dropdown menu

commit 75d52794f4
Merge: e0970fa1 1b892288
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 16 18:27:19 2023 +0200

    Merge branch 'dashboard-desktop-view' of https://github.com/cake-tech/cake_wallet into macos-fix-settings-create-wallet

commit e0970fa182
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 16 18:05:10 2023 +0200

    fix pageview controller reset index

commit 1b89228893
Merge: bb05573c 4027ea04
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 16 17:57:43 2023 +0200

    Merge pull request #745 from cake-tech/CW-301-desktop-side-bar-ui

    Add desktop sidebar

commit 4027ea04eb
Merge: dd13172c 0015f41a
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 16 17:54:54 2023 +0200

    Merge pull request #775 from cake-tech/CW-311-remove-drawer-from-mac-os

    Replace drawer icon for mac os

commit 0015f41a0d
Merge: 5a77aa20 55bf964a
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 16 17:52:24 2023 +0200

    Merge pull request #785 from cake-tech/desktop-ui-for-exchange-send

    Desktop UI for exchange send

commit 55bf964a27
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 16 17:51:52 2023 +0200

    - Use close icon on main screens
    - Minor UI fixes

commit 5296a2118a
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 15 23:50:15 2023 +0200

    Remove duplicated constrains

commit 2496a6574a
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 15 22:14:07 2023 +0200

    remove unnecessary code

commit f0c4952809
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 15 22:13:24 2023 +0200

    remove unnecessary code

commit 3dcf5b05a5
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 15 22:11:34 2023 +0200

    Fix wallet create in settings

commit 8de9c80fe1
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 15 20:55:06 2023 +0200

    Rename misleading variable
    Change initial mac window size

commit f8d70e7ce6
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 15 16:07:46 2023 +0200

    Fix UI issues, paddings and alignments

commit b1947426fb
Merge: 843db656 5a77aa20
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 15 03:09:38 2023 +0200

    Merge branch 'CW-311-remove-drawer-from-mac-os' of https://github.com/cake-tech/cake_wallet into desktop-ui-for-exchange-send

     Conflicts:
    	lib/src/screens/dashboard/desktop_dashboard_page.dart
    	lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart

commit 843db65603
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 15 01:28:10 2023 +0200

    Add width constraints to desktop dashboard

commit 5a77aa2017
Merge: 107e136f 6caeae28
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 15 01:20:05 2023 +0200

    Merge pull request #786 from cake-tech/CW-312-mac-os-settings-icon-to-be-a-toggle

    MacOS settings icon to be a toggle

commit 6caeae2817
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Tue Feb 14 21:55:13 2023 +0200

    Add padding to support page

commit ea09bba0fb
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Tue Feb 14 21:53:17 2023 +0200

    Make side menu items toggle back to dashboard

commit 02fe3c008f
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Feb 14 18:05:44 2023 +0200

    Constrain primary Buttons width

commit fb5efc0429
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Feb 14 18:01:24 2023 +0200

    Fix Desktop dashboard actions background color

commit 8f76232937
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Feb 14 17:21:09 2023 +0200

    - Change design/paddings for Send page on desktop view
    - Make AddTemplateButton instead of having it duplicated in send/exchange

commit bd04383b7c
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Feb 14 01:36:34 2023 +0200

    Change Exchange page UI depending on platform

commit 10b877f55e
Merge: 107e136f dd13172c
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Sat Feb 11 00:48:16 2023 +0200

    Merge branch 'CW-301-desktop-side-bar-ui' of https://github.com/cake-tech/cake_wallet into CW-311-remove-drawer-from-mac-os

commit dd13172cfe
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Sat Feb 11 00:41:48 2023 +0200

    Add max width constrain to Welcome page

commit 107e136f52
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Sat Feb 11 00:35:11 2023 +0200

    remove empty line

commit bdfe070f8d
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Sat Feb 11 00:32:26 2023 +0200

    Refactor sidebar state management

commit 770e3b6f52
Merge: 99bb3cce 5fa50c76
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 23:29:36 2023 +0200

    Merge pull request #774 from cake-tech/CW-310-add-constraints-to-images-on-macos

    [CW-310] Add constraints to images on macos

commit 5fa50c7668
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 23:27:19 2023 +0200

    Fix Constrained width screens UI

commit c1bf0ee7aa
Merge: eb3b2464 99bb3cce
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 22:54:13 2023 +0200

    Merge branch 'CW-301-desktop-side-bar-ui' of https://github.com/cake-tech/cake_wallet into CW-310-add-constraints-to-images-on-macos

     Conflicts:
    	lib/src/screens/pin_code/pin_code_widget.dart

commit 99bb3cce47
Merge: 2623546b 3fb8be00
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 22:34:18 2023 +0200

    Merge pull request #779 from cake-tech/CW-318-desktop-marketplace

    Add Marketplace to dashboard view

commit 3fb8be0053
Merge: 887afdad 2623546b
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 22:33:31 2023 +0200

    Merge branch 'CW-301-desktop-side-bar-ui' of https://github.com/cake-tech/cake_wallet into CW-318-desktop-marketplace

     Conflicts:
    	lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart

commit 2623546b5e
Merge: 2b2bebe9 2ea360d8
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 22:09:55 2023 +0200

    Merge pull request #776 from cake-tech/CW-309-allow-pin-keyboard-entry-on-macos

    Allow Keyboard usage on PIN screen

commit 887afdadd0
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 20:39:23 2023 +0200

    Change ionia welcome page animation

commit 2b2bebe98f
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 20:26:07 2023 +0200

    Refresh desktop dashboard actions on wallet change

commit eb3b246437
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 10 20:19:13 2023 +0200

    Add empty trailing to center page title on desktop

commit 32d2bf2c85
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 10 20:07:53 2023 +0200

    Update widget contraints

commit 89fe8df459
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Fri Feb 10 19:45:48 2023 +0200

    Update trailing icon to open transaction page

commit 6d49e6a543
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 18:40:50 2023 +0200

    Add Marketplace to dashboard view

commit 2ea360d81d
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Feb 10 18:15:05 2023 +0200

    Fix desktop nav bar UI

commit 677305f625
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 9 22:53:02 2023 +0200

    - Listen to keyboard events in PIN screen
    - Fix PIN buttons style

commit 1831ebf435
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 9 20:29:38 2023 +0200

    Remove drawer from mac os

commit 150d43b2da
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 9 20:11:20 2023 +0200

    constraint images and pincoded box

commit a116241185
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 9 19:17:52 2023 +0200

    Separate Dashboard desktop view from mobile view

commit 5c89c42540
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 9 16:53:07 2023 +0200

    [skip ci] remove .project changes

commit dd2bf60b01
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Thu Feb 9 16:51:49 2023 +0200

    [skip ci] remove .project changes

commit 167eae1293
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 9 16:10:43 2023 +0200

    Revert changes in .gitignore

commit 30d16266c0
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Feb 9 16:02:02 2023 +0200

    Revert removing .lock files

commit 3c17310a5b
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 8 22:12:11 2023 +0200

    [skip ci] reformat desktop dashboard

commit 48ae156eb8
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 8 21:57:26 2023 +0200

    [skip ci] reformat desktop dashboard

commit b1b8193043
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 8 20:41:46 2023 +0200

    Fix issues from code review

commit a1abdc849a
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Feb 8 18:56:00 2023 +0200

    Fix bug on sidebar reset

commit 3f03fb0b18
Merge: 69651b3e 9f69de80
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 8 15:50:37 2023 +0200

    Merge pull request #769 from cake-tech/fix-buy-feature-on-macos

    Fix buy feature on macos

commit 9f69de8057
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 8 15:49:26 2023 +0200

    Remove Podfile.lock from cache

commit 738621254f
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Feb 8 15:46:57 2023 +0200

    Add pubspec.lock and Podfile.lock to gitignore

commit 26b79fe0cd
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Mon Feb 6 18:23:40 2023 +0200

    - Refactor onRamper to have a single point of modification
    - Enlarge initial app size
    - update Flutter and Packages

commit dea81f92e3
Merge: c7db7b99 69651b3e
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Jan 31 16:48:36 2023 +0200

    Merge remote-tracking branch 'origin/CW-301-desktop-side-bar-ui' into CW-301-desktop-side-bar-ui

commit 69651b3eb4
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Tue Jan 31 15:30:46 2023 +0200

    Remove constants

commit c7db7b99a5
Merge: 9ed77cd6 4902dc8d
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Jan 31 15:23:47 2023 +0200

    Merge remote-tracking branch 'origin/CW-301-desktop-side-bar-ui' into CW-301-desktop-side-bar-ui

commit 4902dc8dd4
Merge: d12bcc80 bb05573c
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Tue Jan 31 15:12:01 2023 +0200

    Merge branch 'dashboard-desktop-view' of https://github.com/cake-tech/cake_wallet into CW-301-desktop-side-bar-ui

commit 9ed77cd6f9
Merge: d12bcc80 bb05573c
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Mon Jan 30 23:43:09 2023 +0200

    Merge branch 'dashboard-desktop-view' of https://github.com/cake-tech/cake_wallet into CW-301-desktop-side-bar-ui

     Conflicts:
    	lib/src/screens/dashboard/dashboard_page.dart

commit bb05573c3a
Merge: de2b887a c20eb232
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Mon Jan 30 23:33:44 2023 +0200

    Merge pull request #753 from cake-tech/mac-os-icons

    Mac os icons

commit d12bcc80d1
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Mon Jan 30 23:32:31 2023 +0200

    Fix exchange page as fullScreenDialog

commit de2b887a9b
Merge: abf5f0b7 adfebe69
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Mon Jan 30 23:31:59 2023 +0200

    Merge branch 'mac-os-fixes' of https://github.com/cake-tech/cake_wallet into dashboard-desktop-view

commit c20eb2325e
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Mon Jan 30 23:28:15 2023 +0200

    Change Mac os app name and bundle id

commit deadc93a76
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Mon Jan 30 23:23:42 2023 +0200

    fix dashboard sidebar and responsive utils

commit abf5f0b7c6
Merge: b6666ca4 5b50ea05
Author: Omar Hatem <omarh.ismail1@gmail.com>
Date:   Mon Jan 30 22:28:24 2023 +0200

    Merge pull request #754 from cake-tech/desktop-appbar-view

    Desktop AppBar

commit 94184d69d6
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Mon Jan 30 17:26:40 2023 +0200

    localize settings

commit d5957b9873
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Mon Jan 30 16:01:37 2023 +0200

    Generate MacOS icons

commit 5b50ea053e
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Sun Jan 29 16:49:42 2023 +0200

    Add Wallet selection dropdown to dashboard desktop view

commit b6666ca405
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Sat Jan 28 17:13:34 2023 +0200

    Ignore increasing brightness for non-mobile platforms

commit 75f33a433e
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Sat Jan 28 12:43:44 2023 +0200

    refactor desktop settings sidebar

commit adfebe6940
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Jan 26 20:53:26 2023 +0200

    Temporarily fetch unstoppable domains only on mobile

commit 132033207e
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Jan 26 02:33:15 2023 +0200

    Remove unstoppable domain from macos since it's not supported

commit 409c13a77a
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Jan 26 02:25:28 2023 +0200

    Remove wake lock native code and just use the ready made package

commit 90a7432bf9
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Jan 26 02:05:48 2023 +0200

    - Remove legacy migration from macos
    - Remove wake lock native code and just use the ready made package

commit 6b2bf313a3
Merge: 42a28d42 e8c1d863
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Jan 25 18:24:57 2023 +0200

    Merge branch 'mac-os-fixes' of https://github.com/cake-tech/cake_wallet into dashboard-desktop-view

commit 20ae8d530f
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Jan 25 16:17:50 2023 +0200

    [skip ci] Add desktop sidebar

commit ba09a24d53
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Jan 25 16:14:34 2023 +0200

    [skip ci] Add desktop sidebar

commit 4f1f51e0aa
Author: Godwin Asuquo <godilite@gmail.com>
Date:   Wed Jan 25 15:57:56 2023 +0200

    Add desktop sidebar

commit e8c1d86373
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Jan 25 02:38:28 2023 +0200

    Add platform channel specific code for mac os

commit 4aebbdace7
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Jan 25 00:14:28 2023 +0200

    Revert mac os version

commit fa072ff2f1
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Jan 25 00:11:18 2023 +0200

    Revert mac os version

commit 6e03d2933d
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Jan 25 00:07:11 2023 +0200

    Revert back to Cake fork for secure storage

commit c3c81f7685
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Jan 24 23:58:06 2023 +0200

    Revert back to Cake fork for secure storage

commit d41e7b7bab
Merge: ed0d87c8 ae3620b1
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jan 20 18:24:39 2023 +0200

    Merge branch 'desktop-mac-os' of https://github.com/cake-tech/cake_wallet into mac-os-fixes

commit ed0d87c893
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jan 20 17:45:54 2023 +0200

    Update deployment target to 10.13

commit dac7f8e1b3
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Fri Jan 20 15:02:08 2023 +0200

    Add Bundle ID in entitlements files through app config script

commit 786ba3b042
Author: M <m@cakewallet.com>
Date:   Thu Jan 19 18:14:46 2023 -0500

    Add linux application to the project.

commit ae3620b171
Author: M <m@cakewallet.com>
Date:   Thu Jan 19 15:54:59 2023 -0500

    Fix arch match for monero lib for darwin x86_64 -> x86-64

commit 42a28d4246
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Thu Jan 19 04:04:20 2023 +0200

    Add on Tap to desktop_action_button.dart
    Remove unused functions

commit 42a7439315
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Wed Jan 18 22:11:59 2023 +0200

    Change Dashboard view on desktop size screens

commit 9f1e663719
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Jan 17 22:06:05 2023 +0200

    Add network access to mac

commit 456ba28cb2
Author: OmarHatem <omarh.ismail1@gmail.com>
Date:   Tue Jan 17 21:10:39 2023 +0200

    - Update Flutter secure storage to work with macos
    - Enable uni links only on Mobile
    - Update devcelocale to work with macos

commit 31fa9e8b19
Author: M <m@cakewallet.com>
Date:   Tue Jan 10 21:15:24 2023 -0500

    Add build scripts for macOS. Add macos for cw_monero plugin. Add macos proj to the application.
This commit is contained in:
Rafael Saes 2023-09-07 12:52:44 -03:00
parent 68a821cc0e
commit 07a3622f55
165 changed files with 3640 additions and 1082 deletions

2
.gitignore vendored
View file

@ -144,3 +144,5 @@ assets/images/app_logo.png
macos/Runner/Info.plist
macos/Runner/DebugProfile.entitlements
macos/Runner/Release.entitlements
lib/core/secure_storage.dart

View file

@ -18,6 +18,9 @@ migration:
- platform: macos
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- platform: linux
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
# User provided section

View file

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 193 B

160
build-guide-linux.md Normal file
View file

@ -0,0 +1,160 @@
# Building CakeWallet for Linux
## Requirements and Setup
The following are the system requirements to build CakeWallet for your Linux device.
```
Ubuntu >= 16.04
Flutter 3 or above
```
## Building CakeWallet on Linux
These steps will help you configure and execute a build of CakeWallet from its source code.
### 1. Installing Package Dependencies
CakeWallet requires some packages to be install on your build system. You may easily install them on your build system with the following command:
`$ sudo apt install build-essential cmake pkg-config git curl autoconf libtool`
> ### Check gcc version
> Need to use gcc 10 or 9 for successfully link dependecnies with flutter.\
> Check what gcc version is using:\
> ```
> $ gcc --version
> $ g++ --version
> ```
> If you are using gcc version newer than 10, then need to downgrade to version 10.4.0.\
> ```
> $ sudo apt install gcc-10 g++-10
> $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
> $ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
> ```
### 2. Installing Flutter
Need to install flutter. For this please check section [How to install flutter on Linux](https://docs.flutter.dev/get-started/install/linux).
### 3. Verify Installations
Verify that the Flutter have been correctly installed on your system with the following command:
`$ flutter doctor`
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.x.x, on Linux, locale en_US.UTF-8)
```
### 4. Acquiring the CakeWallet Source Code
Download CakeWallet source code
`$ git clone https://github.com/cake-tech/cake_wallet.git --branch linux/password-direct-input`
Proceed into the source code before proceeding with the next steps:
`$ cd cake_wallet/scripts/linux/`
To configure some project properties run:
`$ ./cakewallet.sh`
Build the Monero libraries and their dependencies:
`$ ./build_all.sh`
Now the dependencies need to be copied into the CakeWallet project with this command:
`$ ./setup.sh`
It is now time to change back to the base directory of the CakeWallet source code:
`$ cd ../../`
Install Flutter package dependencies with this command:
`$ flutter pub get`
> #### If you will get an error like:
> ```
> The plugin `cw_shared_external` requires your app to be migrated to the Android embedding v2. Follow the steps on the migration doc above and re-run
> this command.
> ```
> Then need to config Android project settings. For this open `scripts/android` (`$ cd scripts/android`) directory and run followed commands:
> ```
> $ source ./app_env.sh cakewallet
> $ ./app_config.sh
> $ cd ../..
> ```
> Then re-configure Linux project again. For this open `scripts/linux` (`$cd scripts/linux`) directory and run:
> `$ ./cakewallet.sh`
> and back to project root directory:
> `$ cd ../..`
> and fetch dependecies again
> `$ flutter pub get`
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`
We will generate mobx models for the project.
`$ ./model_generator.sh`
Then we need to generate localization files.
`$ flutter packages pub run tool/generate_localization.dart`
### 5. Build!
`$ flutter build linux --release`
Path to executable file will be:
`build/linux/x64/release/bundle/cake_wallet`
> ### Troubleshooting
>
> If you got an error while building the application with `$ flutter build linux --release` command, add `-v` argument to the command (`$ flutter build linux -v --release`) to get details.\
> If you got in flutter build logs: undefined reference to `hid_free_enumeration`, or another error with undefined reference to `hid_*`, then rebuild monero lib without hidapi lib. Check does exists `libhidapi-dev` in your scope and remove it from your scope for build without it.
# Flatpak
For package the built application into flatpak you need fistly to install `flatpak` and `flatpak-builder`:
`$ sudo apt install flatpak flatpak-builder`
Then need to [add flathub](https://flatpak.org/setup/Ubuntu) (or just `$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`). Then need to install freedesktop runtime and sdk:
`$ flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08`
To build with using of `flatpak-build` directory run next:
`$ flatpak-builder --force-clean flatpak-build com.cakewallet.CakeWallet.yml`
And then export bundle:
`$ flatpak build-export export flatpak-build`
`$ flatpak build-bundle export cake_wallet.flatpak com.cakewallet.CakeWallet`
Result file: `cake_wallet.flatpak` should be generated in current directory.
For install generated flatpak file use:
`$ flatpak --user install cake_wallet.flatpak`
For run the installed application run:
`$ flatpak run com.cakewallet.CakeWallet`
Copyright (c) 2023 Cake Technologies LLC.

View file

@ -0,0 +1,35 @@
app-id: com.cakewallet.CakeWallet
runtime: org.freedesktop.Platform
runtime-version: '22.08'
sdk: org.freedesktop.Sdk
command: cake_wallet
separate-locales: false
finish-args:
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
- --device=dri
- --socket=pulseaudio
- --share=network
- --filesystem=home
modules:
- name: cake_wallet
buildsystem: simple
only-arches:
- x86_64
build-commands:
- "cp -R bundle /app/cake_wallet"
- "chmod +x /app/cake_wallet/cake_wallet"
- "mkdir -p /app/bin"
- "ln -s /app/cake_wallet/cake_wallet /app/bin/cake_wallet"
- "mkdir -p /app/share/icons/hicolor/scalable/apps"
- "cp cakewallet_icon_180.png /app/share/icons/hicolor/scalable/apps/com.cakewallet.CakeWallet.png"
- "mkdir -p /app/share/applications"
- "cp com.cakewallet.CakeWallet.desktop /app/share/applications"
sources:
- type: dir
path: build/linux/x64/release
- type: file
path: assets/images/cakewallet_icon_180.png
- type: file
path: linux/com.cakewallet.CakeWallet.desktop

View file

@ -1,4 +1,5 @@
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/encryption_file_utils.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:hive/hive.dart';
@ -23,6 +24,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required Uint8List seedBytes,
required EncryptionFileUtils encryptionFileUtils,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumBalance? initialBalance,
int initialRegularAddressIndex = 0,
@ -36,7 +38,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: seedBytes,
currency: CryptoCurrency.btc) {
currency: CryptoCurrency.btc,
encryptionFileUtils: encryptionFileUtils) {
walletAddresses = BitcoinWalletAddresses(
walletInfo,
electrumClient: electrumClient,
@ -54,6 +57,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required String password,
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required EncryptionFileUtils encryptionFileUtils,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumBalance? initialBalance,
int initialRegularAddressIndex = 0,
@ -66,6 +70,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
unspentCoinsInfo: unspentCoinsInfo,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
encryptionFileUtils: encryptionFileUtils,
seedBytes: await mnemonicToSeedBytes(mnemonic),
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex);
@ -76,8 +81,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required String password,
required EncryptionFileUtils encryptionFileUtils
}) async {
final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
final snp = await ElectrumWallletSnapshot.load(encryptionFileUtils, name, walletInfo.type, password);
return BitcoinWallet(
mnemonic: snp.mnemonic,
password: password,
@ -86,6 +92,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
initialAddresses: snp.addresses,
initialBalance: snp.balance,
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
encryptionFileUtils: encryptionFileUtils,
initialRegularAddressIndex: snp.regularAddressIndex,
initialChangeAddressIndex: snp.changeAddressIndex);
}

View file

@ -2,8 +2,8 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
class BitcoinNewWalletCredentials extends WalletCredentials {
BitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo})
: super(name: name, walletInfo: walletInfo);
BitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
: super(name: name, walletInfo: walletInfo, password: password);
}
class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cw_bitcoin/encryption_file_utils.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_service.dart';
@ -16,10 +17,11 @@ class BitcoinWalletService extends WalletService<
BitcoinNewWalletCredentials,
BitcoinRestoreWalletFromSeedCredentials,
BitcoinRestoreWalletFromWIFCredentials> {
BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
final Box<WalletInfo> walletInfoSource;
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
final bool isDirect;
@override
WalletType getType() => WalletType.bitcoin;
@ -30,7 +32,8 @@ class BitcoinWalletService extends WalletService<
mnemonic: await generateMnemonic(),
password: credentials.password!,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource);
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
await wallet.save();
await wallet.init();
return wallet;
@ -46,7 +49,8 @@ class BitcoinWalletService extends WalletService<
(info) => info.id == WalletBase.idFor(name, getType()))!;
final wallet = await BitcoinWalletBase.open(
password: password, name: name, walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource);
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
await wallet.init();
return wallet;
}
@ -95,7 +99,8 @@ class BitcoinWalletService extends WalletService<
password: credentials.password!,
mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource);
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
await wallet.save();
await wallet.init();
return wallet;

View file

@ -1,9 +1,9 @@
import 'dart:convert';
import 'package:cw_bitcoin/encryption_file_utils.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_bitcoin/file.dart';
import 'package:cw_bitcoin/electrum_transaction_info.dart';
part 'electrum_transaction_history.g.dart';
@ -16,13 +16,14 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase
abstract class ElectrumTransactionHistoryBase
extends TransactionHistoryBase<ElectrumTransactionInfo> with Store {
ElectrumTransactionHistoryBase(
{required this.walletInfo, required String password})
{required this.walletInfo, required String password, required this.encryptionFileUtils})
: _password = password,
_height = 0 {
transactions = ObservableMap<String, ElectrumTransactionInfo>();
}
final WalletInfo walletInfo;
final EncryptionFileUtils encryptionFileUtils;
String _password;
int _height;
@ -34,7 +35,7 @@ abstract class ElectrumTransactionHistoryBase
@override
void addMany(Map<String, ElectrumTransactionInfo> transactions) =>
transactions.forEach((_, tx) => _update(tx));
transactions.forEach((_, tx) => _updateOrInsert(tx));
@override
Future<void> save() async {
@ -44,7 +45,7 @@ abstract class ElectrumTransactionHistoryBase
final path = '$dirPath/$transactionsHistoryFileName';
final data =
json.encode({'height': _height, 'transactions': transactions});
await writeData(path: path, password: _password, data: data);
await encryptionFileUtils.write(path: path, password: _password, data: data);
} catch (e) {
print('Error while save bitcoin transaction history: ${e.toString()}');
}
@ -59,7 +60,7 @@ abstract class ElectrumTransactionHistoryBase
final dirPath =
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
final path = '$dirPath/$transactionsHistoryFileName';
final content = await read(path: path, password: _password);
final content = await encryptionFileUtils.read(path: path, password: _password);
return json.decode(content) as Map<String, dynamic>;
}
@ -73,7 +74,7 @@ abstract class ElectrumTransactionHistoryBase
if (val is Map<String, dynamic>) {
final tx = ElectrumTransactionInfo.fromJson(val, walletInfo.type);
_update(tx);
_updateOrInsert(tx);
}
});
@ -83,7 +84,18 @@ abstract class ElectrumTransactionHistoryBase
}
}
void _update(ElectrumTransactionInfo transaction) =>
transactions[transaction.id] = transaction;
void _updateOrInsert(ElectrumTransactionInfo transaction) {
if (transactions[transaction.id] == null) {
transactions[transaction.id] = transaction;
} else {
final originalTx = transactions[transaction.id];
originalTx?.confirmations = transaction.confirmations;
originalTx?.amount = transaction.amount;
originalTx?.height = transaction.height;
originalTx?.date ??= transaction.date;
originalTx?.isPending = transaction.isPending;
originalTx?.direction = transaction.direction;
}
}
}

View file

@ -2,6 +2,8 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:cw_bitcoin/encryption_file_utils.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:hive/hive.dart';
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
@ -14,6 +16,7 @@ import 'package:cw_core/pathForWallet.dart';
import 'package:cw_bitcoin/address_to_output_script.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
import 'package:cw_bitcoin/electrum_transaction_history.dart';
import 'package:cw_bitcoin/bitcoin_transaction_no_inputs_exception.dart';
@ -21,7 +24,6 @@ import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_bitcoin/bitcoin_transaction_wrong_balance_exception.dart';
import 'package:cw_bitcoin/bitcoin_unspent.dart';
import 'package:cw_bitcoin/bitcoin_wallet_keys.dart';
import 'package:cw_bitcoin/file.dart';
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
import 'package:cw_bitcoin/script_hash.dart';
import 'package:cw_bitcoin/utils.dart';
@ -48,6 +50,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
required this.networkType,
required this.mnemonic,
required Uint8List seedBytes,
required this.encryptionFileUtils,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumClient? electrumClient,
ElectrumBalance? initialBalance,
@ -70,7 +73,10 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
this.electrumClient = electrumClient ?? ElectrumClient();
this.walletInfo = walletInfo;
transactionHistory =
ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
ElectrumTransactionHistory(
walletInfo: walletInfo,
password: password,
encryptionFileUtils: encryptionFileUtils);
}
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
@ -78,6 +84,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
final bitcoin.HDWallet hd;
final String mnemonic;
final EncryptionFileUtils encryptionFileUtils;
late ElectrumClient electrumClient;
Box<UnspentCoinsInfo> unspentCoinsInfo;
@ -107,6 +114,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
@override
String get seed => mnemonic;
@override
String get password => _password;
bitcoin.NetworkType networkType;
@override
@ -119,8 +129,6 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
Map<String, BehaviorSubject<Object>?> _scripthashesUpdateSubject;
bool _isTransactionUpdating;
void Function(FlutterErrorDetails)? _onError;
Future<void> init() async {
await walletAddresses.init();
await transactionHistory.init();
@ -323,7 +331,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
} else {
feeAmount = feeRate(transactionCredentials.priority!) * estimatedSize;
}
final changeValue = totalInputAmount - amount - feeAmount;
if (changeValue > minAmount) {
@ -427,7 +435,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
@override
Future<void> save() async {
final path = await makePath();
await write(path: path, password: _password, data: toJSON());
await encryptionFileUtils.write(path: path, password: _password, data: toJSON());
await transactionHistory.save();
}
@ -665,13 +673,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
await updateUnspent();
await updateBalance();
await updateTransactions();
} catch (e, s) {
} catch (e) {
print(e.toString());
_onError?.call(FlutterErrorDetails(
exception: e,
stack: s,
library: this.runtimeType.toString(),
));
}
});
});
@ -737,7 +740,4 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
return addresses[random.nextInt(addresses.length)].address;
}
@override
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
}

View file

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/file.dart';
import 'package:cw_bitcoin/encryption_file_utils.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/wallet_type.dart';
@ -26,9 +26,9 @@ class ElectrumWallletSnapshot {
int regularAddressIndex;
int changeAddressIndex;
static Future<ElectrumWallletSnapshot> load(String name, WalletType type, String password) async {
static Future<ElectrumWallletSnapshot> load(EncryptionFileUtils encryptionFileUtils, String name, WalletType type, String password) async {
final path = await pathForWallet(name: name, type: type);
final jsonSource = await read(path: path, password: password);
final jsonSource = await encryptionFileUtils.read(path: path, password: password);
final data = json.decode(jsonSource) as Map;
final addressesTmp = data['addresses'] as List? ?? <Object>[];
final mnemonic = data['mnemonic'] as String;

View file

@ -0,0 +1,42 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:cw_bitcoin/file.dart' as bf;
import 'package:cake_backup/backup.dart' as cwb;
EncryptionFileUtils encryptionFileUtilsFor(bool direct)
=> direct
? XChaCha20EncryptionFileUtils()
: Salsa20EncryhptionFileUtils();
abstract class EncryptionFileUtils {
Future<void> write({required String path, required String password, required String data});
Future<String> read({required String path, required String password});
}
class Salsa20EncryhptionFileUtils extends EncryptionFileUtils {
// Requires legacy complex key + iv as password
@override
Future<void> write({required String path, required String password, required String data}) async
=> await bf.write(path: path, password: password, data: data);
// Requires legacy complex key + iv as password
@override
Future<String> read({required String path, required String password}) async
=> await bf.read(path: path, password: password);
}
class XChaCha20EncryptionFileUtils extends EncryptionFileUtils {
@override
Future<void> write({required String path, required String password, required String data}) async {
final encrypted = await cwb.encrypt(password, Uint8List.fromList(data.codeUnits));
await File(path).writeAsBytes(encrypted);
}
@override
Future<String> read({required String path, required String password}) async {
final file = File(path);
final encrypted = await file.readAsBytes();
final bytes = await cwb.decrypt(password, encrypted);
return String.fromCharCodes(bytes);
}
}

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:cw_core/key.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
// Do not use directly, move to Salsa20EncryhptionFile
Future<void> write(
{required String path,
required String password,

View file

@ -1,5 +1,6 @@
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_bitcoin/encryption_file_utils.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
@ -26,6 +27,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required Uint8List seedBytes,
required EncryptionFileUtils encryptionFileUtils,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumBalance? initialBalance,
int initialRegularAddressIndex = 0,
@ -39,6 +41,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: seedBytes,
encryptionFileUtils: encryptionFileUtils,
currency: CryptoCurrency.ltc) {
walletAddresses = LitecoinWalletAddresses(
walletInfo,
@ -58,6 +61,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
required String password,
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required EncryptionFileUtils encryptionFileUtils,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumBalance? initialBalance,
int initialRegularAddressIndex = 0,
@ -71,6 +75,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: await mnemonicToSeedBytes(mnemonic),
encryptionFileUtils: encryptionFileUtils,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex);
}
@ -80,8 +85,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required String password,
required EncryptionFileUtils encryptionFileUtils
}) async {
final snp = await ElectrumWallletSnapshot.load (name, walletInfo.type, password);
final snp = await ElectrumWallletSnapshot.load(encryptionFileUtils, name, walletInfo.type, password);
return LitecoinWallet(
mnemonic: snp.mnemonic,
password: password,
@ -90,6 +96,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
initialAddresses: snp.addresses,
initialBalance: snp.balance,
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
encryptionFileUtils: encryptionFileUtils,
initialRegularAddressIndex: snp.regularAddressIndex,
initialChangeAddressIndex: snp.changeAddressIndex);
}

View file

@ -1,4 +1,5 @@
import 'dart:io';
import 'package:cw_bitcoin/encryption_file_utils.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:hive/hive.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
@ -16,10 +17,11 @@ class LitecoinWalletService extends WalletService<
BitcoinNewWalletCredentials,
BitcoinRestoreWalletFromSeedCredentials,
BitcoinRestoreWalletFromWIFCredentials> {
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
final Box<WalletInfo> walletInfoSource;
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
final bool isDirect;
@override
WalletType getType() => WalletType.litecoin;
@ -30,7 +32,8 @@ class LitecoinWalletService extends WalletService<
mnemonic: await generateMnemonic(),
password: credentials.password!,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource);
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
await wallet.save();
await wallet.init();
@ -47,7 +50,8 @@ class LitecoinWalletService extends WalletService<
(info) => info.id == WalletBase.idFor(name, getType()))!;
final wallet = await LitecoinWalletBase.open(
password: password, name: name, walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource);
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
await wallet.init();
return wallet;
}
@ -96,7 +100,8 @@ class LitecoinWalletService extends WalletService<
password: credentials.password!,
mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource);
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
await wallet.save();
await wallet.init();
return wallet;

View file

@ -21,10 +21,10 @@ packages:
dependency: transitive
description:
name: args
sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.4.0"
asn1lib:
dependency: transitive
description:
@ -111,10 +111,10 @@ packages:
dependency: transitive
description:
name: build_daemon
sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf"
sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.1"
build_resolvers:
dependency: "direct dev"
description:
@ -151,10 +151,19 @@ packages:
dependency: transitive
description:
name: built_value
sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0"
url: "https://pub.dev"
source: hosted
version: "8.4.3"
version: "8.4.4"
cake_backup:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
url: "https://github.com/cake-tech/cake_backup.git"
source: git
version: "1.0.0+1"
characters:
dependency: transitive
description:
@ -215,10 +224,18 @@ packages:
dependency: "direct main"
description:
name: cryptography
sha256: e0e37f79665cd5c86e8897f9abe1accfe813c0cc5299dab22256e22fddc1fef8
sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35
url: "https://pub.dev"
source: hosted
version: "2.0.5"
version: "2.5.0"
cupertino_icons:
dependency: transitive
description:
name: cupertino_icons
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
url: "https://pub.dev"
source: hosted
version: "1.0.5"
cw_core:
dependency: "direct main"
description:
@ -270,10 +287,10 @@ packages:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
sha256: "04be3e934c52e082558cc9ee21f42f5c1cd7a1262f4c63cd0357c08d5bba81ec"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.0.1"
flutter:
dependency: "direct main"
description: flutter
@ -440,10 +457,10 @@ packages:
dependency: "direct main"
description:
name: mobx
sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a
sha256: "6738620307a424d2c9ad8b873f4dce391c44e9135eb4e75668ac8202fec7a9b8"
url: "https://pub.dev"
source: hosted
version: "2.1.3+1"
version: "2.1.4"
mobx_codegen:
dependency: "direct dev"
description:
@ -472,50 +489,50 @@ packages:
dependency: "direct main"
description:
name: path_provider
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95
sha256: "04890b994ee89bfa80bf3080bfec40d5a92c5c7a785ebb02c13084a099d2b6f9"
url: "https://pub.dev"
source: hosted
version: "2.0.12"
version: "2.0.13"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
sha256: "019f18c9c10ae370b08dce1f3e3b73bc9f58e7f087bb5e921f06529438ac0ae7"
url: "https://pub.dev"
source: hosted
version: "2.0.22"
version: "2.0.24"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74"
sha256: "026b97a6c29da75181a37aae2eba9227f5fe13cb2838c6b975ce209328b8ab4e"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.3"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379
sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1"
url: "https://pub.dev"
source: hosted
version: "2.1.7"
version: "2.1.10"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
url: "https://pub.dev"
source: hosted
version: "2.0.5"
version: "2.0.6"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c
sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.5"
platform:
dependency: transitive
description:
@ -528,10 +545,10 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.4"
pointycastle:
dependency: transitive
description:
@ -568,10 +585,10 @@ packages:
dependency: transitive
description:
name: pubspec_parse
sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
sha256: ec85d7d55339d85f44ec2b682a82fea340071e8978257e5a43e69f79e98ef50c
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
rxdart:
dependency: "direct main"
description:
@ -681,6 +698,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
tuple:
dependency: transitive
description:
name: tuple
sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
typed_data:
dependency: transitive
description:
@ -733,10 +758,10 @@ packages:
dependency: transitive
description:
name: xdg_directories
sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
url: "https://pub.dev"
source: hosted
version: "0.2.0+3"
version: "1.0.0"
yaml:
dependency: transitive
description:

View file

@ -27,7 +27,12 @@ dependencies:
unorm_dart: ^0.2.0
cryptography: ^2.0.5
encrypt: ^5.0.1
cake_backup:
git:
url: https://github.com/cake-tech/cake_backup.git
ref: main
version: 1.0.0
dev_dependencies:
flutter_test:
sdk: flutter

View file

@ -1,10 +1,11 @@
import 'dart:io';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
Future<String> pathForWalletDir({required String name, required WalletType type}) async {
final root = await getApplicationDocumentsDirectory();
final root = await getAppDir();
final prefix = walletTypeToString(type).toLowerCase();
final walletsDir = Directory('${root.path}/wallets');
final walletDire = Directory('${walletsDir.path}/$prefix/$name');
@ -21,7 +22,7 @@ Future<String> pathForWallet({required String name, required WalletType type}) a
.then((path) => path + '/$name');
Future<String> outdatedAndroidPathForWalletDir({required String name}) async {
final directory = await getApplicationDocumentsDirectory();
final directory = await getAppDir();
final pathDir = directory.path + '/$name';
return pathDir;

26
cw_core/lib/root_dir.dart Normal file
View file

@ -0,0 +1,26 @@
import 'dart:io';
import 'package:path_provider/path_provider.dart';
String? _rootDirPath;
void setRootDirFromEnv()
=> _rootDirPath = Platform.environment['CAKE_WALLET_DIR'];
Future<Directory> getAppDir({String appName = 'cake_wallet'}) async {
Directory dir;
if (_rootDirPath != null && _rootDirPath!.isNotEmpty) {
dir = Directory.fromUri(Uri.file(_rootDirPath!));
dir.create(recursive: true);
} else {
dir = await getApplicationDocumentsDirectory();
if (Platform.isLinux) {
final appDirPath = '${dir.path}/$appName';
dir = Directory.fromUri(Uri.file(appDirPath));
await dir.create(recursive: true);
}
}
return dir;
}

View file

@ -1,11 +1,18 @@
import 'dart:typed_data';
import 'dart:io';
import 'dart:math';
import 'package:flutter/services.dart';
const utils = const MethodChannel('com.cake_wallet/native_utils');
Future<Uint8List> secRandom(int count) async {
try {
if (Platform.isLinux) {
// Used method to get securely generated random bytes from cake backups
const byteSize = 256;
final rng = Random.secure();
return Uint8List.fromList(List<int>.generate(count, (_) => rng.nextInt(byteSize)));
}
return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ?? Uint8List.fromList([]);
} on PlatformException catch (_) {
return Uint8List.fromList([]);

View file

@ -78,6 +78,8 @@ abstract class WalletBase<
Future<void> changePassword(String password);
String get password;
Future<void>? updateBalance();
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => null;

View file

@ -5,218 +5,191 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: "4897882604d919befd350648c7f91926a9d5de99e67b455bf0917cc2362f4bb8"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "47.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: "690e335554a8385bc9d787117d9eb52c0c03ee207a607e593de3c9d71b1cfe80"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
args:
dependency: transitive
description:
name: args
sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.2"
version: "2.4.0"
asn1lib:
dependency: transitive
description:
name: asn1lib
sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.11.0"
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.0"
build:
dependency: transitive
description:
name: build
sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
build_config:
dependency: transitive
description:
name: build_config
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
build_daemon:
dependency: transitive
description:
name: build_daemon
sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
version: "3.1.1"
build_resolvers:
dependency: "direct dev"
description:
name: build_resolvers
sha256: "687cf90a3951affac1bd5f9ecb5e3e90b60487f3d9cdc359bb310f8876bb02a6"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.10"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.3"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "7.2.7"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "8.4.3"
version: "8.4.4"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "4.4.0"
collection:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.17.1"
version: "1.16.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.4"
encrypt:
dependency: "direct main"
description:
name: encrypt
sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.1"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
file:
dependency: "direct main"
description:
name: file
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.0.1"
flutter:
dependency: "direct main"
description: flutter
@ -226,8 +199,7 @@ packages:
dependency: "direct main"
description:
name: flutter_mobx
sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6+5"
flutter_test:
@ -239,288 +211,252 @@ packages:
dependency: transitive
description:
name: frontend_server_client
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.0"
glob:
dependency: transitive
description:
name: glob
sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
graphs:
dependency: transitive
description:
name: graphs
sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
hive:
dependency: transitive
description:
name: hive
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.3"
hive_generator:
dependency: "direct dev"
description:
name: hive_generator
sha256: "81fd20125cb2ce8fd23623d7744ffbaf653aae93706c9bd3bf7019ea0ace3938"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
http:
dependency: "direct main"
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.2"
intl:
dependency: "direct main"
description:
name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "0.18.1"
io:
dependency: transitive
description:
name: io
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
js:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.7"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "4.8.0"
logging:
dependency: transitive
description:
name: logging
sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
matcher:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.15"
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.1"
mime:
dependency: transitive
description:
name: mime
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
mobx:
dependency: "direct main"
description:
name: mobx
sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3+1"
version: "2.1.4"
mobx_codegen:
dependency: "direct dev"
description:
name: mobx_codegen
sha256: "86122e410d8ea24dda0c69adb5c2a6ccadd5ce02ad46e144764e0d0184a06181"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
package_config:
dependency: transitive
description:
name: package_config
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.3"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.12"
version: "2.0.13"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.22"
version: "2.0.24"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.3"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.7"
version: "2.1.10"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.0.6"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.1.5"
platform:
dependency: transitive
description:
name: platform
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.1.4"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.2"
pool:
dependency: transitive
description:
name: pool
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
process:
dependency: transitive
description:
name: process
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
version: "1.2.2"
shelf:
dependency: transitive
description:
name: shelf
sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
sky_engine:
@ -532,136 +468,119 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: "2d79738b6bbf38a43920e2b8d189e9a3ce6cc201f4b8fc76be5e4fe377b1c38d"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.6"
source_helper:
dependency: transitive
description:
name: source_helper
sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.3"
source_span:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.1"
version: "1.9.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.0"
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.1"
version: "0.4.12"
timing:
dependency: transitive
description:
name: timing
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
version: "2.1.2"
watcher:
dependency: transitive
description:
name: watcher
sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
win32:
dependency: transitive
description:
name: win32
sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+3"
version: "1.0.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
url: "https://pub.dev"
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
sdks:

View file

@ -18,6 +18,9 @@ migration:
- platform: macos
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
- platform: linux
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
# User provided section

1
cw_monero/example/linux/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
flutter/ephemeral

View file

@ -0,0 +1,138 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "cw_monero_example")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "com.cakewallet.cw_monero")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0063 NEW)
# Load bundled libraries from the lib/ directory relative to the binary.
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Root filesystem for cross-building.
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
# Define build configuration options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
# Flutter library and tool build rules.
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endforeach(bundled_library)
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
# Install the AOT library on non-Debug builds only.
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()

View file

@ -0,0 +1,88 @@
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required(VERSION 3.10)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
# which isn't available in 3.10.
function(list_prepend LIST_NAME PREFIX)
set(NEW_LIST "")
foreach(element ${${LIST_NAME}})
list(APPEND NEW_LIST "${PREFIX}${element}")
endforeach(element)
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# === Flutter Library ===
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"fl_basic_message_channel.h"
"fl_binary_codec.h"
"fl_binary_messenger.h"
"fl_dart_project.h"
"fl_engine.h"
"fl_json_message_codec.h"
"fl_json_method_codec.h"
"fl_message_codec.h"
"fl_method_call.h"
"fl_method_channel.h"
"fl_method_codec.h"
"fl_method_response.h"
"fl_plugin_registrar.h"
"fl_plugin_registry.h"
"fl_standard_message_codec.h"
"fl_standard_method_codec.h"
"fl_string_codec.h"
"fl_value.h"
"fl_view.h"
"flutter_linux.h"
)
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
target_link_libraries(flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
)
add_dependencies(flutter flutter_assemble)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
)

View file

@ -0,0 +1,15 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
#include <cw_monero/cw_monero_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) cw_monero_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "CwMoneroPlugin");
cw_monero_plugin_register_with_registrar(cw_monero_registrar);
}

View file

@ -0,0 +1,15 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter_linux/flutter_linux.h>
// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_

View file

@ -0,0 +1,24 @@
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
cw_monero
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)

View file

@ -0,0 +1,6 @@
#include "my_application.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}

View file

@ -0,0 +1,104 @@
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
// Use a header bar when running in GNOME as this is the common style used
// by applications and is the setup most users will be using (e.g. Ubuntu
// desktop).
// If running on X and not using GNOME then just use a traditional title bar
// in case the window manager does more exotic layout, e.g. tiling.
// If running on Wayland assume the header bar will work (may need changing
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen* screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "cw_monero_example");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(window, "cw_monero_example");
}
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
}
// Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
MyApplication* self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr;
if (!g_application_register(application, nullptr, &error)) {
g_warning("Failed to register: %s", error->message);
*exit_status = 1;
return TRUE;
}
g_application_activate(application);
*exit_status = 0;
return TRUE;
}
// Implements GObject::dispose.
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
}
static void my_application_init(MyApplication* self) {}
MyApplication* my_application_new() {
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID,
"flags", G_APPLICATION_NON_UNIQUE,
nullptr));
}

View file

@ -0,0 +1,18 @@
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
GtkApplication)
/**
* my_application_new:
*
* Creates a new Flutter-based application.
*
* Returns: a new #MyApplication.
*/
MyApplication* my_application_new();
#endif // FLUTTER_MY_APPLICATION_H_

View file

@ -13,16 +13,22 @@
// Fix for randomx on ios
void __clear_cache(void* start, void* end) { }
#include "../External/ios/include/wallet2_api.h"
#elif __linux__
#include "../External/linux/include/wallet2_api.h"
#include <string.h>
#else
#include "../External/android/include/wallet2_api.h"
#endif
#if defined(__GNUC__)
#define FUNCTION_VISABILITY_ATTRIBUTE __attribute__((visibility("default"))) __attribute__((used))
#endif
using namespace std::chrono_literals;
#ifdef __cplusplus
extern "C"
{
#endif
const uint64_t MONERO_BLOCK_SIZE = 1000;
struct Utf8Box
{
@ -151,7 +157,8 @@ extern "C"
fee = transaction->fee();
blockHeight = transaction->blockHeight();
subaddrAccount = transaction->subaddrAccount();
std::set<uint32_t>::iterator it = transaction->subaddrIndex().begin();
std::set<uint32_t> subIndex = transaction->subaddrIndex();
std::set<uint32_t>::iterator it = subIndex.begin();
subaddrIndex = *it;
confirmations = transaction->confirmations();
datetime = static_cast<int64_t>(transaction->timestamp());
@ -250,6 +257,7 @@ extern "C"
std::mutex store_lock;
bool is_storing = false;
FUNCTION_VISABILITY_ATTRIBUTE
void change_current_wallet(Monero::Wallet *wallet)
{
m_wallet = wallet;
@ -300,6 +308,7 @@ extern "C"
return m_wallet;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool create_wallet(char *path, char *password, char *language, int32_t networkType, char *error)
{
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
@ -322,6 +331,7 @@ extern "C"
return true;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool restore_wallet_from_seed(char *path, char *password, char *seed, int32_t networkType, uint64_t restoreHeight, char *error)
{
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
@ -347,6 +357,7 @@ extern "C"
return true;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool restore_wallet_from_keys(char *path, char *password, char *language, char *address, char *viewKey, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error)
{
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
@ -375,6 +386,7 @@ extern "C"
return true;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool load_wallet(char *path, char *password, int32_t nettype)
{
nice(19);
@ -390,78 +402,91 @@ extern "C"
return !(status != Monero::Wallet::Status_Ok || !errorString.empty());
}
FUNCTION_VISABILITY_ATTRIBUTE
char *error_string() {
return strdup(get_current_wallet()->errorString().c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
bool is_wallet_exist(char *path)
{
return Monero::WalletManagerFactory::getWalletManager()->walletExists(std::string(path));
}
FUNCTION_VISABILITY_ATTRIBUTE
void close_current_wallet()
{
Monero::WalletManagerFactory::getWalletManager()->closeWallet(get_current_wallet());
change_current_wallet(nullptr);
}
FUNCTION_VISABILITY_ATTRIBUTE
char *get_filename()
{
return strdup(get_current_wallet()->filename().c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
char *secret_view_key()
{
return strdup(get_current_wallet()->secretViewKey().c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
char *public_view_key()
{
return strdup(get_current_wallet()->publicViewKey().c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
char *secret_spend_key()
{
return strdup(get_current_wallet()->secretSpendKey().c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
char *public_spend_key()
{
return strdup(get_current_wallet()->publicSpendKey().c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
char *get_address(uint32_t account_index, uint32_t address_index)
{
return strdup(get_current_wallet()->address(account_index, address_index).c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
const char *seed()
{
return strdup(get_current_wallet()->seed().c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
uint64_t get_full_balance(uint32_t account_index)
{
return get_current_wallet()->balance(account_index);
}
FUNCTION_VISABILITY_ATTRIBUTE
uint64_t get_unlocked_balance(uint32_t account_index)
{
return get_current_wallet()->unlockedBalance(account_index);
}
FUNCTION_VISABILITY_ATTRIBUTE
uint64_t get_current_height()
{
return get_current_wallet()->blockChainHeight();
}
FUNCTION_VISABILITY_ATTRIBUTE
uint64_t get_node_height()
{
return get_current_wallet()->daemonBlockChainHeight();
}
FUNCTION_VISABILITY_ATTRIBUTE
bool connect_to_node(char *error)
{
nice(19);
@ -475,6 +500,7 @@ extern "C"
return is_connected;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *socksProxyAddress, char *error)
{
nice(19);
@ -511,27 +537,32 @@ extern "C"
return inited;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool is_connected()
{
return get_current_wallet()->connected();
}
FUNCTION_VISABILITY_ATTRIBUTE
void start_refresh()
{
get_current_wallet()->refreshAsync();
get_current_wallet()->startRefresh();
}
FUNCTION_VISABILITY_ATTRIBUTE
void set_refresh_from_block_height(uint64_t height)
{
get_current_wallet()->setRefreshFromBlockHeight(height);
}
FUNCTION_VISABILITY_ATTRIBUTE
void set_recovering_from_seed(bool is_recovery)
{
get_current_wallet()->setRecoveringFromSeed(is_recovery);
}
FUNCTION_VISABILITY_ATTRIBUTE
void store(char *path)
{
store_lock.lock();
@ -545,6 +576,7 @@ extern "C"
store_lock.unlock();
}
FUNCTION_VISABILITY_ATTRIBUTE
bool set_password(char *password, Utf8Box &error) {
bool is_changed = get_current_wallet()->setPassword(std::string(password));
@ -555,6 +587,7 @@ extern "C"
return is_changed;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool transaction_create(char *address, char *payment_id, char *amount,
uint8_t priority_raw, uint32_t subaddr_account,
char **preferred_inputs, uint32_t preferred_inputs_size,
@ -604,6 +637,7 @@ extern "C"
return true;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size,
uint8_t priority_raw, uint32_t subaddr_account,
char **preferred_inputs, uint32_t preferred_inputs_size,
@ -655,6 +689,7 @@ extern "C"
return true;
}
FUNCTION_VISABILITY_ATTRIBUTE
bool transaction_commit(PendingTransactionRaw *transaction, Utf8Box &error)
{
bool committed = transaction->transaction->commit();
@ -669,6 +704,7 @@ extern "C"
return committed;
}
FUNCTION_VISABILITY_ATTRIBUTE
uint64_t get_node_height_or_update(uint64_t base_eight)
{
if (m_cached_syncing_blockchain_height < base_eight) {
@ -678,6 +714,7 @@ extern "C"
return m_cached_syncing_blockchain_height;
}
FUNCTION_VISABILITY_ATTRIBUTE
uint64_t get_syncing_height()
{
if (m_listener == nullptr) {
@ -698,6 +735,7 @@ extern "C"
return height;
}
FUNCTION_VISABILITY_ATTRIBUTE
uint64_t is_needed_to_refresh()
{
if (m_listener == nullptr) {
@ -713,6 +751,7 @@ extern "C"
return should_refresh;
}
FUNCTION_VISABILITY_ATTRIBUTE
uint8_t is_new_transaction_exist()
{
if (m_listener == nullptr) {
@ -729,6 +768,7 @@ extern "C"
return is_new_transaction_exist;
}
FUNCTION_VISABILITY_ATTRIBUTE
void set_listener()
{
m_last_known_wallet_height = 0;
@ -742,6 +782,7 @@ extern "C"
get_current_wallet()->setListener(m_listener);
}
FUNCTION_VISABILITY_ATTRIBUTE
int64_t *subaddrress_get_all()
{
std::vector<Monero::SubaddressRow *> _subaddresses = m_subaddress->getAll();
@ -758,33 +799,39 @@ extern "C"
return subaddresses;
}
FUNCTION_VISABILITY_ATTRIBUTE
int32_t subaddrress_size()
{
std::vector<Monero::SubaddressRow *> _subaddresses = m_subaddress->getAll();
return _subaddresses.size();
}
FUNCTION_VISABILITY_ATTRIBUTE
void subaddress_add_row(uint32_t accountIndex, char *label)
{
m_subaddress->addRow(accountIndex, std::string(label));
}
FUNCTION_VISABILITY_ATTRIBUTE
void subaddress_set_label(uint32_t accountIndex, uint32_t addressIndex, char *label)
{
m_subaddress->setLabel(accountIndex, addressIndex, std::string(label));
}
FUNCTION_VISABILITY_ATTRIBUTE
void subaddress_refresh(uint32_t accountIndex)
{
m_subaddress->refresh(accountIndex);
}
FUNCTION_VISABILITY_ATTRIBUTE
int32_t account_size()
{
std::vector<Monero::SubaddressAccountRow *> _accocunts = m_account->getAll();
return _accocunts.size();
}
FUNCTION_VISABILITY_ATTRIBUTE
int64_t *account_get_all()
{
std::vector<Monero::SubaddressAccountRow *> _accocunts = m_account->getAll();
@ -801,21 +848,25 @@ extern "C"
return accocunts;
}
FUNCTION_VISABILITY_ATTRIBUTE
void account_add_row(char *label)
{
m_account->addRow(std::string(label));
}
FUNCTION_VISABILITY_ATTRIBUTE
void account_set_label_row(uint32_t account_index, char *label)
{
m_account->setLabel(account_index, label);
}
FUNCTION_VISABILITY_ATTRIBUTE
void account_refresh()
{
m_account->refresh();
}
FUNCTION_VISABILITY_ATTRIBUTE
int64_t *transactions_get_all()
{
std::vector<Monero::TransactionInfo *> transactions = m_transaction_history->getAll();
@ -832,16 +883,19 @@ extern "C"
return transactionAddresses;
}
FUNCTION_VISABILITY_ATTRIBUTE
void transactions_refresh()
{
m_transaction_history->refresh();
}
FUNCTION_VISABILITY_ATTRIBUTE
int64_t transactions_count()
{
return m_transaction_history->count();
}
FUNCTION_VISABILITY_ATTRIBUTE
int LedgerExchange(
unsigned char *command,
unsigned int cmd_len,
@ -851,37 +905,44 @@ extern "C"
return -1;
}
FUNCTION_VISABILITY_ATTRIBUTE
int LedgerFind(char *buffer, size_t len)
{
return -1;
}
FUNCTION_VISABILITY_ATTRIBUTE
void on_startup()
{
Monero::Utils::onStartup();
Monero::WalletManagerFactory::setLogLevel(0);
}
FUNCTION_VISABILITY_ATTRIBUTE
void rescan_blockchain()
{
m_wallet->rescanBlockchainAsync();
}
FUNCTION_VISABILITY_ATTRIBUTE
char * get_tx_key(char * txId)
{
return strdup(m_wallet->getTxKey(std::string(txId)).c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
char *get_subaddress_label(uint32_t accountIndex, uint32_t addressIndex)
{
return strdup(get_current_wallet()->getSubaddressLabel(accountIndex, addressIndex).c_str());
}
FUNCTION_VISABILITY_ATTRIBUTE
void set_trusted_daemon(bool arg)
{
m_wallet->setTrustedDaemon(arg);
}
FUNCTION_VISABILITY_ATTRIBUTE
bool trusted_daemon()
{
return m_wallet->trustedDaemon();

View file

@ -3,4 +3,4 @@ import 'dart:io';
final DynamicLibrary moneroApi = Platform.isAndroid
? DynamicLibrary.open("libcw_monero.so")
: DynamicLibrary.open("cw_monero.framework/cw_monero");
: DynamicLibrary.process();

View file

@ -39,8 +39,10 @@ class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
MoneroTransactionHistory, MoneroTransactionInfo> with Store {
MoneroWalletBase({required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo})
MoneroWalletBase({
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required String password})
: balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({
CryptoCurrency.xmr: MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
@ -49,6 +51,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
_isTransactionUpdating = false,
_hasSyncAfterStartup = false,
isEnabledAutoGenerateSubaddress = false,
_password = password,
syncStatus = NotConnectedSyncStatus(),
unspentCoins = [],
this.unspentCoinsInfo = unspentCoinsInfo,
@ -96,6 +99,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
@override
String get seed => monero_wallet.getSeed();
@override
String get password => _password;
@override
MoneroWalletKeys get keys => MoneroWalletKeys(
privateSpendKey: monero_wallet.getSecretSpendKey(),
@ -109,6 +115,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
bool _hasSyncAfterStartup;
Timer? _autoSaveTimer;
List<MoneroUnspent> unspentCoins;
String _password;
Future<void> init() async {
await walletAddresses.init();
@ -370,6 +377,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
@override
Future<void> changePassword(String password) async {
monero_wallet.setPasswordSync(password);
_password = password;
}
Future<int> getNodeHeight() async => monero_wallet.getNodeHeight();

View file

@ -73,7 +73,9 @@ class MoneroWalletService extends WalletService<
password: credentials.password!,
language: credentials.language);
final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
password: credentials.password!);
await wallet.init();
return wallet;
@ -109,7 +111,10 @@ class MoneroWalletService extends WalletService<
.openWalletAsync({'path': path, 'password': password});
final walletInfo = walletInfoSource.values.firstWhere(
(info) => info.id == WalletBase.idFor(name, getType()));
final wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
final wallet = MoneroWallet(
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
password: password);
final isValid = wallet.walletAddresses.validate();
if (!isValid) {
@ -192,7 +197,9 @@ class MoneroWalletService extends WalletService<
viewKey: credentials.viewKey,
spendKey: credentials.spendKey);
final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
walletInfo: credentials.walletInfo
unspentCoinsInfo: unspentCoinsInfoSource,
password: credentials.password!);
await wallet.init();
return wallet;
@ -214,7 +221,9 @@ class MoneroWalletService extends WalletService<
seed: credentials.mnemonic,
restoreHeight: credentials.height!);
final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
password: credentials.password!);
await wallet.init();
return wallet;

View file

@ -0,0 +1,270 @@
# The Flutter tooling requires that developers have CMake 3.10 or later
# installed. You should not increase this version, as doing so will cause
# the plugin to fail to compile for some customers of the plugin.
cmake_minimum_required(VERSION 3.10)
# Project-level configuration.
set(PROJECT_NAME "cw_monero")
project(${PROJECT_NAME} LANGUAGES CXX)
# This value is used when generating builds using this plugin, so it must
# not be changed.
set(PLUGIN_NAME "cw_monero_plugin")
# Define the plugin library target. Its name must not be changed (see comment
# on PLUGIN_NAME above).
#
# Any new source files that you add to the plugin should be added here.
add_library(${PLUGIN_NAME} SHARED
"cw_monero_plugin.cc"
"../ios/Classes/monero_api.cpp"
)
# Apply a standard set of build settings that are configured in the
# application-level CMakeLists.txt. This can be removed for plugins that want
# full control over build settings.
apply_standard_settings(${PLUGIN_NAME})
# Symbols are hidden by default to reduce the chance of accidental conflicts
# between plugins. This should not be removed; any symbols that should be
# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro.
set_target_properties(${PLUGIN_NAME} PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
# Source include directories and library dependencies. Add any plugin-specific
# dependencies here.
target_include_directories(${PLUGIN_NAME} INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter)
target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)
target_link_libraries(${PLUGIN_NAME} PUBLIC cw_monero)
# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
# external build triggered from this build file.
set(cw_monero_bundled_libraries
""
PARENT_SCOPE
)
add_library( cw_monero
STATIC
../ios/Classes/monero_api.cpp)
set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../cw_shared_external/ios/External/linux)
############
# libsodium
############
add_library(sodium STATIC IMPORTED)
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libsodium.a)
############
# OpenSSL
############
add_library(crypto STATIC IMPORTED)
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libcrypto.a)
add_library(ssl STATIC IMPORTED)
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libssl.a)
############
# Boost
############
add_library(boost_chrono STATIC IMPORTED)
set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_chrono.a)
add_library(boost_date_time STATIC IMPORTED)
set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_date_time.a)
add_library(boost_filesystem STATIC IMPORTED)
set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_filesystem.a)
add_library(boost_program_options STATIC IMPORTED)
set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_program_options.a)
add_library(boost_regex STATIC IMPORTED)
set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_regex.a)
add_library(boost_serialization STATIC IMPORTED)
set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_serialization.a)
add_library(boost_system STATIC IMPORTED)
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_system.a)
add_library(boost_thread STATIC IMPORTED)
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_thread.a)
add_library(boost_wserialization STATIC IMPORTED)
set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libboost_wserialization.a)
#############
# Monero
#############
add_library(wallet STATIC IMPORTED)
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libwallet.a)
add_library(wallet_api STATIC IMPORTED)
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libwallet_api.a)
add_library(cryptonote_core STATIC IMPORTED)
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libcryptonote_core.a)
add_library(cryptonote_basic STATIC IMPORTED)
set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libcryptonote_basic.a)
add_library(cryptonote_format_utils_basic STATIC IMPORTED)
set_target_properties(cryptonote_format_utils_basic PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libcryptonote_format_utils_basic.a)
add_library(mnemonics STATIC IMPORTED)
set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libmnemonics.a)
add_library(common STATIC IMPORTED)
set_target_properties(common PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libcommon.a)
add_library(cncrypto STATIC IMPORTED)
set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libcncrypto.a)
add_library(ringct STATIC IMPORTED)
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libringct.a)
add_library(ringct_basic STATIC IMPORTED)
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libringct_basic.a)
add_library(blockchain_db STATIC IMPORTED)
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libblockchain_db.a)
add_library(lmdb STATIC IMPORTED)
set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/liblmdb.a)
add_library(easylogging STATIC IMPORTED)
set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libeasylogging.a)
add_library(epee STATIC IMPORTED)
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libepee.a)
add_library(blocks STATIC IMPORTED)
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libblocks.a)
add_library(checkpoints STATIC IMPORTED)
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libcheckpoints.a)
add_library(device STATIC IMPORTED)
set_target_properties(device PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libdevice.a)
add_library(device_trezor STATIC IMPORTED)
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libdevice_trezor.a)
add_library(multisig STATIC IMPORTED)
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libmultisig.a)
add_library(version STATIC IMPORTED)
set_target_properties(version PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libversion.a)
add_library(net STATIC IMPORTED)
set_target_properties(net PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libnet.a)
add_library(hardforks STATIC IMPORTED)
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libhardforks.a)
add_library(randomx STATIC IMPORTED)
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/librandomx.a)
add_library(rpc_base STATIC IMPORTED)
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/librpc_base.a)
add_library(wallet-crypto STATIC IMPORTED)
set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/monero/libwallet-crypto.a)
add_library(unbound STATIC IMPORTED)
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/lib/libunbound.a)
include_directories( ${EXTERNAL_LIBS_DIR}/include )
target_link_libraries( cw_monero
wallet_api
wallet
cryptonote_core
cryptonote_basic
cryptonote_format_utils_basic
mnemonics
ringct
ringct_basic
net
common
cncrypto
blockchain_db
lmdb
easylogging
unbound
epee
blocks
checkpoints
device
device_trezor
multisig
version
randomx
hardforks
rpc_base
wallet-crypto
boost_chrono
boost_date_time
boost_filesystem
boost_program_options
boost_regex
boost_serialization
boost_system
boost_thread
boost_wserialization
ssl
crypto
sodium
)

View file

@ -0,0 +1,70 @@
#include "include/cw_monero/cw_monero_plugin.h"
#include <flutter_linux/flutter_linux.h>
#include <gtk/gtk.h>
#include <sys/utsname.h>
#include <cstring>
#define CW_MONERO_PLUGIN(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), cw_monero_plugin_get_type(), \
CwMoneroPlugin))
struct _CwMoneroPlugin {
GObject parent_instance;
};
G_DEFINE_TYPE(CwMoneroPlugin, cw_monero_plugin, g_object_get_type())
// Called when a method call is received from Flutter.
static void cw_monero_plugin_handle_method_call(
CwMoneroPlugin* self,
FlMethodCall* method_call) {
g_autoptr(FlMethodResponse) response = nullptr;
const gchar* method = fl_method_call_get_name(method_call);
if (strcmp(method, "getPlatformVersion") == 0) {
struct utsname uname_data = {};
uname(&uname_data);
g_autofree gchar *version = g_strdup_printf("Linux %s", uname_data.version);
g_autoptr(FlValue) result = fl_value_new_string(version);
response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
} else {
response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
}
fl_method_call_respond(method_call, response, nullptr);
}
static void cw_monero_plugin_dispose(GObject* object) {
G_OBJECT_CLASS(cw_monero_plugin_parent_class)->dispose(object);
}
static void cw_monero_plugin_class_init(CwMoneroPluginClass* klass) {
G_OBJECT_CLASS(klass)->dispose = cw_monero_plugin_dispose;
}
static void cw_monero_plugin_init(CwMoneroPlugin* self) {}
static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call,
gpointer user_data) {
CwMoneroPlugin* plugin = CW_MONERO_PLUGIN(user_data);
cw_monero_plugin_handle_method_call(plugin, method_call);
}
void cw_monero_plugin_register_with_registrar(FlPluginRegistrar* registrar) {
CwMoneroPlugin* plugin = CW_MONERO_PLUGIN(
g_object_new(cw_monero_plugin_get_type(), nullptr));
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
g_autoptr(FlMethodChannel) channel =
fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar),
"cw_monero",
FL_METHOD_CODEC(codec));
fl_method_channel_set_method_call_handler(channel, method_call_cb,
g_object_ref(plugin),
g_object_unref);
g_object_unref(plugin);
}

View file

@ -0,0 +1,26 @@
#ifndef FLUTTER_PLUGIN_CW_MONERO_PLUGIN_H_
#define FLUTTER_PLUGIN_CW_MONERO_PLUGIN_H_
#include <flutter_linux/flutter_linux.h>
G_BEGIN_DECLS
#ifdef FLUTTER_PLUGIN_IMPL
#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define FLUTTER_PLUGIN_EXPORT
#endif
typedef struct _CwMoneroPlugin CwMoneroPlugin;
typedef struct {
GObjectClass parent_class;
} CwMoneroPluginClass;
FLUTTER_PLUGIN_EXPORT GType cw_monero_plugin_get_type();
FLUTTER_PLUGIN_EXPORT void cw_monero_plugin_register_with_registrar(
FlPluginRegistrar* registrar);
G_END_DECLS
#endif // FLUTTER_PLUGIN_CW_MONERO_PLUGIN_H_

View file

@ -22,8 +22,6 @@ using namespace std::chrono_literals;
extern "C"
{
#endif
const uint64_t MONERO_BLOCK_SIZE = 1000;
struct Utf8Box
{
char *value;
@ -151,7 +149,8 @@ extern "C"
fee = transaction->fee();
blockHeight = transaction->blockHeight();
subaddrAccount = transaction->subaddrAccount();
std::set<uint32_t>::iterator it = transaction->subaddrIndex().begin();
std::set<uint32_t> subIndex = transaction->subaddrIndex();
std::set<uint32_t>::iterator it = subIndex.begin();
subaddrIndex = *it;
confirmations = transaction->confirmations();
datetime = static_cast<int64_t>(transaction->timestamp());

View file

@ -46,9 +46,10 @@ flutter:
pluginClass: CwMoneroPlugin
ios:
pluginClass: CwMoneroPlugin
macos:
pluginClass: CwMoneroPlugin
linux:
pluginClass: CwMoneroPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:

View file

@ -44,7 +44,6 @@ post_install do |installer|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',

View file

@ -4,10 +4,10 @@ PODS:
- MTBBarcodeScanner
- SwiftProtobuf
- BigInt (5.2.0)
- connectivity_plus (0.0.1):
- connectivity (0.0.1):
- Flutter
- ReachabilitySwift
- CryptoSwift (1.7.1)
- Reachability
- CryptoSwift (1.6.0)
- cw_haven (0.0.1):
- cw_haven/Boost (= 0.0.1)
- cw_haven/Haven (= 0.0.1)
@ -130,10 +130,10 @@ PODS:
- Flutter
- platform_device_id (0.0.1):
- Flutter
- ReachabilitySwift (5.0.0)
- SDWebImage (5.16.0):
- SDWebImage/Core (= 5.16.0)
- SDWebImage/Core (5.16.0)
- Reachability (3.2)
- SDWebImage (5.15.5):
- SDWebImage/Core (= 5.15.5)
- SDWebImage/Core (5.15.5)
- sensitive_clipboard (0.0.1):
- Flutter
- share_plus (0.0.1):
@ -141,7 +141,7 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftProtobuf (1.22.0)
- SwiftProtobuf (1.21.0)
- SwiftyGif (5.4.4)
- uni_links (0.0.1):
- Flutter
@ -157,7 +157,7 @@ PODS:
DEPENDENCIES:
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- connectivity (from `.symlinks/plugins/connectivity/ios`)
- CryptoSwift
- cw_haven (from `.symlinks/plugins/cw_haven/ios`)
- cw_monero (from `.symlinks/plugins/cw_monero/ios`)
@ -194,7 +194,7 @@ SPEC REPOS:
- DKPhotoGallery
- MTBBarcodeScanner
- OrderedSet
- ReachabilitySwift
- Reachability
- SDWebImage
- SwiftProtobuf
- SwiftyGif
@ -203,8 +203,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
barcode_scan2:
:path: ".symlinks/plugins/barcode_scan2/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
connectivity:
:path: ".symlinks/plugins/connectivity/ios"
cw_haven:
:path: ".symlinks/plugins/cw_haven/ios"
cw_monero:
@ -259,8 +259,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
BigInt: f668a80089607f521586bbe29513d708491ef2f7
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
CryptoSwift: d3d18dc357932f7e6d580689e065cf1f176007c1
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
CryptoSwift: 562f8eceb40e80796fffc668b0cad9313284cfa6
cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d
cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
@ -283,12 +283,12 @@ SPEC CHECKSUMS:
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
SDWebImage: 2aea163b50bfcb569a2726b6a754c54a4506fcf6
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989
SwiftProtobuf: afced68785854575756db965e9da52bbf3dc45e7
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
@ -296,6 +296,6 @@ SPEC CHECKSUMS:
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
PODFILE CHECKSUM: 09df1114e7c360f55770d35a79356bf5446e0100
PODFILE CHECKSUM: ae71bdf0eb731a1ffc399c122f6aa4dea0cb5f6f
COCOAPODS: 1.12.1

View file

@ -10,8 +10,8 @@
0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44A7192518EF8000B570ED /* decrypt.swift */; };
0C9D68C9264854B60011B691 /* secRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9D68C8264854B60011B691 /* secRandom.swift */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
20ED0868E1BD7E12278C0CB3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C663361C56EBB242598F609 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
@ -23,13 +23,13 @@
0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = "<group>"; };
0C9986A3251A932F00D566FD /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0C9D68C8264854B60011B691 /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secRandom.swift; sourceTree = "<group>"; };
11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
20F67A1B2C2FCB2A3BB048C1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3C663361C56EBB242598F609 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
501EA9286675DC8636978EA4 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
5AFFEBFC279AD49C00F906A4 /* wakeLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = wakeLock.swift; sourceTree = "<group>"; };
61CAA8652B54F23356F7592A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@ -40,7 +40,7 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -48,7 +48,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4DFD1BB54A3A50573E19A583 /* Pods_Runner.framework in Frameworks */,
20ED0868E1BD7E12278C0CB3 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -59,7 +59,7 @@
isa = PBXGroup;
children = (
0C9986A3251A932F00D566FD /* CryptoSwift.framework */,
3C663361C56EBB242598F609 /* Pods_Runner.framework */,
B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -77,9 +77,9 @@
84389F1A05D5860790D82820 /* Pods */ = {
isa = PBXGroup;
children = (
11F9FC13F9EE2A705B213FA9 /* Pods-Runner.debug.xcconfig */,
1F083F2041D1F553F2AF8B62 /* Pods-Runner.release.xcconfig */,
AD0937B0140D5A4C24E73BEA /* Pods-Runner.profile.xcconfig */,
20F67A1B2C2FCB2A3BB048C1 /* Pods-Runner.debug.xcconfig */,
501EA9286675DC8636978EA4 /* Pods-Runner.release.xcconfig */,
61CAA8652B54F23356F7592A /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -138,13 +138,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */,
0843B0813AFBAF53935AD24E /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */,
DD8DB3179CA4E511F9954A6F /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -203,21 +203,26 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
32D0076A9969C0C38D68AF62 /* [CP] Embed Pods Frameworks */ = {
0843B0813AFBAF53935AD24E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
@ -250,26 +255,21 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
B91154210ADCED81FBF06A85 /* [CP] Check Pods Manifest.lock */ = {
DD8DB3179CA4E511F9954A6F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -390,7 +390,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic";
};
@ -537,7 +537,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic";
};
@ -574,7 +574,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64;
VERSIONING_SYSTEM = "apple-generic";
};

View file

@ -1,25 +1,21 @@
{
"images" : [
{
"filename" : "Icon-App-40x40@1x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "Icon-App-20x20@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "Icon-App-29x29@2x 1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "Icon-App-29x29@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
@ -30,7 +26,6 @@
"size" : "40x40"
},
{
"filename" : "Icon-App-40x40@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
@ -48,31 +43,26 @@
"size" : "60x60"
},
{
"filename" : "Icon-App-20x20@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "Icon-App-20x20@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "Icon-App-29x29@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "Icon-App-29x29@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "Icon-App-40x40@1x 1.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
@ -83,19 +73,16 @@
"size" : "40x40"
},
{
"filename" : "Icon-App-76x76@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "Icon-App-76x76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "Icon-App-83.5x83.5@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View file

@ -22,8 +22,9 @@ class CWBitcoin extends Bitcoin {
@override
WalletCredentials createBitcoinNewWalletCredentials({
required String name,
WalletInfo? walletInfo})
=> BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo);
WalletInfo? walletInfo,
String? password})
=> BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
@override
List<String> getWordList() => wordlist;
@ -138,12 +139,12 @@ class CWBitcoin extends Bitcoin {
await bitcoinWallet.updateUnspent();
}
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
return BitcoinWalletService(walletInfoSource, unspentCoinSource);
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
return BitcoinWalletService(walletInfoSource, unspentCoinSource, isDirect);
}
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
return LitecoinWalletService(walletInfoSource, unspentCoinSource);
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
return LitecoinWalletService(walletInfoSource, unspentCoinSource, isDirect);
}
@override

View file

@ -1,7 +1,4 @@
import 'dart:convert';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:crypto/crypto.dart';
import 'package:cake_wallet/buy/buy_exception.dart';
import 'package:http/http.dart';
@ -19,42 +16,20 @@ class MoonPaySellProvider {
MoonPaySellProvider({this.isTest = false})
: baseUrl = isTest ? _baseTestUrl : _baseProductUrl;
static const _baseTestUrl = 'sell-sandbox.moonpay.com';
static const _baseTestUrl = 'sell-staging.moonpay.com';
static const _baseProductUrl = 'sell.moonpay.com';
static String themeToMoonPayTheme(ThemeBase theme) {
switch (theme.type) {
case ThemeType.bright:
return 'light';
case ThemeType.light:
return 'light';
case ThemeType.dark:
return 'dark';
}
}
static String get _apiKey => secrets.moonPayApiKey;
static String get _secretKey => secrets.moonPaySecretKey;
final bool isTest;
final String baseUrl;
Future<Uri> requestUrl(
{required CryptoCurrency currency,
required String refundWalletAddress,
required SettingsStore settingsStore}) async {
final customParams = {
'theme': themeToMoonPayTheme(settingsStore.currentTheme),
'language': settingsStore.languageCode,
'colorCode': settingsStore.currentTheme.type == ThemeType.dark
? '#${Palette.blueCraiola.value.toRadixString(16).substring(2, 8)}'
: '#${Palette.moderateSlateBlue.value.toRadixString(16).substring(2, 8)}',
};
Future<Uri> requestUrl({required CryptoCurrency currency, required String refundWalletAddress}) async {
final originalUri = Uri.https(
baseUrl, '', <String, dynamic>{
'apiKey': _apiKey,
'defaultBaseCurrencyCode': currency.toString().toLowerCase(),
'refundWalletAddress': refundWalletAddress
}..addAll(customParams));
});
final messageBytes = utf8.encode('?${originalUri.query}');
final key = utf8.encode(_secretKey);
final hmac = Hmac(sha256, key);

View file

@ -3,7 +3,7 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
@ -31,7 +31,7 @@ class AuthService with Store {
Routes.restoreOptions,
];
final FlutterSecureStorage secureStorage;
final SecureStorage secureStorage;
final SharedPreferences sharedPreferences;
final SettingsStore settingsStore;
@ -106,7 +106,7 @@ class AuthService with Store {
}
}
Navigator.of(context).pushNamed(Routes.auth,
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
if (!isAuthenticatedSuccessfully) {
@ -140,8 +140,8 @@ class AuthService with Store {
}
}
}
});
}
}

View file

@ -1,10 +1,11 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:path_provider/path_provider.dart';
import 'package:cryptography/cryptography.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -32,7 +33,7 @@ class BackupService {
static const _v2 = 2;
final Cipher _cipher;
final FlutterSecureStorage _flutterSecureStorage;
final SecureStorage _flutterSecureStorage;
final SharedPreferences _sharedPreferences;
final Box<WalletInfo> _walletInfoSource;
final KeyService _keyService;
@ -74,7 +75,7 @@ class BackupService {
Future<Uint8List> _exportBackupV2(String password) async {
final zipEncoder = ZipFileEncoder();
final appDir = await getApplicationDocumentsDirectory();
final appDir = await getAppDir();
final now = DateTime.now();
final tmpDir = Directory('${appDir.path}/~_BACKUP_TMP');
final archivePath = '${tmpDir.path}/backup_${now.toString()}.zip';
@ -114,7 +115,7 @@ class BackupService {
}
Future<void> _importBackupV1(Uint8List data, String password, {required String nonce}) async {
final appDir = await getApplicationDocumentsDirectory();
final appDir = await getAppDir();
final decryptedData = await _decryptV1(data, password, nonce);
final zip = ZipDecoder().decodeBytes(decryptedData);
@ -137,7 +138,7 @@ class BackupService {
}
Future<void> _importBackupV2(Uint8List data, String password) async {
final appDir = await getApplicationDocumentsDirectory();
final appDir = await getAppDir();
final decryptedData = await _decryptV2(data, password);
final zip = ZipDecoder().decodeBytes(decryptedData);
@ -170,7 +171,7 @@ class BackupService {
}
Future<Box<WalletInfo>> _reloadHiveWalletInfoBox() async {
final appDir = await getApplicationDocumentsDirectory();
final appDir = await getAppDir();
await CakeHive.close();
CakeHive.init(appDir.path);
@ -182,7 +183,7 @@ class BackupService {
}
Future<void> _importPreferencesDump() async {
final appDir = await getApplicationDocumentsDirectory();
final appDir = await getAppDir();
final preferencesFile = File('${appDir.path}/~_preferences_dump');
if (!preferencesFile.existsSync()) {
@ -379,7 +380,7 @@ class BackupService {
Future<void> _importKeychainDumpV1(String password,
{required String nonce, String keychainSalt = secrets.backupKeychainSalt}) async {
final appDir = await getApplicationDocumentsDirectory();
final appDir = await getAppDir();
final keychainDumpFile = File('${appDir.path}/~_keychain_dump');
final decryptedKeychainDumpFileData =
await _decryptV1(keychainDumpFile.readAsBytesSync(), '$keychainSalt$password', nonce);
@ -405,7 +406,7 @@ class BackupService {
Future<void> _importKeychainDumpV2(String password,
{String keychainSalt = secrets.backupKeychainSalt}) async {
final appDir = await getApplicationDocumentsDirectory();
final appDir = await getAppDir();
final keychainDumpFile = File('${appDir.path}/~_keychain_dump');
final decryptedKeychainDumpFileData =
await _decryptV2(keychainDumpFile.readAsBytesSync(), '$keychainSalt$password');

View file

@ -1,11 +1,11 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cake_wallet/entities/encrypt.dart';
class KeyService {
KeyService(this._secureStorage);
final FlutterSecureStorage _secureStorage;
final SecureStorage _secureStorage;
Future<String> getWalletPassword({required String walletName}) async {
final key = generateStoreKeyFor(

View file

@ -2,7 +2,6 @@ import 'package:cake_wallet/di.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/core/key_service.dart';
@ -15,7 +14,6 @@ import 'package:cw_core/wallet_type.dart';
class WalletCreationService {
WalletCreationService(
{required WalletType initialType,
required this.secureStorage,
required this.keyService,
required this.sharedPreferences,
required this.walletInfoSource})
@ -24,7 +22,6 @@ class WalletCreationService {
}
WalletType type;
final FlutterSecureStorage secureStorage;
final SharedPreferences sharedPreferences;
final KeyService keyService;
final Box<WalletInfo> walletInfoSource;
@ -58,10 +55,13 @@ class WalletCreationService {
Future<WalletBase> create(WalletCredentials credentials) async {
checkIfExists(credentials.name);
final password = generateWalletPassword();
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
if (credentials.password == null) {
credentials.password = generateWalletPassword();
await keyService.saveWalletPassword(
password: credentials.password!, walletName: credentials.name);
}
final wallet = await _service!.create(credentials);
if (wallet.type == WalletType.monero) {
@ -76,10 +76,13 @@ class WalletCreationService {
Future<WalletBase> restoreFromKeys(WalletCredentials credentials) async {
checkIfExists(credentials.name);
final password = generateWalletPassword();
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
if (credentials.password == null) {
credentials.password = generateWalletPassword();
await keyService.saveWalletPassword(
password: credentials.password!, walletName: credentials.name);
}
final wallet = await _service!.restoreFromKeys(credentials);
if (wallet.type == WalletType.monero) {
@ -94,10 +97,13 @@ class WalletCreationService {
Future<WalletBase> restoreFromSeed(WalletCredentials credentials) async {
checkIfExists(credentials.name);
final password = generateWalletPassword();
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
if (credentials.password == null) {
credentials.password = generateWalletPassword();
await keyService.saveWalletPassword(
password: credentials.password!, walletName: credentials.name);
}
final wallet = await _service!.restoreFromSeed(credentials);
if (wallet.type == WalletType.monero) {

View file

@ -7,12 +7,14 @@ import 'package:cw_core/wallet_type.dart';
import 'package:shared_preferences/shared_preferences.dart';
class WalletLoadingService {
WalletLoadingService(
this.sharedPreferences, this.keyService, this.walletServiceFactory);
final SharedPreferences sharedPreferences;
final KeyService keyService;
final WalletService Function(WalletType type) walletServiceFactory;
WalletLoadingService(
this.sharedPreferences,
this.keyService,
this.walletServiceFactory);
final SharedPreferences sharedPreferences;
final KeyService keyService;
final WalletService Function(WalletType type) walletServiceFactory;
Future<void> renameWallet(
WalletType type, String name, String newName) async {
@ -36,11 +38,33 @@ class WalletLoadingService {
await sharedPreferences.setBool(newNameKey, isPasswordUpdated);
}
}
Future<WalletBase> load(WalletType type, String name) async {
Future<void> renameWallet(
WalletType type, String name, String newName) async {
final walletService = walletServiceFactory.call(type);
final password = await keyService.getWalletPassword(walletName: name);
final wallet = await walletService.openWallet(name, password);
// Save the current wallet's password to the new wallet name's key
await keyService.saveWalletPassword(
walletName: newName, password: password);
// Delete previous wallet name from keyService to keep only new wallet's name
// otherwise keeps duplicate (old and new names)
await keyService.deleteWalletPassword(walletName: name);
await walletService.rename(name, password, newName);
// set shared preferences flag based on previous wallet name
if (type == WalletType.monero) {
final oldNameKey = PreferencesKey.moneroWalletUpdateV1Key(name);
final isPasswordUpdated = sharedPreferences.getBool(oldNameKey) ?? false;
final newNameKey = PreferencesKey.moneroWalletUpdateV1Key(newName);
await sharedPreferences.setBool(newNameKey, isPasswordUpdated);
}
}
Future<WalletBase> load(WalletType type, String name) async {
final walletService = walletServiceFactory.call(type);
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
final wallet = await walletService.openWallet(name, password);
if (type == WalletType.monero) {
await updateMoneroWalletPassword(wallet);

View file

@ -1,3 +1,9 @@
import 'dart:io';
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/core/yat_service.dart';
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/anonpay/anonpay_api.dart';
import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
@ -15,7 +21,9 @@ import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_tip.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
@ -33,6 +41,10 @@ import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dar
import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
@ -44,12 +56,10 @@ import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
@ -80,6 +90,9 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_i
import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:cake_wallet/view_model/wallet_unlock_loadable_view_model.dart';
import 'package:cake_wallet/view_model/wallet_unlock_verifiable_view_model.dart';
import 'package:cake_wallet/view_model/wallet_unlock_view_model.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cake_wallet/core/backup_service.dart';
import 'package:cw_core/wallet_service.dart';
@ -172,12 +185,13 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:get_it/get_it.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cw_core/wallet_type.dart';
@ -202,6 +216,7 @@ import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
import 'package:cake_wallet/core/wallet_loading_service.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart';
import 'package:cake_wallet/entities/qr_view_data.dart';
import 'core/totp_request_details.dart';
@ -258,7 +273,7 @@ Future<void> setup({
nodeSource: _nodeSource,
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
// Enforce darkTheme on platforms other than mobile till the design for other themes is completed
initialTheme: ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile
initialTheme: DeviceInfo.instance.isMobile
? null
: ThemeList.darkTheme,
);
@ -269,7 +284,7 @@ Future<void> setup({
getIt.registerFactory<Box<Node>>(() => _nodeSource);
getIt.registerSingleton<FlutterSecureStorage>(FlutterSecureStorage());
getIt.registerSingleton<SecureStorage>(secureStorageShared);
getIt.registerSingleton(AuthenticationStore());
getIt.registerSingleton<WalletListStore>(WalletListStore());
getIt.registerSingleton(NodeListStoreBase.instance);
@ -290,22 +305,21 @@ Future<void> setup({
getIt.registerSingleton<ExchangeTemplateStore>(
ExchangeTemplateStore(templateSource: _exchangeTemplates));
getIt.registerSingleton<YatStore>(
YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<FlutterSecureStorage>())
YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>())
..init());
getIt.registerSingleton<AnonpayTransactionsStore>(
AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
final secretStore = await SecretStoreBase.load(getIt.get<FlutterSecureStorage>());
final secretStore = await SecretStoreBase.load(getIt.get<SecureStorage>());
getIt.registerSingleton<SecretStore>(secretStore);
getIt.registerFactory<KeyService>(() => KeyService(getIt.get<FlutterSecureStorage>()));
getIt.registerFactory<KeyService>(() => KeyService(getIt.get<SecureStorage>()));
getIt.registerFactoryParam<WalletCreationService, WalletType, void>((type, _) =>
WalletCreationService(
initialType: type,
keyService: getIt.get<KeyService>(),
secureStorage: getIt.get<FlutterSecureStorage>(),
sharedPreferences: getIt.get<SharedPreferences>(),
walletInfoSource: _walletInfoSource));
@ -346,7 +360,7 @@ Future<void> setup({
getIt.registerFactory<AuthService>(
() => AuthService(
secureStorage: getIt.get<FlutterSecureStorage>(),
secureStorage: getIt.get<SecureStorage>(),
sharedPreferences: getIt.get<SharedPreferences>(),
settingsStore: getIt.get<SettingsStore>(),
),
@ -693,7 +707,7 @@ Future<void> setup({
wallet: getIt.get<AppStore>().wallet!,
));
getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri));
getIt.registerFactory(() => OnRamperPage(getIt.get<OnRamperBuyProvider>()));
getIt.registerFactory<PayfuraBuyProvider>(() => PayfuraBuyProvider(
settingsStore: getIt.get<AppStore>().settingsStore,
@ -732,11 +746,15 @@ Future<void> setup({
case WalletType.monero:
return monero!.createMoneroWalletService(_walletInfoSource, _unspentCoinsInfoSource);
case WalletType.bitcoin:
return bitcoin!.createBitcoinWalletService(_walletInfoSource, _unspentCoinsInfoSource);
return bitcoin!.createBitcoinWalletService(
_walletInfoSource, _unspentCoinsInfoSource,
SettingsStoreBase.walletPasswordDirectInput);
case WalletType.litecoin:
return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource);
return bitcoin!.createLitecoinWalletService(
_walletInfoSource, _unspentCoinsInfoSource);
case WalletType.ethereum:
return ethereum!.createEthereumWalletService(_walletInfoSource);
return ethereum!.createEthereumWalletService(_walletInfoSource,
SettingsStoreBase.walletPasswordDirectInput);
default:
throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
}
@ -791,16 +809,19 @@ Future<void> setup({
trades: _tradesSource,
settingsStore: getIt.get<SettingsStore>()));
getIt.registerFactory(() => BackupService(getIt.get<FlutterSecureStorage>(), _walletInfoSource,
getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
getIt.registerFactory(() => BackupService(
getIt.get<SecureStorage>(),
_walletInfoSource,
getIt.get<KeyService>(),
getIt.get<SharedPreferences>()));
getIt.registerFactory(() => BackupViewModel(
getIt.get<FlutterSecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupService>()));
getIt.get<SecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupService>()));
getIt.registerFactory(() => BackupPage(getIt.get<BackupViewModel>()));
getIt.registerFactory(() =>
EditBackupPasswordViewModel(getIt.get<FlutterSecureStorage>(), getIt.get<SecretStore>()));
EditBackupPasswordViewModel(getIt.get<SecureStorage>(), getIt.get<SecretStore>()));
getIt.registerFactory(() => EditBackupPasswordPage(getIt.get<EditBackupPasswordViewModel>()));
@ -891,7 +912,7 @@ Future<void> setup({
getIt.registerFactory(() => AnyPayApi());
getIt.registerFactory<IoniaService>(
() => IoniaService(getIt.get<FlutterSecureStorage>(), getIt.get<IoniaApi>()));
() => IoniaService(getIt.get<SecureStorage>(), getIt.get<IoniaApi>()));
getIt.registerFactory<IoniaAnyPay>(() => IoniaAnyPay(
getIt.get<IoniaService>(), getIt.get<AnyPayApi>(), getIt.get<AppStore>().wallet!));
@ -929,7 +950,7 @@ Future<void> setup({
return IoniaVerifyIoniaOtp(getIt.get<IoniaAuthViewModel>(), email, isSignIn);
});
getIt.registerFactory(() => IoniaWelcomePage());
getIt.registerFactory(() => IoniaWelcomePage(getIt.get<IoniaGiftCardsListViewModel>()));
getIt.registerFactoryParam<IoniaBuyGiftCardPage, List, void>((List args, _) {
final merchant = args.first as IoniaMerchant;
@ -1048,5 +1069,62 @@ Future<void> setup({
getIt.registerFactory<ManageNodesPage>(() => ManageNodesPage(getIt.get<NodeListViewModel>()));
getIt.registerFactoryParam<WalletUnlockLoadableViewModel, WalletUnlockArguments, void>((args, _) {
final currentWalletName = getIt
.get<SharedPreferences>()
.getString(PreferencesKey.currentWalletName) ?? '';
final currentWalletTypeRaw =
getIt.get<SharedPreferences>()
.getInt(PreferencesKey.currentWalletType) ?? 0;
final currentWalletType = deserializeFromInt(currentWalletTypeRaw);
return WalletUnlockLoadableViewModel(
getIt.get<AppStore>(),
getIt.get<WalletLoadingService>(),
walletName: args.walletName ?? currentWalletName,
walletType: args.walletType ?? currentWalletType);
});
getIt.registerFactoryParam<WalletUnlockVerifiableViewModel, WalletUnlockArguments, void>((args, _) {
final currentWalletName = getIt
.get<SharedPreferences>()
.getString(PreferencesKey.currentWalletName) ?? '';
final currentWalletTypeRaw =
getIt.get<SharedPreferences>()
.getInt(PreferencesKey.currentWalletType) ?? 0;
final currentWalletType = deserializeFromInt(currentWalletTypeRaw);
return WalletUnlockVerifiableViewModel(
getIt.get<AppStore>(),
walletName: args.walletName ?? currentWalletName,
walletType: args.walletType ?? currentWalletType);
});
getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
return WalletUnlockPage(
getIt.get<WalletUnlockLoadableViewModel>(param1: args),
args.callback,
closable: closable);
}, instanceName: 'wallet_unlock_loadable');
getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
return WalletUnlockPage(
getIt.get<WalletUnlockVerifiableViewModel>(param1: args),
args.callback,
closable: closable);
}, instanceName: 'wallet_unlock_verifiable');
getIt.registerFactory<WalletUnlockPage>(
() => getIt.get<WalletUnlockPage>(
param1: WalletUnlockArguments(
callback: (bool successful, _) {
if (successful) {
final authStore = getIt.get<AuthenticationStore>();
authStore.allowed();
}}),
param2: false,
instanceName: 'wallet_unlock_loadable'),
instanceName: 'wallet_password_login');
_isSetupFinished = true;
}

View file

@ -3,7 +3,7 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -30,7 +30,7 @@ const ethereumDefaultNodeUri = 'ethereum.publicnode.com';
Future<void> defaultSettingsMigration(
{required int version,
required SharedPreferences sharedPreferences,
required FlutterSecureStorage secureStorage,
required SecureStorage secureStorage,
required Box<Node> nodes,
required Box<WalletInfo> walletInfoSource,
required Box<Trade> tradeSource,
@ -453,7 +453,7 @@ Future<void> updateDisplayModes(SharedPreferences sharedPreferences) async {
PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode);
}
Future<void> generateBackupPassword(FlutterSecureStorage secureStorage) async {
Future<void> generateBackupPassword(SecureStorage secureStorage) async {
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
if ((await secureStorage.read(key: key))?.isNotEmpty ?? false) {

View file

@ -1,7 +1,7 @@
import 'dart:io';
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
@ -136,9 +136,8 @@ Future<void> ios_migrate_pin() async {
return;
}
final flutterSecureStorage = FlutterSecureStorage();
final pinPassword = await flutterSecureStorage.read(
key: 'pin_password', iOptions: IOSOptions());
final flutterSecureStorage = secureStorageShared;
final pinPassword = await flutterSecureStorage.readNoIOptions(key: 'pin_password');
// No pin
if (pinPassword == null) {
await prefs.setBool('ios_migration_pin_completed', true);
@ -159,7 +158,7 @@ Future<void> ios_migrate_wallet_passwords() async {
}
final appDocDir = await getApplicationDocumentsDirectory();
final flutterSecureStorage = FlutterSecureStorage();
final flutterSecureStorage = secureStorageShared;
final keyService = KeyService(flutterSecureStorage);
final walletsDir = Directory('${appDocDir.path}/wallets');
final moneroWalletsDir = Directory('${walletsDir.path}/monero');
@ -174,8 +173,7 @@ Future<void> ios_migrate_wallet_passwords() async {
if (item is Directory) {
final name = item.path.split('/').last;
final oldKey = 'wallet_monero_' + name + '_password';
final password = await flutterSecureStorage.read(
key: oldKey, iOptions: IOSOptions());
final password = await flutterSecureStorage.readNoIOptions(key: oldKey);
await keyService.saveWalletPassword(
walletName: name, password: password!);
}
@ -371,9 +369,8 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
}
final content = file.readAsBytesSync();
final flutterSecureStorage = FlutterSecureStorage();
final masterPassword = await flutterSecureStorage.read(
key: 'master_password', iOptions: IOSOptions());
final flutterSecureStorage = secureStorageShared;
final masterPassword = await flutterSecureStorage.readNoIOptions(key: 'master_password');
final key = masterPassword!.replaceAll('-', '');
final decoded =
await ios_legacy_helper.decrypt(content, key: key, salt: secrets.salt);

View file

@ -1,8 +1,8 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cw_core/cake_hive.dart';
Future<List<int>> getEncryptionKey(
{required String forKey, required FlutterSecureStorage secureStorage}) async {
{required String forKey, required SecureStorage secureStorage}) async {
final stringifiedKey = await secureStorage.read(key: 'transactionDescriptionsBoxKey');
List<int> key;

View file

@ -55,11 +55,11 @@ class LanguageService {
'cs': 'czk',
'ur': 'pak',
'id': 'idn',
'yo': 'nga',
'yo': 'yor',
'ha': 'hau'
};
static final list = <String, String>{};
static final list = <String, String> {};
static void loadLocaleList() {
supportedLocales.forEach((key, value) {

View file

@ -6,7 +6,7 @@ import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/core/wallet_loading_service.dart';
Future<void> loadCurrentWallet() async {
Future<void> loadCurrentWallet({String? password}) async {
final appStore = getIt.get<AppStore>();
final name = getIt
.get<SharedPreferences>()
@ -21,7 +21,10 @@ Future<void> loadCurrentWallet() async {
final type = deserializeFromInt(typeRaw);
final walletLoadingService = getIt.get<WalletLoadingService>();
final wallet = await walletLoadingService.load(type, name);
final wallet = await walletLoadingService.load(
type,
name,
password: password);
appStore.changeCurrentWallet(wallet);
getIt.get<BackgroundTasks>().registerSyncTask();

View file

@ -51,8 +51,7 @@ class MainActions {
if (viewModel.isEnabledBuyAction) {
final uri = getIt.get<OnRamperBuyProvider>().requestUrl(context);
if (DeviceInfo.instance.isMobile) {
Navigator.of(context)
.pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]);
Navigator.of(context).pushNamed(Routes.onramperPage);
} else {
await launchUrl(uri);
}
@ -117,16 +116,9 @@ class MainActions {
final uri = await moonPaySellProvider.requestUrl(
currency: viewModel.wallet.currency,
refundWalletAddress: viewModel.wallet.walletAddresses.address,
settingsStore: viewModel.settingsStore,
);
if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.webViewPage,
arguments: [S.of(context).sell, uri]);
} else {
await launchUrl(uri);
}
await launchUrl(uri);
}
break;
default:
await showPopUp<void>(

View file

@ -202,11 +202,11 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final expectedSendAmount = responseJSON['expectedAmountFrom'].toString();
final status = responseJSON['status'] as String;
final state = TradeState.deserialize(raw: status);
final extraId = responseJSON['payinExtraId'] as String?;
final outputTransaction = responseJSON['payoutHash'] as String?;
final expiredAtRaw = responseJSON['validUntil'] as String?;
final extraId = responseJSON['payinExtraId'] as String;
final outputTransaction = responseJSON['payoutHash'] as String;
final expiredAtRaw = responseJSON['validUntil'] as String;
final payoutAddress = responseJSON['payoutAddress'] as String;
final expiredAt = DateTime.tryParse(expiredAtRaw ?? '')?.toLocal();
final expiredAt = DateTime.tryParse(expiredAtRaw)?.toLocal();
return Trade(
id: id,

View file

@ -19,10 +19,10 @@ class SideShiftExchangeProvider extends ExchangeProvider {
static const affiliateId = secrets.sideShiftAffiliateId;
static const apiBaseUrl = 'https://sideshift.ai/api';
static const rangePath = '/v2/pair';
static const orderPath = '/v2/shifts';
static const quotePath = '/v2/quotes';
static const permissionPath = '/v2/permissions';
static const rangePath = '/v1/pairs';
static const orderPath = '/v1/orders';
static const quotePath = '/v1/quotes';
static const permissionPath = '/v1/permissions';
static const List<CryptoCurrency> _notSupported = [
CryptoCurrency.xhv,
@ -35,22 +35,23 @@ class SideShiftExchangeProvider extends ExchangeProvider {
CryptoCurrency.scrt,
CryptoCurrency.stx,
CryptoCurrency.bttc,
CryptoCurrency.usdt,
CryptoCurrency.eos,
];
static List<ExchangePair> _supportedPairs() {
final supportedCurrencies =
CryptoCurrency.all.where((element) => !_notSupported.contains(element)).toList();
final supportedCurrencies = CryptoCurrency.all
.where((element) => !_notSupported.contains(element))
.toList();
return supportedCurrencies
.map((i) => supportedCurrencies.map((k) => ExchangePair(from: i, to: k, reverse: true)))
.map((i) => supportedCurrencies
.map((k) => ExchangePair(from: i, to: k, reverse: true)))
.expand((i) => i)
.toList();
}
@override
ExchangeProviderDescription get description => ExchangeProviderDescription.sideShift;
ExchangeProviderDescription get description =>
ExchangeProviderDescription.sideShift;
@override
Future<double> fetchRate(
@ -63,18 +64,17 @@ class SideShiftExchangeProvider extends ExchangeProvider {
if (amount == 0) {
return 0.0;
}
final fromCurrency = from.title.toLowerCase();
final toCurrency = to.title.toLowerCase();
final depositNetwork = _networkFor(from);
final settleNetwork = _networkFor(to);
final url = "$apiBaseUrl$rangePath/$fromCurrency-$depositNetwork/$toCurrency-$settleNetwork";
final fromCurrency = _normalizeCryptoCurrency(from);
final toCurrency = _normalizeCryptoCurrency(to);
final url =
apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
final uri = Uri.parse(url);
final response = await get(uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final rate = double.parse(responseJSON['rate'] as String);
final max = double.parse(responseJSON['max'] as String);
if (amount > max) return 0.00;
return rate;
} catch (_) {
@ -100,38 +100,25 @@ class SideShiftExchangeProvider extends ExchangeProvider {
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final cancreateShift = responseJSON['createShift'] as bool;
return cancreateShift;
final canCreateOrder = responseJSON['createOrder'] as bool;
final canCreateQuote = responseJSON['createQuote'] as bool;
return canCreateOrder && canCreateQuote;
}
@override
Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
Future<Trade> createTrade(
{required TradeRequest request, required bool isFixedRateMode}) async {
final _request = request as SideShiftRequest;
String url = '';
final depositCoin = request.depositMethod.title.toLowerCase();
final settleCoin = request.settleMethod.title.toLowerCase();
final quoteId = await _createQuote(_request);
final url = apiBaseUrl + orderPath;
final headers = {'Content-Type': 'application/json'};
final body = {
'type': 'fixed',
'quoteId': quoteId,
'affiliateId': affiliateId,
'settleAddress': _request.settleAddress,
'refundAddress': _request.refundAddress,
'refundAddress': _request.refundAddress
};
if (isFixedRateMode) {
final quoteId = await _createQuote(_request);
body['quoteId'] = quoteId;
url = apiBaseUrl + orderPath + '/fixed';
} else {
url = apiBaseUrl + orderPath + '/variable';
final depositNetwork = _networkFor(request.depositMethod);
final settleNetwork = _networkFor(request.settleMethod);
body["depositCoin"] = depositCoin;
body["settleCoin"] = settleCoin;
body["settleNetwork"] = settleNetwork;
body["depositNetwork"] = depositNetwork;
}
final headers = {'Content-Type': 'application/json'};
final uri = Uri.parse(url);
final response = await post(uri, headers: headers, body: json.encode(body));
@ -148,9 +135,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final id = responseJSON['id'] as String;
final inputAddress = responseJSON['depositAddress'] as String;
final settleAddress = responseJSON['settleAddress'] as String;
final depositAmount = responseJSON['depositAmount'] as String?;
final inputAddress = responseJSON['depositAddress']['address'] as String;
final settleAddress = responseJSON['settleAddress']['address'] as String;
return Trade(
id: id,
@ -160,7 +146,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
inputAddress: inputAddress,
refundAddress: settleAddress,
state: TradeState.created,
amount: depositAmount ?? _request.depositAmount,
amount: _request.depositAmount,
payoutAddress: settleAddress,
createdAt: DateTime.now(),
);
@ -169,17 +155,13 @@ class SideShiftExchangeProvider extends ExchangeProvider {
Future<String> _createQuote(SideShiftRequest request) async {
final url = apiBaseUrl + quotePath;
final headers = {'Content-Type': 'application/json'};
final depositMethod = request.depositMethod.title.toLowerCase();
final settleMethod = request.settleMethod.title.toLowerCase();
final depositNetwork = _networkFor(request.depositMethod);
final settleNetwork = _networkFor(request.settleMethod);
final depositMethod = _normalizeCryptoCurrency(request.depositMethod);
final settleMethod = _normalizeCryptoCurrency(request.settleMethod);
final body = {
'depositCoin': depositMethod,
'settleCoin': settleMethod,
'depositMethod': depositMethod,
'settleMethod': settleMethod,
'affiliateId': affiliateId,
'settleAmount': request.depositAmount,
'settleNetwork': settleNetwork,
'depositNetwork': depositNetwork,
'depositAmount': request.depositAmount,
};
final uri = Uri.parse(url);
final response = await post(uri, headers: headers, body: json.encode(body));
@ -206,15 +188,9 @@ class SideShiftExchangeProvider extends ExchangeProvider {
{required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode}) async {
final fromCurrency = isFixedRateMode ? to : from;
final toCurrency = isFixedRateMode ? from : to;
final fromNetwork = _networkFor(fromCurrency);
final toNetwork = _networkFor(toCurrency);
final url =
"$apiBaseUrl$rangePath/${fromCurrency.title.toLowerCase()}-$fromNetwork/${toCurrency.title.toLowerCase()}-$toNetwork";
final fromCurrency = _normalizeCryptoCurrency(from);
final toCurrency = _normalizeCryptoCurrency(to);
final url = apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
final uri = Uri.parse(url);
final response = await get(uri);
@ -233,14 +209,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final min = double.tryParse(responseJSON['min'] as String? ?? '');
final max = double.tryParse(responseJSON['max'] as String? ?? '');
if (isFixedRateMode) {
final currentRate = double.parse(responseJSON['rate'] as String);
return Limits(
min: min != null ? (min * currentRate) : null,
max: max != null ? (max * currentRate) : null,
);
}
return Limits(min: min, max: max);
}
@ -258,7 +226,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final error = responseJSON['error']['message'] as String;
throw TradeNotFoundException(id, provider: description, description: error);
throw TradeNotFoundException(id,
provider: description, description: error);
}
if (response.statusCode != 200) {
@ -266,32 +235,36 @@ class SideShiftExchangeProvider extends ExchangeProvider {
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final fromCurrency = responseJSON['depositCoin'] as String;
final fromCurrency = responseJSON['depositMethodId'] as String;
final from = CryptoCurrency.fromString(fromCurrency);
final toCurrency = responseJSON['settleCoin'] as String;
final toCurrency = responseJSON['settleMethodId'] as String;
final to = CryptoCurrency.fromString(toCurrency);
final inputAddress = responseJSON['depositAddress'] as String;
final expectedSendAmount = responseJSON['depositAmount'] as String?;
final status = responseJSON['status'] as String?;
final settleAddress = responseJSON['settleAddress'] as String;
final inputAddress = responseJSON['depositAddress']['address'] as String;
final expectedSendAmount = responseJSON['depositAmount'].toString();
final deposits = responseJSON['deposits'] as List?;
final settleAddress = responseJSON['settleAddress']['address'] as String;
TradeState? state;
String? status;
if (deposits?.isNotEmpty ?? false) {
status = deposits![0]['status'] as String?;
}
state = TradeState.deserialize(raw: status ?? 'created');
final isVariable = (responseJSON['type'] as String) == 'variable';
final expiredAtRaw = responseJSON['expiresAt'] as String;
final expiredAt = isVariable ? null : DateTime.tryParse(expiredAtRaw)?.toLocal();
final expiredAtRaw = responseJSON['expiresAtISO'] as String;
final expiredAt = DateTime.tryParse(expiredAtRaw)?.toLocal();
return Trade(
id: id,
from: from,
to: to,
provider: description,
inputAddress: inputAddress,
amount: expectedSendAmount ?? '',
state: state,
expiredAt: expiredAt,
payoutAddress: settleAddress);
id: id,
from: from,
to: to,
provider: description,
inputAddress: inputAddress,
amount: expectedSendAmount,
state: state,
expiredAt: expiredAt,
payoutAddress: settleAddress
);
}
@override
@ -306,25 +279,28 @@ class SideShiftExchangeProvider extends ExchangeProvider {
@override
String get title => 'SideShift';
String _networkFor(CryptoCurrency currency) =>
currency.tag != null ? _normalizeTag(currency.tag!) : 'mainnet';
String _normalizeTag(String tag) {
switch (tag) {
case 'ETH':
return 'ethereum';
case 'TRX':
return 'tron';
case 'LN':
return 'lightning';
case 'POLY':
static String _normalizeCryptoCurrency(CryptoCurrency currency) {
switch (currency) {
case CryptoCurrency.zaddr:
return 'zaddr';
case CryptoCurrency.zec:
return 'zec';
case CryptoCurrency.bnb:
return currency.tag!.toLowerCase();
case CryptoCurrency.usdterc20:
return 'usdtErc20';
case CryptoCurrency.usdttrc20:
return 'usdtTrc20';
case CryptoCurrency.usdcpoly:
return 'usdcpolygon';
case CryptoCurrency.usdcsol:
return 'usdcsol';
case CryptoCurrency.maticpoly:
return 'polygon';
case 'ZEC':
return 'zcash';
case 'AVAXC':
return 'avax';
case CryptoCurrency.btcln:
return 'ln';
default:
return tag.toLowerCase();
return currency.title.toLowerCase();
}
}
}

View file

@ -1,7 +1,7 @@
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/ionia/ionia_api.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
@ -17,7 +17,7 @@ class IoniaService {
static String get clientId => secrets.ioniaClientId;
final FlutterSecureStorage secureStorage;
final SecureStorage secureStorage;
final IoniaApi ioniaApi;
// Create user

View file

@ -7,7 +7,7 @@ import 'package:cake_wallet/locales/locale.dart';
import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cw_core/address_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/hive_type_ids.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -16,7 +16,7 @@ import 'package:hive/hive.dart';
import 'package:cake_wallet/di.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/router.dart' as Router;
@ -71,7 +71,8 @@ Future<void> main() async {
}
Future<void> initializeAppConfigs() async {
final appDir = await getApplicationDocumentsDirectory();
setRootDirFromEnv();
final appDir = await getAppDir();
CakeHive.init(appDir.path);
if (!CakeHive.isAdapterRegistered(Contact.typeId)) {
@ -122,7 +123,7 @@ Future<void> initializeAppConfigs() async {
CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
}
final secureStorage = FlutterSecureStorage();
final secureStorage = secureStorageShared;
final transactionDescriptionsBoxKey =
await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
@ -168,7 +169,7 @@ Future<void> initialSetup(
required Box<Template> templates,
required Box<ExchangeTemplate> exchangeTemplates,
required Box<TransactionDescription> transactionDescriptions,
required FlutterSecureStorage secureStorage,
required SecureStorage secureStorage,
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
int initialMigrationVersion = 15}) async {
@ -202,7 +203,10 @@ class App extends StatefulWidget {
}
class AppState extends State<App> with SingleTickerProviderStateMixin {
AppState() : yatStore = getIt.get<YatStore>();
AppState() : yatStore = getIt.get<YatStore>() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
}
YatStore yatStore;
StreamSubscription? stream;

View file

@ -1,9 +1,10 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/sync_status.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:connectivity/connectivity.dart';
Timer? _checkConnectionTimer;
void startCheckConnectionReaction(

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:flutter/widgets.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/entities/load_current_wallet.dart';
@ -14,7 +15,7 @@ void startAuthenticationStateChange(
_onAuthenticationStateChange ??= autorun((_) async {
final state = authenticationStore.state;
if (state == AuthenticationState.installed) {
if (state == AuthenticationState.installed && !SettingsStoreBase.walletPasswordDirectInput) {
try {
await loadCurrentWallet();
} catch (error, stack) {

View file

@ -8,7 +8,7 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar
import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
@ -45,6 +45,8 @@ import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart';
import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart';
import 'package:cake_wallet/src/screens/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_unlock/wallet_unlock_arguments.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
@ -99,6 +101,7 @@ import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/node.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart';
late RouteSettings currentRouteSettings;
@ -110,6 +113,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
return MaterialPageRoute<void>(builder: (_) => createWelcomePage());
case Routes.newWalletFromWelcome:
if (SettingsStoreBase.walletPasswordDirectInput) {
if (availableWalletTypes.length == 1) {
return createRoute(RouteSettings(name: Routes.newWallet, arguments: availableWalletTypes.first));
} else {
return createRoute(RouteSettings(name: Routes.newWalletType));
}
}
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>(
param1: (PinCodeState<PinCodeWidget> context, dynamic _) {
@ -118,7 +129,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
} else {
Navigator.of(context.context).pushNamed(Routes.newWalletType);
}
}),
}),
fullscreenDialog: true);
case Routes.newWalletType:
@ -155,6 +166,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
param2: false));
case Routes.restoreOptions:
if (SettingsStoreBase.walletPasswordDirectInput) {
return createRoute(RouteSettings(name: Routes.restoreWalletType));
}
final isNewInstall = settings.arguments as bool;
return CupertinoPageRoute<void>(
fullscreenDialog: true,
@ -178,6 +193,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
fullscreenDialog: true);
} else if (isSingleCoin) {
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<WalletRestorePage>(
param1: availableWalletTypes.first
));
@ -198,6 +214,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.restoreWallet:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<WalletRestorePage>(
param1: settings.arguments as WalletType));
@ -207,7 +224,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.dashboard:
return CupertinoPageRoute<void>(
settings: settings,
builder: (_) => getIt.get<DashboardPage>());
case Routes.send:
@ -273,9 +289,16 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.auth:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished,
param2: true));
builder: (_)
=> SettingsStoreBase.walletPasswordDirectInput
? getIt.get<WalletUnlockPage>(
param1: WalletUnlockArguments(
callback: settings.arguments as OnAuthenticationFinished),
instanceName: 'wallet_unlock_verifiable',
param2: true)
: getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished,
param2: true));
case Routes.totpAuthCodePage:
final args = settings.arguments as TotpAuthArgumentsModel;
@ -286,25 +309,32 @@ Route<dynamic> createRoute(RouteSettings settings) {
),
);
case Routes.login:
return CupertinoPageRoute<void>(
builder: (context) => WillPopScope(
child: getIt.get<AuthPage>(instanceName: 'login'),
onWillPop: () async =>
// FIX-ME: Additional check does it works correctly
(await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ??
false),
),
fullscreenDialog: true);
case Routes.walletUnlockLoadable:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_)
=> getIt.get<WalletUnlockPage>(
param1: settings.arguments as WalletUnlockArguments,
instanceName: 'wallet_unlock_loadable',
param2: true));
case Routes.unlock:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => WillPopScope(
child: getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished,
param2: false),
onWillPop: () async => false));
builder: (_)
=> SettingsStoreBase.walletPasswordDirectInput
? WillPopScope(
child: getIt.get<WalletUnlockPage>(
param1: WalletUnlockArguments(
callback: settings.arguments as OnAuthenticationFinished),
param2: false,
instanceName: 'wallet_unlock_verifiable'),
onWillPop: () async => false)
: WillPopScope(
child: getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished,
param2: false),
onWillPop: () async => false));
case Routes.connectionSync:
return CupertinoPageRoute<void>(
@ -338,7 +368,16 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: args?['editingNode'] as Node?,
param2: args?['isSelected'] as bool?));
case Routes.login:
return CupertinoPageRoute<void>(
builder: (context) => WillPopScope(
child: SettingsStoreBase.walletPasswordDirectInput
? getIt.get<WalletUnlockPage>(instanceName: 'wallet_password_login')
: getIt.get<AuthPage>(instanceName: 'login'),
onWillPop: () async =>
// FIX-ME: Additional check does it works correctly
(await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ?? false)),
fullscreenDialog: true);
case Routes.accountCreation:
return CupertinoPageRoute<String>(
@ -474,8 +513,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>( builder: (_) => getIt.get<IoniaCreateAccountPage>());
case Routes.ioniaManageCardsPage:
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<IoniaManageCardsPage>());
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaManageCardsPage>());
case Routes.ioniaBuyGiftCardPage:
final args = settings.arguments as List;
@ -525,13 +563,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: paymentInfo,
param2: commitedInfo));
case Routes.webViewPage:
final args = settings.arguments as List;
final title = args.first as String;
final url = args[1] as Uri;
return CupertinoPageRoute<void>(builder: (_) => getIt.get<WebViewPage>(
param1: title,
param2: url));
case Routes.onramperPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<OnRamperPage>());
case Routes.advancedPrivacySettings:
final type = settings.arguments as WalletType;
@ -545,6 +578,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.anonPayInvoicePage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<AnonPayInvoicePage>(param1: args));
case Routes.anonPayReceivePage:

View file

@ -72,7 +72,7 @@ class Routes {
static const ioniaPaymentStatusPage = '/ionia_payment_status_page';
static const ioniaMoreOptionsPage = '/ionia_more_options_page';
static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page';
static const webViewPage = '/web_view_page';
static const onramperPage = '/onramper';
static const connectionSync = '/connection_sync_page';
static const securityBackupPage = '/security_and_backup_page';
static const privacyPage = '/privacy_page';
@ -80,6 +80,8 @@ class Routes {
static const otherSettingsPage = '/other_settings_page';
static const advancedPrivacySettings = '/advanced_privacy_settings';
static const sweepingWalletPage = '/sweeping_wallet_page';
static const walletPasswordUnlock = '/wallet_password_unlock';
static const walletUnlockLoadable = '/wallet_unlock_loadable';
static const anonPayInvoicePage = '/anon_pay_invoice_page';
static const anonPayReceivePage = '/anon_pay_receive_page';
static const anonPayDetailsPage = '/anon_pay_details_page';

View file

@ -12,6 +12,12 @@ import 'package:cake_wallet/core/execution_state.dart';
typedef OnAuthenticationFinished = void Function(bool, AuthPageState);
abstract class AuthPageState<T extends StatefulWidget> extends State<T> {
void changeProcessText(String text);
void hideProgressText();
Future<void> close({String? route, dynamic arguments});
}
class AuthPage extends StatefulWidget {
AuthPage(this.authViewModel,
{required this.onAuthenticationFinished,
@ -22,10 +28,10 @@ class AuthPage extends StatefulWidget {
final bool closable;
@override
AuthPageState createState() => AuthPageState();
AuthPageState createState() => AuthPagePinCodeStateImpl();
}
class AuthPageState extends State<AuthPage> {
class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
final _key = GlobalKey<ScaffoldState>();
final _pinCodeKey = GlobalKey<PinCodeState>();
final _backArrowImageDarkTheme =
@ -55,8 +61,6 @@ class AuthPageState extends State<AuthPage> {
}
if (state is FailureState) {
print('X');
print(state.error);
WidgetsBinding.instance.addPostFrameCallback((_) async {
_pinCodeKey.currentState?.clear();
dismissFlushBar(_authBar);
@ -95,17 +99,20 @@ class AuthPageState extends State<AuthPage> {
super.dispose();
}
@override
void changeProcessText(String text) {
dismissFlushBar(_authBar);
_progressBar = createBar<void>(text, duration: null)
..show(_key.currentContext!);
}
@override
void hideProgressText() {
dismissFlushBar(_progressBar);
_progressBar = null;
}
@override
Future<void> close({String? route, dynamic arguments}) async {
if (_key.currentContext == null) {
throw Exception('Key context is null. Should be not happened');

View file

@ -5,32 +5,33 @@ import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';
class WebViewPage extends BasePage {
WebViewPage(this._title, this._url);
class OnRamperPage extends BasePage {
OnRamperPage(this._onRamperBuyProvider);
final String _title;
final Uri _url;
final OnRamperBuyProvider _onRamperBuyProvider;
@override
String get title => _title;
String get title => S.current.buy;
@override
Widget body(BuildContext context) {
return WebViewPageBody(_url);
return OnRamperPageBody(_onRamperBuyProvider);
}
}
class WebViewPageBody extends StatefulWidget {
WebViewPageBody(this.uri);
class OnRamperPageBody extends StatefulWidget {
OnRamperPageBody(this.onRamperBuyProvider);
final Uri uri;
final OnRamperBuyProvider onRamperBuyProvider;
Uri get uri => onRamperBuyProvider.requestUrl();
@override
WebViewPageBodyState createState() => WebViewPageBodyState();
OnRamperPageBodyState createState() => OnRamperPageBodyState();
}
class WebViewPageBodyState extends State<WebViewPageBody> {
WebViewPageBodyState();
class OnRamperPageBodyState extends State<OnRamperPageBody> {
OnRamperPageBodyState();
@override
Widget build(BuildContext context) {

View file

@ -8,7 +8,7 @@ import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/version_comparator.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
@ -29,6 +29,8 @@ import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
@ -59,7 +61,7 @@ class DashboardPage extends StatelessWidget {
addressListViewModel: addressListViewModel,
);
}
} else if (ResponsiveLayoutUtil.instance.shouldRenderMobileUI()) {
} else if (ResponsiveLayoutUtil.instance.shouldRenderMobileUI()) {(context)
return _DashboardPageView(
balancePage: balancePage,
dashboardViewModel: dashboardViewModel,

View file

@ -1,9 +1,7 @@
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/main_actions.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -74,10 +72,7 @@ class DesktopDashboardActions extends StatelessWidget {
],
),
Expanded(
child: MarketPlacePage(
dashboardViewModel: dashboardViewModel,
marketPlaceViewModel: getIt.get<MarketPlaceViewModel>(),
),
child: MarketPlacePage(dashboardViewModel: dashboardViewModel),
),
],
);

View file

@ -4,9 +4,12 @@ import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/desktop_dropdown_item.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/store/settings_store.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';
@ -34,14 +37,12 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
final havenIcon = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
final ethereumIcon = Image.asset('assets/images/eth_icon.png', height: 24, width: 24);
final nonWalletTypeIcon = Image.asset('assets/images/close.png', height: 24, width: 24);
Image _newWalletImage(BuildContext context) => Image.asset(
'assets/images/new_wallet.png',
height: 12,
width: 12,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
);
Image _restoreWalletImage(BuildContext context) => Image.asset(
'assets/images/restore_wallet.png',
height: 12,
@ -147,6 +148,20 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
}
Future<void> _loadWallet(WalletListItem wallet) async {
if (SettingsStoreBase.walletPasswordDirectInput) {
Navigator.of(context).pushNamed(
Routes.walletUnlockLoadable,
arguments: WalletUnlockArguments(
callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
if (isAuthenticatedSuccessfully) {
auth.close();
setState(() {});
}
}, walletName: wallet.name,
walletType: wallet.type));
return;
}
widget._authService.authenticateAction(context,
onAuthSuccess: (isAuthenticatedSuccessfully) async {
if (!isAuthenticatedSuccessfully) {

View file

@ -64,7 +64,7 @@ class AddressPage extends BasePage {
@override
Widget? leading(BuildContext context) {
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics(
child: SizedBox(
@ -250,7 +250,7 @@ class AddressPage extends BasePage {
reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) {
switch (option) {
case ReceivePageOption.anonPayInvoice:
Navigator.pushNamed(
Navigator.pushReplacementNamed(
context,
Routes.anonPayInvoicePage,
arguments: [addressListViewModel.address.address, option],
@ -262,7 +262,7 @@ class AddressPage extends BasePage {
final onionUrl = sharedPreferences.getString(PreferencesKey.onionDonationLink);
if (clearnetUrl != null && onionUrl != null) {
Navigator.pushNamed(
Navigator.pushReplacementNamed(
context,
Routes.anonPayReceivePage,
arguments: AnonpayDonationLinkInfo(
@ -272,7 +272,7 @@ class AddressPage extends BasePage {
),
);
} else {
Navigator.pushNamed(
Navigator.pushReplacementNamed(
context,
Routes.anonPayInvoicePage,
arguments: [addressListViewModel.address.address, option],

View file

@ -1,9 +1,9 @@
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
@ -11,13 +11,10 @@ import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
class MarketPlacePage extends StatelessWidget {
MarketPlacePage({
required this.dashboardViewModel,
required this.marketPlaceViewModel,
});
MarketPlacePage({required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
final MarketPlaceViewModel marketPlaceViewModel;
final _scrollController = ScrollController();
@override
@ -75,14 +72,13 @@ class MarketPlacePage extends StatelessWidget {
),
);
}
// TODO: Remove ionia flow/files if we will discard it
void _navigatorToGiftCardsPage(BuildContext context) {
final walletType = dashboardViewModel.type;
switch (walletType) {
case WalletType.haven:
showPopUp<void>(
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
@ -92,14 +88,9 @@ class MarketPlacePage extends StatelessWidget {
buttonAction: () => Navigator.of(context).pop());
});
break;
default:
marketPlaceViewModel.isIoniaUserAuthenticated().then((value) {
if (value) {
Navigator.pushNamed(context, Routes.ioniaManageCardsPage);
return;
}
Navigator.of(context).pushNamed(Routes.ioniaWelcomePage);
});
default:
Navigator.of(context).pushNamed(Routes.ioniaWelcomePage);
}
}
}

View file

@ -28,18 +28,13 @@ class TransactionsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPress: () => dashboardViewModel.balanceViewModel.isReversing =
!dashboardViewModel.balanceViewModel.isReversing,
onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing =
!dashboardViewModel.balanceViewModel.isReversing,
child: Container(
color: ResponsiveLayoutUtil.instance.isMobile
? null
: Theme.of(context).colorScheme.background,
padding: EdgeInsets.only(top: 24, bottom: 24),
child: Column(
children: <Widget>[
return Container(
color: ResponsiveLayoutUtil.instance.isMobile(context)
? null
: Theme.of(context).colorScheme.background,
padding: EdgeInsets.only(top: 24, bottom: 24),
child: Column(
children: <Widget>[
Observer(builder: (_) {
final status = dashboardViewModel.status;
if (status is SyncingSyncStatus) {
@ -57,97 +52,87 @@ class TransactionsPage extends StatelessWidget {
return Container();
}
}),
HeaderRow(dashboardViewModel: dashboardViewModel),
Expanded(child: Observer(builder: (_) {
final items = dashboardViewModel.items;
HeaderRow(dashboardViewModel: dashboardViewModel),
Expanded(child: Observer(builder: (_) {
final items = dashboardViewModel.items;
return items.isNotEmpty
? ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return items.isNotEmpty
? ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (item is DateSectionItem) {
return DateSectionRaw(date: item.date);
}
if (item is DateSectionItem) {
return DateSectionRaw(date: item.date);
}
if (item is TransactionListItem) {
final transaction = item.transaction;
if (item is TransactionListItem) {
final transaction = item.transaction;
return Observer(
builder: (_) => TransactionRow(
onTap: () => Navigator.of(context).pushNamed(
Routes.transactionDetails,
arguments: transaction),
direction: transaction.direction,
formattedDate: DateFormat('HH:mm')
.format(transaction.date),
formattedAmount: item.formattedCryptoAmount,
formattedFiatAmount: dashboardViewModel
.balanceViewModel.isFiatDisabled
? ''
: item.formattedFiatAmount,
isPending: transaction.isPending,
title: item.formattedTitle +
item.formattedStatus));
}
return Observer(
builder: (_) => TransactionRow(
onTap: () => Navigator.of(context)
.pushNamed(Routes.transactionDetails, arguments: transaction),
direction: transaction.direction,
formattedDate: DateFormat('HH:mm').format(transaction.date),
formattedAmount: item.formattedCryptoAmount,
formattedFiatAmount:
dashboardViewModel.balanceViewModel.isFiatDisabled
? ''
: item.formattedFiatAmount,
isPending: transaction.isPending,
title: item.formattedTitle + item.formattedStatus));
}
if (item is AnonpayTransactionListItem) {
final transactionInfo = item.transaction;
if (item is AnonpayTransactionListItem) {
final transactionInfo = item.transaction;
return AnonpayTransactionRow(
onTap: () => Navigator.of(context).pushNamed(
Routes.anonPayDetailsPage,
arguments: transactionInfo),
currency: transactionInfo.fiatAmount != null
? transactionInfo.fiatEquiv ?? ''
: CryptoCurrency.fromFullName(
transactionInfo.coinTo)
.name
.toUpperCase(),
provider: transactionInfo.provider,
amount: transactionInfo.fiatAmount?.toString() ??
(transactionInfo.amountTo?.toString() ?? ''),
createdAt: DateFormat('HH:mm')
.format(transactionInfo.createdAt),
);
}
return AnonpayTransactionRow(
onTap: () => Navigator.of(context)
.pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
currency: transactionInfo.fiatAmount != null
? transactionInfo.fiatEquiv ?? ''
: CryptoCurrency.fromFullName(transactionInfo.coinTo)
.name
.toUpperCase(),
provider: transactionInfo.provider,
amount: transactionInfo.fiatAmount?.toString() ??
(transactionInfo.amountTo?.toString() ?? ''),
createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
);
}
if (item is TradeListItem) {
final trade = item.trade;
if (item is TradeListItem) {
final trade = item.trade;
return Observer(
builder: (_) => TradeRow(
onTap: () => Navigator.of(context).pushNamed(
Routes.tradeDetails,
arguments: trade),
provider: trade.provider,
from: trade.from,
to: trade.to,
return Observer(
builder: (_) => TradeRow(
onTap: () => Navigator.of(context)
.pushNamed(Routes.tradeDetails, arguments: trade),
provider: trade.provider,
from: trade.from,
to: trade.to,
createdAtFormattedDate: trade.createdAt != null
? DateFormat('HH:mm').format(trade.createdAt!)
: null,
formattedAmount: item.tradeFormattedAmount));
}
if (item is OrderListItem) {
final order = item.order;
return Observer(
builder: (_) => OrderRow(
onTap: () => Navigator.of(context)
.pushNamed(Routes.orderDetails, arguments: order),
provider: order.provider,
from: order.from!,
to: order.to!,
createdAtFormattedDate:
trade.createdAt != null
? DateFormat('HH:mm')
.format(trade.createdAt!)
: null,
formattedAmount: item.tradeFormattedAmount));
}
if (item is OrderListItem) {
final order = item.order;
return Observer(
builder: (_) => OrderRow(
onTap: () => Navigator.of(context)
.pushNamed(Routes.orderDetails,
arguments: order),
provider: order.provider,
from: order.from!,
to: order.to!,
createdAtFormattedDate: DateFormat('HH:mm')
.format(order.createdAt),
formattedAmount: item.orderFormattedAmount,
));
}
DateFormat('HH:mm').format(order.createdAt),
formattedAmount: item.orderFormattedAmount,
));
}
return Container(color: Colors.transparent, height: 1);
})

View file

@ -127,7 +127,7 @@ class ExchangePage extends BasePage {
final _closeButton =
currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics(
child: SizedBox(
@ -576,8 +576,8 @@ class ExchangePage extends BasePage {
alertContent: S.of(context).low_fee_alert,
leftButtonText: S.of(context).ignor,
rightButtonText: S.of(context).use_suggested,
actionLeftButton: () => Navigator.of(dialogContext).pop(false),
actionRightButton: () => Navigator.of(dialogContext).pop(true));
actionLeftButton: () => Navigator.of(context).pop(false),
actionRightButton: () => Navigator.of(context).pop(true));
}) ??
false;
if (confirmed) {
@ -705,7 +705,7 @@ class ExchangePage extends BasePage {
},
));
if (ResponsiveLayoutUtil.instance.isMobile) {
if (ResponsiveLayoutUtil.instance.isMobile(context)) {
return MobileExchangeCardsSection(
firstExchangeCard: firstExchangeCard,
secondExchangeCard: secondExchangeCard,

View file

@ -4,11 +4,14 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:mobx/mobx.dart';
class IoniaWelcomePage extends BasePage {
IoniaWelcomePage();
IoniaWelcomePage(this._cardsListViewModel);
@override
Widget middle(BuildContext context) {
@ -20,8 +23,15 @@ class IoniaWelcomePage extends BasePage {
);
}
final IoniaGiftCardsListViewModel _cardsListViewModel;
@override
Widget body(BuildContext context) {
reaction((_) => _cardsListViewModel.isLoggedIn, (bool state) {
if (state) {
Navigator.pushReplacementNamed(context, Routes.ioniaManageCardsPage);
}
});
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
@ -29,7 +39,7 @@ class IoniaWelcomePage extends BasePage {
children: [
Column(
children: [
SizedBox(height: 90),
SizedBox(height: 100),
Text(
S.of(context).about_cake_pay,
style: TextStyle(

View file

@ -23,7 +23,7 @@ import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
class IoniaManageCardsPage extends BasePage {
IoniaManageCardsPage(this._cardsListViewModel): searchFocusNode = FocusNode() {
IoniaManageCardsPage(this._cardsListViewModel) {
_searchController.addListener(() {
if (_searchController.text != _cardsListViewModel.searchString) {
_searchDebounce.run(() {
@ -35,7 +35,6 @@ class IoniaManageCardsPage extends BasePage {
_cardsListViewModel.getMerchants();
}
final FocusNode searchFocusNode;
final IoniaGiftCardsListViewModel _cardsListViewModel;
final _searchDebounce = Debounce(Duration(milliseconds: 500));
@ -111,7 +110,6 @@ class IoniaManageCardsPage extends BasePage {
Expanded(
child: _SearchWidget(
controller: _searchController,
focusNode: searchFocusNode,
)),
SizedBox(width: 10),
filterButton
@ -229,10 +227,9 @@ class _SearchWidget extends StatelessWidget {
const _SearchWidget({
Key? key,
required this.controller,
required this.focusNode,
}) : super(key: key);
final TextEditingController controller;
final FocusNode focusNode;
@override
Widget build(BuildContext context) {
final searchIcon = ExcludeSemantics(
@ -246,7 +243,6 @@ class _SearchWidget extends StatelessWidget {
);
return TextField(
focusNode: focusNode,
style: TextStyle(color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
controller: controller,
decoration: InputDecoration(

View file

@ -52,14 +52,18 @@ class _WalletNameFormState extends State<WalletNameForm> {
_WalletNameFormState(this._walletNewVM)
: _formKey = GlobalKey<FormState>(),
_languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(),
_controller = TextEditingController();
_nameController = TextEditingController(),
_passwordController = _walletNewVM.hasWalletPassword ? TextEditingController() : null,
_repeatedPasswordController = _walletNewVM.hasWalletPassword ? TextEditingController() : null;
static const aspectRatioImage = 1.22;
final GlobalKey<FormState> _formKey;
final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
final WalletNewVM _walletNewVM;
final TextEditingController _controller;
final TextEditingController _nameController;
final TextEditingController? _passwordController;
final TextEditingController? _repeatedPasswordController;
ReactionDisposer? _stateReaction;
@override
@ -110,12 +114,11 @@ class _WalletNameFormState extends State<WalletNameForm> {
padding: EdgeInsets.only(top: 24),
child: Form(
key: _formKey,
child: Stack(
alignment: Alignment.centerRight,
child: Column(
children: [
TextFormField(
onChanged: (value) => _walletNewVM.name = value,
controller: _controller,
controller: _nameController,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
@ -144,10 +147,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
FocusManager.instance.primaryFocus?.unfocus();
setState(() {
_controller.text = rName;
_nameController.text = rName;
_walletNewVM.name = rName;
_controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length));
_nameController.selection = TextSelection.fromPosition(
TextPosition(offset: _nameController.text.length));
});
},
icon: Container(
@ -168,6 +171,71 @@ class _WalletNameFormState extends State<WalletNameForm> {
),
validator: WalletNameValidator(),
),
if (_walletNewVM.hasWalletPassword)
...[TextFormField(
onChanged: (value) => _walletNewVM.walletPassword = value,
controller: _passwordController,
textAlign: TextAlign.center,
obscureText: true,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w600,
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
decoration: InputDecoration(
hintStyle: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.color!),
hintText: S.of(context).password,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentTextTheme!
.headline2!
.decorationColor!,
width: 1.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentTextTheme!
.headline2!
.decorationColor!,
width: 1.0),
)
)
),
TextFormField(
onChanged: (value) => _walletNewVM.repeatedWalletPassword = value,
controller: _repeatedPasswordController,
textAlign: TextAlign.center,
obscureText: true,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w600,
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
decoration: InputDecoration(
hintStyle: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.color!),
hintText: S.of(context).repeate_wallet_password,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentTextTheme!
.headline2!
.decorationColor!,
width: 1.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentTextTheme!
.headline2!
.decorationColor!,
width: 1.0),
)
)
)],
],
),
),

View file

@ -10,7 +10,6 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option
import 'package:cake_wallet/src/screens/receive/widgets/anonpay_input_form.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:flutter/material.dart';
@ -29,7 +28,8 @@ class AnonPayInvoicePage extends BasePage {
AnonPayInvoicePage(
this.anonInvoicePageViewModel,
this.receiveOptionViewModel,
) : _amountFocusNode = FocusNode() {}
) : _amountFocusNode = FocusNode() {
}
final _nameController = TextEditingController();
final _emailController = TextEditingController();
@ -71,22 +71,15 @@ class AnonPayInvoicePage extends BasePage {
anonInvoicePageViewModel.reset();
});
Future<bool> _onNavigateBack(BuildContext context) async {
onClose(context);
return false;
}
@override
Widget body(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context));
return WillPopScope(
onWillPop: () => _onNavigateBack(context),
child: KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
@ -99,7 +92,7 @@ class AnonPayInvoicePage extends BasePage {
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Container(
decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
decoration: DeviceInfo.instance.isMobile ? BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(
@ -110,76 +103,74 @@ class AnonPayInvoicePage extends BasePage {
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
) : null,
child: Observer(builder: (_) {
return Padding(
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
child: AnonInvoiceForm(
nameController: _nameController,
descriptionController: _descriptionController,
amountController: _amountController,
emailController: _emailController,
depositAmountFocus: _amountFocusNode,
formKey: _formKey,
isInvoice: receiveOptionViewModel.selectedReceiveOption ==
ReceivePageOption.anonPayInvoice,
anonInvoicePageViewModel: anonInvoicePageViewModel,
),
);
}),
),
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Observer(builder: (_) {
final isInvoice =
receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice;
return Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 15),
child: Center(
child: Text(
isInvoice
? S.of(context).anonpay_description("an invoice", "pay")
: S.of(context).anonpay_description("a donation link", "donate"),
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).extension<ExchangePageTheme>()!.receiveAmountColor,
fontWeight: FontWeight.w500,
fontSize: 12),
),
),
),
LoadingPrimaryButton(
text: isInvoice
? S.of(context).create_invoice
: S.of(context).create_donation_link,
onPressed: () {
FocusScope.of(context).unfocus();
anonInvoicePageViewModel.setRequestParams(
inputAmount: _amountController.text,
inputName: _nameController.text,
inputEmail: _emailController.text,
inputDescription: _descriptionController.text,
);
if (anonInvoicePageViewModel.receipientEmail.isNotEmpty &&
_formKey.currentState != null &&
!_formKey.currentState!.validate()) {
return;
}
if (isInvoice) {
anonInvoicePageViewModel.createInvoice();
} else {
anonInvoicePageViewModel.generateDonationLink();
}
},
color: Theme.of(context).primaryColor,
textColor: Colors.white,
isLoading: anonInvoicePageViewModel.state is IsExecutingState,
),
],
) : null,
child: Observer(builder: (_) {
return Padding(
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
child: AnonInvoiceForm(
nameController: _nameController,
descriptionController: _descriptionController,
amountController: _amountController,
emailController: _emailController,
depositAmountFocus: _amountFocusNode,
formKey: _formKey,
isInvoice: receiveOptionViewModel.selectedReceiveOption ==
ReceivePageOption.anonPayInvoice,
anonInvoicePageViewModel: anonInvoicePageViewModel,
),
);
}),
),
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Observer(builder: (_) {
final isInvoice =
receiveOptionViewModel.selectedReceiveOption == ReceivePageOption.anonPayInvoice;
return Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 15),
child: Center(
child: Text(
isInvoice
? S.of(context).anonpay_description("an invoice", "pay")
: S.of(context).anonpay_description("a donation link", "donate"),
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).extension<ExchangePageTheme>()!.receiveAmountColor,
fontWeight: FontWeight.w500,
fontSize: 12),
),
),
),
LoadingPrimaryButton(
text:
isInvoice ? S.of(context).create_invoice : S.of(context).create_donation_link,
onPressed: () {
FocusScope.of(context).unfocus();
anonInvoicePageViewModel.setRequestParams(
inputAmount: _amountController.text,
inputName: _nameController.text,
inputEmail: _emailController.text,
inputDescription: _descriptionController.text,
);
if (anonInvoicePageViewModel.receipientEmail.isNotEmpty &&
_formKey.currentState != null &&
!_formKey.currentState!.validate()) {
return;
}
if (isInvoice) {
anonInvoicePageViewModel.createInvoice();
} else {
anonInvoicePageViewModel.generateDonationLink();
}
},
color: Theme.of(context).primaryColor,
textColor: Colors.white,
isLoading: anonInvoicePageViewModel.state is IsExecutingState,
),
],
);
}),
),
),
);

View file

@ -1,5 +1,4 @@
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/currency.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -13,8 +12,7 @@ class CurrencyInputField extends StatelessWidget {
required this.onTapPicker,
required this.selectedCurrency,
this.focusNode,
required this.controller,
required this.isLight,
required this.controller, required this.isLight,
});
final Function() onTapPicker;
@ -30,9 +28,7 @@ class CurrencyInputField extends StatelessWidget {
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
height: 8,
);
// This magic number for wider screen sets the text input focus at center of the inputfield
final _width =
ResponsiveLayoutUtil.instance.isMobile ? MediaQuery.of(context).size.width : 500;
final _width = MediaQuery.of(context).size.width;
return Column(
children: [
@ -46,12 +42,10 @@ class CurrencyInputField extends StatelessWidget {
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))],
hintText: '0.000',
placeholderTextStyle: isLight
? null
: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
fontWeight: FontWeight.w600,
),
placeholderTextStyle: isLight ? null : TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
fontWeight: FontWeight.w600,
),
borderColor: Theme.of(context).extension<PickerTheme>()!.dividerColor,
textColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
textStyle: TextStyle(

View file

@ -15,19 +15,25 @@ class WalletRestoreFromKeysFrom extends StatefulWidget {
required this.walletRestoreViewModel,
required this.displayPrivateKeyField,
required this.onHeightOrDateEntered,
required this.displayWalletPassword,
required this.onRepeatedPasswordChange,
this.onPasswordChange,
Key? key,
}) : super(key: key);
final Function(bool) onHeightOrDateEntered;
final WalletRestoreViewModel walletRestoreViewModel;
final bool displayPrivateKeyField;
final bool displayWalletPassword;
final void Function(String)? onPasswordChange;
final void Function(String)? onRepeatedPasswordChange;
@override
WalletRestoreFromKeysFromState createState() => WalletRestoreFromKeysFromState();
WalletRestoreFromKeysFromState createState() => WalletRestoreFromKeysFromState(displayWalletPassword: displayWalletPassword);
}
class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
WalletRestoreFromKeysFromState()
WalletRestoreFromKeysFromState({required bool displayWalletPassword})
: formKey = GlobalKey<FormState>(),
blockchainHeightKey = GlobalKey<BlockchainHeightState>(),
nameController = TextEditingController(),
@ -35,7 +41,9 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
viewKeyController = TextEditingController(),
spendKeyController = TextEditingController(),
privateKeyController = TextEditingController(),
nameTextEditingController = TextEditingController();
nameTextEditingController = TextEditingController(),
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null;
final GlobalKey<FormState> formKey;
final GlobalKey<BlockchainHeightState> blockchainHeightKey;
@ -45,9 +53,23 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
final TextEditingController spendKeyController;
final TextEditingController nameTextEditingController;
final TextEditingController privateKeyController;
final TextEditingController? passwordTextEditingController;
final TextEditingController? repeatedPasswordTextEditingController;
void Function()? passwordListener;
void Function()? repeatedPasswordListener;
@override
void initState() {
if (passwordTextEditingController != null) {
passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
passwordTextEditingController?.addListener(passwordListener!);
}
if (repeatedPasswordTextEditingController != null) {
repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
}
super.initState();
privateKeyController.addListener(() {
@ -57,6 +79,7 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
});
}
@override
void dispose() {
nameController.dispose();
@ -64,6 +87,14 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
viewKeyController.dispose();
spendKeyController.dispose();
privateKeyController.dispose();
passwordTextEditingController?.dispose();
if (passwordListener != null) {
passwordTextEditingController?.removeListener(passwordListener!);
}
if (repeatedPasswordListener != null) {
repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
}
super.dispose();
}
@ -111,6 +142,19 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
),
],
),
if (widget.displayWalletPassword)
...[Container(
padding: EdgeInsets.only(top: 20.0),
child: BaseTextFormField(
controller: passwordTextEditingController,
hintText: S.of(context).password,
obscureText: true)),
Container(
padding: EdgeInsets.only(top: 20.0),
child: BaseTextFormField(
controller: repeatedPasswordTextEditingController,
hintText: S.of(context).repeate_wallet_password,
obscureText: true))],
Container(height: 20),
_restoreFromKeysFormFields(),
],

View file

@ -19,46 +19,79 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
required this.displayLanguageSelector,
required this.displayBlockHeightSelector,
required this.type,
required this.displayWalletPassword,
this.blockHeightFocusNode,
this.onHeightOrDateEntered,
this.onSeedChange,
this.onLanguageChange})
this.onLanguageChange,
this.onPasswordChange,
this.onRepeatedPasswordChange})
: super(key: key);
final WalletType type;
final bool displayLanguageSelector;
final bool displayBlockHeightSelector;
final bool displayWalletPassword;
final FocusNode? blockHeightFocusNode;
final Function(bool)? onHeightOrDateEntered;
final void Function(String)? onSeedChange;
final void Function(String)? onLanguageChange;
final void Function(String)? onPasswordChange;
final void Function(String)? onRepeatedPasswordChange;
@override
WalletRestoreFromSeedFormState createState() =>
WalletRestoreFromSeedFormState('English');
WalletRestoreFromSeedFormState('English', displayWalletPassword: displayWalletPassword);
}
class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
WalletRestoreFromSeedFormState(this.language)
WalletRestoreFromSeedFormState(this.language, {required bool displayWalletPassword})
: seedWidgetStateKey = GlobalKey<SeedWidgetState>(),
blockchainHeightKey = GlobalKey<BlockchainHeightState>(),
formKey = GlobalKey<FormState>(),
languageController = TextEditingController(),
nameTextEditingController = TextEditingController();
nameTextEditingController = TextEditingController(),
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null;
final GlobalKey<SeedWidgetState> seedWidgetStateKey;
final GlobalKey<BlockchainHeightState> blockchainHeightKey;
final TextEditingController languageController;
final TextEditingController nameTextEditingController;
final TextEditingController? passwordTextEditingController;
final TextEditingController? repeatedPasswordTextEditingController;
final GlobalKey<FormState> formKey;
String language;
void Function()? passwordListener;
void Function()? repeatedPasswordListener;
@override
void initState() {
_setLanguageLabel(language);
if (passwordTextEditingController != null) {
passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
passwordTextEditingController?.addListener(passwordListener!);
}
if (repeatedPasswordTextEditingController != null) {
repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
}
super.initState();
}
@override
void dispose() {
if (passwordListener != null) {
passwordTextEditingController?.removeListener(passwordListener!);
}
if (repeatedPasswordListener != null) {
repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
@ -108,6 +141,15 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
language: language,
type: widget.type,
onSeedChange: widget.onSeedChange),
if (widget.displayWalletPassword)
...[BaseTextFormField(
controller: passwordTextEditingController,
hintText: S.of(context).password,
obscureText: true),
BaseTextFormField(
controller: repeatedPasswordTextEditingController,
hintText: S.of(context).repeate_wallet_password,
obscureText: true)],
if (widget.displayLanguageSelector)
GestureDetector(
onTap: () async {
@ -129,7 +171,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
focusNode: widget.blockHeightFocusNode,
key: blockchainHeightKey,
onHeightOrDateEntered: widget.onHeightOrDateEntered,
hasDatePicker: widget.type == WalletType.monero)
hasDatePicker: widget.type == WalletType.monero),
]));
}

View file

@ -63,13 +63,19 @@ class WalletRestorePage extends BasePage {
} else {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
}));
},
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword));
break;
case WalletRestoreMode.keys:
_pages.add(WalletRestoreFromKeysFrom(
key: walletRestoreFromKeysFormKey,
walletRestoreViewModel: walletRestoreViewModel,
displayPrivateKeyField: walletRestoreViewModel.hasRestoreFromPrivateKey,
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword,
onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
break;
default:
@ -118,6 +124,8 @@ class WalletRestorePage extends BasePage {
reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
walletRestoreViewModel.isButtonEnabled = false;
walletRestoreViewModel.walletPassword = null;
walletRestoreViewModel.repeatedWalletPassword = null;
walletRestoreFromSeedFormKey
.currentState!.blockchainHeightKey.currentState!.restoreHeightController.text = '';
@ -264,8 +272,6 @@ class WalletRestorePage extends BasePage {
}
void _confirmForm() {
// Dismissing all visible keyboard to provide context for navigation
FocusManager.instance.primaryFocus?.unfocus();
final formContext = walletRestoreViewModel.mode == WalletRestoreMode.seed
? walletRestoreFromSeedFormKey.currentContext
: walletRestoreFromKeysFormKey.currentContext;

View file

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/core/totp_request_details.dart';
import 'package:cake_wallet/utils/device_info.dart';

View file

@ -70,7 +70,7 @@ class SendPage extends BasePage {
? closeButtonImageDarkTheme
: closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics(
child: SizedBox(
@ -102,7 +102,7 @@ class SendPage extends BasePage {
double _sendCardHeight(BuildContext context) {
final double initialHeight = sendViewModel.hasCoinControl ? 490 : 465;
if (!ResponsiveLayoutUtil.instance.isMobile) {
if (!ResponsiveLayoutUtil.instance.isMobile(context)) {
return initialHeight - 66;
}
return initialHeight;
@ -363,14 +363,13 @@ class SendPage extends BasePage {
showErrorValidationAlert(context);
}
return;
}
return;
}
final notValidItems = sendViewModel.outputs
.where((item) =>
item.address.isEmpty ||
item.cryptoAmount.isEmpty)
.toList();
final notValidItems = sendViewModel.outputs
.where((item) =>
item.address.isEmpty || item.cryptoAmount.isEmpty)
.toList();
if (notValidItems.isNotEmpty) {
showErrorValidationAlert(context);
@ -428,54 +427,51 @@ class SendPage extends BasePage {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (context.mounted) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return ConfirmSendingAlert(
alertTitle: S.of(context).confirm_sending,
amount: S.of(context).send_amount,
amountValue:
sendViewModel.pendingTransaction!.amountFormatted,
fiatAmountValue:
sendViewModel.pendingTransactionFiatAmountFormatted,
fee: S.of(context).send_fee,
feeValue: sendViewModel.pendingTransaction!.feeFormatted,
feeFiatAmount: sendViewModel
.pendingTransactionFeeFiatAmountFormatted,
outputs: sendViewModel.outputs,
rightButtonText: S.of(context).ok,
leftButtonText: S.of(context).cancel,
actionRightButton: () {
Navigator.of(context).pop();
sendViewModel.commitTransaction();
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return Observer(builder: (_) {
final state = sendViewModel.state;
context: context,
builder: (BuildContext context) {
return ConfirmSendingAlert(
alertTitle: S.of(context).confirm_sending,
amount: S.of(context).send_amount,
amountValue:
sendViewModel.pendingTransaction!.amountFormatted,
fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted,
fee: S.of(context).send_fee,
feeValue: sendViewModel.pendingTransaction!.feeFormatted,
feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
outputs: sendViewModel.outputs,
rightButtonText: S.of(context).ok,
leftButtonText: S.of(context).cancel,
actionRightButton: () {
Navigator.of(context).pop();
sendViewModel.commitTransaction();
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return Observer(builder: (_) {
final state = sendViewModel.state;
if (state is FailureState) {
Navigator.of(context).pop();
if (state is FailureState) {
Navigator.of(context).pop();
}
if (state is TransactionCommitted) {
return AlertWithOneAction(
alertTitle: '',
alertContent: S.of(context).send_success(
sendViewModel.selectedCryptoCurrency.toString()),
buttonText: S.of(context).ok,
buttonAction: () {
Navigator.of(context).pop();
RequestReviewHandler.requestReview();
});
}
if (state is TransactionCommitted) {
return AlertWithOneAction(
alertTitle: '',
alertContent: S.of(context).send_success(
sendViewModel.selectedCryptoCurrency
.toString()),
buttonText: S.of(context).ok,
buttonAction: () {
Navigator.of(context).pop();
RequestReviewHandler.requestReview();
});
}
return Offstage();
});
return Offstage();
});
},
actionLeftButton: () => Navigator.of(context).pop());
});
});
},
actionLeftButton: () => Navigator.of(context).pop());
});
}
});
}
@ -529,18 +525,16 @@ class SendPage extends BasePage {
});
}
void presentCurrencyPicker(BuildContext context) async {
void presentCurrencyPicker(BuildContext context) async {
await showPopUp<CryptoCurrency>(
builder: (_) => Picker(
items: sendViewModel.currencies,
displayItem: (Object item) => item.toString(),
selectedAtIndex: sendViewModel.currencies
.indexOf(sendViewModel.selectedCryptoCurrency),
title: S.of(context).please_select,
mainAxisAlignment: MainAxisAlignment.center,
onItemSelected: (CryptoCurrency cur) =>
sendViewModel.selectedCryptoCurrency = cur,
),
items: sendViewModel.currencies,
displayItem: (Object item) => item.toString(),
selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
title: S.of(context).please_select,
mainAxisAlignment: MainAxisAlignment.center,
onItemSelected: (CryptoCurrency cur) => sendViewModel.selectedCryptoCurrency = cur,
),
context: context);
}
}

View file

@ -139,9 +139,9 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
child: Padding(
padding: EdgeInsets.fromLTRB(
24,
ResponsiveLayoutUtil.instance.isMobile ? 100 : 55,
ResponsiveLayoutUtil.instance.isMobile(context) ? 100 : 55,
24,
ResponsiveLayoutUtil.instance.isMobile ? 32 : 0,
ResponsiveLayoutUtil.instance.isMobile(context) ? 32 : 0,
),
child: SingleChildScrollView(
child: Observer(

Some files were not shown because too many files have changed in this diff Show more