mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-02-27 13:30:29 +00:00
Merge remote-tracking branch 'origin/linux/password-direct-input' into cw-linux
This commit is contained in:
parent
9999816850
commit
39d3499d07
195 changed files with 4103 additions and 1112 deletions
.gitignore.metadatabuild-guide-linux.mdcom.cakewallet.CakeWallet.yml
cw_bitcoin
lib
bitcoin_wallet.dartbitcoin_wallet_creation_credentials.dartbitcoin_wallet_service.dartelectrum_transaction_history.dartelectrum_wallet.dartelectrum_wallet_snapshot.dartencryption_file_utils.dartfile.dartlitecoin_wallet.dartlitecoin_wallet_service.dart
pubspec.lockpubspec.yamlcw_core
lib
cake_hive.darterc20_token.darthive_type_ids.dartnode.dartpathForWallet.dartroot_dir.dartsec_random_native.dartunspent_coins_info.dartwallet_base.dartwallet_info.dartwallet_type.dart
pubspec.lockcw_ethereum
lib
encryption_file_utils.dartethereum_transaction_history.dartethereum_wallet.dartethereum_wallet_creation_credentials.dartethereum_wallet_service.dart
pubspec.yamlcw_monero
.metadata
example/linux
ios/Classes
lib
linux
macos/Classes
pubspec.yamlios
lib
anonpay
bitcoin
buy
core
auth_service.dartbackup_service.dartkey_service.dartwallet_creation_service.dartwallet_loading_service.dart
di.dartentities
contact.dartdefault_settings_migration.dartfs_migration.dartget_encryption_key.dartlanguage_service.dartload_current_wallet.darttemplate.darttransaction_description.dart
ethereum
exchange
ionia
main.dartreactions
router.dartroutes.dartsrc/screens
auth
buy
dashboard
desktop_widgets
widgets
ionia/auth
new_wallet
receive/widgets
restore
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -18,6 +18,9 @@ migration:
|
|||
- platform: macos
|
||||
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||
- platform: linux
|
||||
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||
|
||||
# User provided section
|
||||
|
||||
|
|
195
build-guide-linux.md
Normal file
195
build-guide-linux.md
Normal file
|
@ -0,0 +1,195 @@
|
|||
# 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.7.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`
|
||||
|
||||
|
||||
> ### If you get the error like:
|
||||
> ```
|
||||
> The lower bound of "sdk: '>=2.0.0-dev.68.0 <3.0.0'" must be 2.12.0 or higher to enable null safety.
|
||||
> ```
|
||||
>
|
||||
> #### Downgrade Flutter to version 3.7.x
|
||||
> Make sure that Flutter is reverted back to version 3.7.x (which would automatically revert Dart to 2.18 or 2.19)
|
||||
>
|
||||
> In your Linux terminal, find where your Flutter SDK is installed with:
|
||||
>
|
||||
> ```
|
||||
> $ which flutter
|
||||
> ```
|
||||
>
|
||||
> Proceed to the Flutter SDK path:
|
||||
>
|
||||
> ```
|
||||
> $ cd user/snap/flutter/common/flutter
|
||||
> ```
|
||||
>
|
||||
> In the Flutter SDK directory, revert to a 3.7.x version (I used 3.7.12):
|
||||
>
|
||||
>
|
||||
> ```
|
||||
> $ git checkout 3.7.12
|
||||
> ```
|
||||
> Then re-configure Cake Wallet's 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.
|
35
com.cakewallet.CakeWallet.yml
Normal file
35
com.cakewallet.CakeWallet.yml
Normal 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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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';
|
||||
|
@ -12,14 +13,13 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class BitcoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials,
|
||||
BitcoinRestoreWalletFromWIFCredentials> {
|
||||
BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
|
||||
class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromWIFCredentials> {
|
||||
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 +30,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;
|
||||
|
@ -42,33 +43,37 @@ class BitcoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<BitcoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await BitcoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
password: password,
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||
await wallet.init();
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> remove(String wallet) async {
|
||||
File(await pathForWalletDir(name: wallet, type: getType()))
|
||||
.delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
await walletInfoSource.delete(walletInfo.key);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rename(String currentName, String password, String newName) async {
|
||||
final currentWalletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||
final currentWalletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||
final currentWallet = await BitcoinWalletBase.open(
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
|
@ -80,13 +85,11 @@ class BitcoinWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<BitcoinWallet> restoreFromKeys(
|
||||
BitcoinRestoreWalletFromWIFCredentials credentials) async =>
|
||||
Future<BitcoinWallet> restoreFromKeys(BitcoinRestoreWalletFromWIFCredentials credentials) async =>
|
||||
throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<BitcoinWallet> restoreFromSeed(
|
||||
BitcoinRestoreWalletFromSeedCredentials credentials) async {
|
||||
Future<BitcoinWallet> restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials) async {
|
||||
if (!validateMnemonic(credentials.mnemonic)) {
|
||||
throw BitcoinMnemonicIsIncorrectException();
|
||||
}
|
||||
|
@ -95,7 +98,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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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>;
|
||||
}
|
||||
|
||||
|
@ -85,5 +86,4 @@ abstract class ElectrumTransactionHistoryBase
|
|||
|
||||
void _update(ElectrumTransactionInfo transaction) =>
|
||||
transactions[transaction.id] = transaction;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
42
cw_bitcoin/lib/encryption_file_utils.dart
Normal file
42
cw_bitcoin/lib/encryption_file_utils.dart
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
@ -12,14 +13,13 @@ import 'package:cw_core/wallet_info.dart';
|
|||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class LitecoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials,
|
||||
BitcoinRestoreWalletFromWIFCredentials> {
|
||||
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
|
||||
class LitecoinWalletService extends WalletService<BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromWIFCredentials> {
|
||||
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 +30,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();
|
||||
|
||||
|
@ -43,33 +44,37 @@ class LitecoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<LitecoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await LitecoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
password: password,
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||
await wallet.init();
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> remove(String wallet) async {
|
||||
File(await pathForWalletDir(name: wallet, type: getType()))
|
||||
.delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
await walletInfoSource.delete(walletInfo.key);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rename(String currentName, String password, String newName) async {
|
||||
final currentWalletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||
final currentWalletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||
final currentWallet = await LitecoinWalletBase.open(
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
|
@ -96,7 +101,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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -27,6 +27,11 @@ 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:
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:hive/src/hive_impl.dart';
|
||||
|
||||
final HiveInterface CakeHive = HiveImpl();
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'erc20_token.g.dart';
|
||||
|
@ -54,7 +53,7 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin {
|
|||
iconPath: icon,
|
||||
);
|
||||
|
||||
static const typeId = ERC20_TOKEN_TYPE_ID;
|
||||
static const typeId = 12;
|
||||
static const boxName = 'Erc20Tokens';
|
||||
|
||||
@override
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
const CONTACT_TYPE_ID = 0;
|
||||
const NODE_TYPE_ID = 1;
|
||||
const TRANSACTION_TYPE_ID = 2;
|
||||
const TRADE_TYPE_ID = 3;
|
||||
const WALLET_INFO_TYPE_ID = 4;
|
||||
const WALLET_TYPE_TYPE_ID = 5;
|
||||
const TEMPLATE_TYPE_ID = 6;
|
||||
const EXCHANGE_TEMPLATE_TYPE_ID = 7;
|
||||
const ORDER_TYPE_ID = 8;
|
||||
const UNSPENT_COINS_INFO_TYPE_ID = 9;
|
||||
const ANONPAY_INVOICE_INFO_TYPE_ID = 10;
|
||||
|
||||
const ERC20_TOKEN_TYPE_ID = 12;
|
|
@ -3,7 +3,6 @@ import 'package:cw_core/keyable.dart';
|
|||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:http/io_client.dart' as ioc;
|
||||
|
||||
|
@ -38,7 +37,7 @@ class Node extends HiveObject with Keyable {
|
|||
trusted = map['trusted'] as bool? ?? false,
|
||||
socksProxyAddress = map['socksProxyPort'] as String?;
|
||||
|
||||
static const typeId = NODE_TYPE_ID;
|
||||
static const typeId = 1;
|
||||
static const boxName = 'Nodes';
|
||||
|
||||
@HiveField(0, defaultValue: '')
|
||||
|
|
|
@ -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
26
cw_core/lib/root_dir.dart
Normal 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;
|
||||
}
|
|
@ -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([]);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'unspent_coins_info.g.dart';
|
||||
|
@ -17,7 +16,7 @@ class UnspentCoinsInfo extends HiveObject {
|
|||
this.keyImage = null
|
||||
});
|
||||
|
||||
static const typeId = UNSPENT_COINS_INFO_TYPE_ID;
|
||||
static const typeId = 9;
|
||||
static const boxName = 'Unspent';
|
||||
static const boxKey = 'unspentBoxKey';
|
||||
|
||||
|
@ -51,4 +50,4 @@ class UnspentCoinsInfo extends HiveObject {
|
|||
String get note => noteRaw ?? '';
|
||||
|
||||
set note(String value) => noteRaw = value;
|
||||
}
|
||||
}
|
|
@ -74,6 +74,8 @@ abstract class WalletBase<
|
|||
|
||||
Future<void> changePassword(String password);
|
||||
|
||||
String get password;
|
||||
|
||||
Future<void>? updateBalance();
|
||||
|
||||
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => null;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'dart:async';
|
||||
|
||||
part 'wallet_info.g.dart';
|
||||
|
||||
|
@ -30,7 +30,7 @@ class WalletInfo extends HiveObject {
|
|||
yatEid, yatLastUsedAddressRaw, showIntroCakePayCard);
|
||||
}
|
||||
|
||||
static const typeId = WALLET_INFO_TYPE_ID;
|
||||
static const typeId = 4;
|
||||
static const boxName = 'WalletInfo';
|
||||
|
||||
@HiveField(0, defaultValue: '')
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'wallet_type.g.dart';
|
||||
|
@ -11,8 +10,9 @@ const walletTypes = [
|
|||
WalletType.haven,
|
||||
WalletType.ethereum,
|
||||
];
|
||||
const walletTypeTypeId = 5;
|
||||
|
||||
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
|
||||
@HiveType(typeId: walletTypeTypeId)
|
||||
enum WalletType {
|
||||
@HiveField(0)
|
||||
monero,
|
||||
|
|
|
@ -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: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.10.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: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
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: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
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: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
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: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.17.0"
|
||||
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: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
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: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.13"
|
||||
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: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
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: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
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: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.16"
|
||||
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:
|
||||
|
|
42
cw_ethereum/lib/encryption_file_utils.dart
Normal file
42
cw_ethereum/lib/encryption_file_utils.dart
Normal file
|
@ -0,0 +1,42 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:cw_ethereum/file.dart' as ef;
|
||||
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 ef.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 ef.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);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||
import 'dart:core';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_ethereum/file.dart';
|
||||
import 'package:cw_ethereum/encryption_file_utils.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_ethereum/ethereum_transaction_info.dart';
|
||||
|
@ -15,12 +15,16 @@ class EthereumTransactionHistory = EthereumTransactionHistoryBase with _$Ethereu
|
|||
|
||||
abstract class EthereumTransactionHistoryBase
|
||||
extends TransactionHistoryBase<EthereumTransactionInfo> with Store {
|
||||
EthereumTransactionHistoryBase({required this.walletInfo, required String password})
|
||||
: _password = password {
|
||||
EthereumTransactionHistoryBase({
|
||||
required this.walletInfo,
|
||||
required String password,
|
||||
required this.encryptionFileUtils,
|
||||
}) : _password = password {
|
||||
transactions = ObservableMap<String, EthereumTransactionInfo>();
|
||||
}
|
||||
|
||||
final WalletInfo walletInfo;
|
||||
final EncryptionFileUtils encryptionFileUtils;
|
||||
String _password;
|
||||
|
||||
Future<void> init() async => await _load();
|
||||
|
@ -31,7 +35,7 @@ abstract class EthereumTransactionHistoryBase
|
|||
final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||
final path = '$dirPath/$transactionsHistoryFileName';
|
||||
final data = json.encode({'transactions': transactions});
|
||||
await writeData(path: path, password: _password, data: data);
|
||||
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
||||
} catch (e, s) {
|
||||
print('Error while save ethereum transaction history: ${e.toString()}');
|
||||
print(s);
|
||||
|
@ -48,7 +52,7 @@ abstract class EthereumTransactionHistoryBase
|
|||
Future<Map<String, dynamic>> _read() async {
|
||||
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);
|
||||
if (content.isEmpty) {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'dart:io';
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/cake_hive.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
|
@ -15,6 +14,7 @@ import 'package:cw_core/wallet_addresses.dart';
|
|||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_ethereum/default_erc20_tokens.dart';
|
||||
import 'package:cw_ethereum/encryption_file_utils.dart';
|
||||
import 'package:cw_ethereum/erc20_balance.dart';
|
||||
import 'package:cw_ethereum/ethereum_client.dart';
|
||||
import 'package:cw_ethereum/ethereum_exceptions.dart';
|
||||
|
@ -47,22 +47,28 @@ abstract class EthereumWalletBase
|
|||
String? mnemonic,
|
||||
String? privateKey,
|
||||
required String password,
|
||||
required EncryptionFileUtils encryptionFileUtils,
|
||||
ERC20Balance? initialBalance,
|
||||
}) : syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
_mnemonic = mnemonic,
|
||||
_hexPrivateKey = privateKey,
|
||||
_isTransactionUpdating = false,
|
||||
_encryptionFileUtils = encryptionFileUtils,
|
||||
_client = EthereumClient(),
|
||||
walletAddresses = EthereumWalletAddresses(walletInfo),
|
||||
balance = ObservableMap<CryptoCurrency, ERC20Balance>.of(
|
||||
{CryptoCurrency.eth: initialBalance ?? ERC20Balance(BigInt.zero)}),
|
||||
super(walletInfo) {
|
||||
this.walletInfo = walletInfo;
|
||||
transactionHistory = EthereumTransactionHistory(walletInfo: walletInfo, password: password);
|
||||
transactionHistory = EthereumTransactionHistory(
|
||||
walletInfo: walletInfo,
|
||||
password: password,
|
||||
encryptionFileUtils: encryptionFileUtils,
|
||||
);
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(Erc20Token.typeId)) {
|
||||
CakeHive.registerAdapter(Erc20TokenAdapter());
|
||||
if (!Hive.isAdapterRegistered(Erc20Token.typeId)) {
|
||||
Hive.registerAdapter(Erc20TokenAdapter());
|
||||
}
|
||||
|
||||
_sharedPrefs.complete(SharedPreferences.getInstance());
|
||||
|
@ -72,6 +78,8 @@ abstract class EthereumWalletBase
|
|||
final String? _hexPrivateKey;
|
||||
final String _password;
|
||||
|
||||
final EncryptionFileUtils _encryptionFileUtils;
|
||||
|
||||
late final Box<Erc20Token> erc20TokensBox;
|
||||
|
||||
late final EthPrivateKey _ethPrivateKey;
|
||||
|
@ -99,7 +107,7 @@ abstract class EthereumWalletBase
|
|||
Completer<SharedPreferences> _sharedPrefs = Completer();
|
||||
|
||||
Future<void> init() async {
|
||||
erc20TokensBox = await CakeHive.openBox<Erc20Token>(Erc20Token.boxName);
|
||||
erc20TokensBox = await Hive.openBox<Erc20Token>(Erc20Token.boxName);
|
||||
await walletAddresses.init();
|
||||
await transactionHistory.init();
|
||||
_ethPrivateKey = await getPrivateKey(
|
||||
|
@ -301,7 +309,7 @@ abstract class EthereumWalletBase
|
|||
Future<void> save() async {
|
||||
await walletAddresses.updateAddressesInBox();
|
||||
final path = await makePath();
|
||||
await write(path: path, password: _password, data: toJSON());
|
||||
await _encryptionFileUtils.write(path: path, password: _password, data: toJSON());
|
||||
await transactionHistory.save();
|
||||
}
|
||||
|
||||
|
@ -344,9 +352,10 @@ abstract class EthereumWalletBase
|
|||
required String name,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required EncryptionFileUtils encryptionFileUtils,
|
||||
}) async {
|
||||
final path = await pathForWallet(name: name, type: walletInfo.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 mnemonic = data['mnemonic'] as String?;
|
||||
final privateKey = data['private_key'] as String?;
|
||||
|
@ -358,6 +367,7 @@ abstract class EthereumWalletBase
|
|||
mnemonic: mnemonic,
|
||||
privateKey: privateKey,
|
||||
initialBalance: balance,
|
||||
encryptionFileUtils: encryptionFileUtils,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -502,4 +512,7 @@ abstract class EthereumWalletBase
|
|||
_transactionsUpdateTimer?.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String get password => _password;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ import 'package:cw_core/wallet_credentials.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
class EthereumNewWalletCredentials extends WalletCredentials {
|
||||
EthereumNewWalletCredentials({required String name, WalletInfo? walletInfo})
|
||||
: super(name: name, walletInfo: walletInfo);
|
||||
EthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
|
||||
: super(name: name, walletInfo: walletInfo, password: password);
|
||||
}
|
||||
|
||||
class EthereumRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:cw_core/wallet_base.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_service.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_ethereum/encryption_file_utils.dart';
|
||||
import 'package:cw_ethereum/ethereum_mnemonics.dart';
|
||||
import 'package:cw_ethereum/ethereum_wallet.dart';
|
||||
import 'package:cw_ethereum/ethereum_wallet_creation_credentials.dart';
|
||||
|
@ -14,9 +15,10 @@ import 'package:collection/collection.dart';
|
|||
|
||||
class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
||||
EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromPrivateKey> {
|
||||
EthereumWalletService(this.walletInfoSource);
|
||||
EthereumWalletService(this.walletInfoSource, this.isDirect);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final bool isDirect;
|
||||
|
||||
@override
|
||||
Future<EthereumWallet> create(EthereumNewWalletCredentials credentials) async {
|
||||
|
@ -25,6 +27,7 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
walletInfo: credentials.walletInfo!,
|
||||
mnemonic: mnemonic,
|
||||
password: credentials.password!,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await wallet.init();
|
||||
|
@ -49,6 +52,7 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
name: name,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await wallet.init();
|
||||
|
@ -60,8 +64,8 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
@override
|
||||
Future<void> remove(String wallet) async {
|
||||
File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
await walletInfoSource.delete(walletInfo.key);
|
||||
}
|
||||
|
||||
|
@ -91,6 +95,7 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
password: credentials.password!,
|
||||
mnemonic: credentials.mnemonic,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await wallet.init();
|
||||
|
@ -105,7 +110,11 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
final currentWalletInfo = walletInfoSource.values
|
||||
.firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||
final currentWallet = await EthereumWalletBase.open(
|
||||
password: password, name: currentName, walletInfo: currentWalletInfo);
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
|
|
|
@ -23,6 +23,11 @@ dependencies:
|
|||
shared_preferences: ^2.0.15
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
cake_backup:
|
||||
git:
|
||||
url: https://github.com/cake-tech/cake_backup.git
|
||||
ref: main
|
||||
version: 1.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -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
1
cw_monero/example/linux/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
flutter/ephemeral
|
138
cw_monero/example/linux/CMakeLists.txt
Normal file
138
cw_monero/example/linux/CMakeLists.txt
Normal 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()
|
88
cw_monero/example/linux/flutter/CMakeLists.txt
Normal file
88
cw_monero/example/linux/flutter/CMakeLists.txt
Normal 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}
|
||||
)
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
24
cw_monero/example/linux/flutter/generated_plugins.cmake
Normal file
24
cw_monero/example/linux/flutter/generated_plugins.cmake
Normal 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)
|
6
cw_monero/example/linux/main.cc
Normal file
6
cw_monero/example/linux/main.cc
Normal 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);
|
||||
}
|
104
cw_monero/example/linux/my_application.cc
Normal file
104
cw_monero/example/linux/my_application.cc
Normal 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));
|
||||
}
|
18
cw_monero/example/linux/my_application.h
Normal file
18
cw_monero/example/linux/my_application.h
Normal 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_
|
|
@ -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);
|
||||
|
@ -495,9 +521,9 @@ extern "C"
|
|||
}
|
||||
|
||||
if (socksProxyAddress != nullptr)
|
||||
{
|
||||
_socksProxyAddress = std::string(socksProxyAddress);
|
||||
}
|
||||
{
|
||||
_socksProxyAddress = std::string(socksProxyAddress);
|
||||
}
|
||||
|
||||
bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet, _socksProxyAddress);
|
||||
|
||||
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -22,7 +22,7 @@ abstract class MoneroSubaddressListBase with Store {
|
|||
bool _isUpdating;
|
||||
|
||||
void update({required int accountIndex}) {
|
||||
refreshCoins(accountIndex);
|
||||
// refreshCoins(accountIndex);
|
||||
|
||||
if (_isUpdating) {
|
||||
return;
|
||||
|
|
|
@ -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),
|
||||
|
@ -48,6 +50,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
}),
|
||||
_isTransactionUpdating = false,
|
||||
_hasSyncAfterStartup = false,
|
||||
_password = password,
|
||||
walletAddresses = MoneroWalletAddresses(walletInfo),
|
||||
syncStatus = NotConnectedSyncStatus(),
|
||||
unspentCoins = [],
|
||||
|
@ -86,6 +89,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(),
|
||||
|
@ -99,6 +105,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
bool _hasSyncAfterStartup;
|
||||
Timer? _autoSaveTimer;
|
||||
List<MoneroUnspent> unspentCoins;
|
||||
String _password;
|
||||
|
||||
Future<void> init() async {
|
||||
await walletAddresses.init();
|
||||
|
@ -352,6 +359,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();
|
||||
|
@ -378,7 +386,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
Future<void> updateUnspent() async {
|
||||
refreshCoins(walletAddresses.account!.id);
|
||||
// refreshCoins(walletAddresses.account!.id);
|
||||
|
||||
unspentCoins.clear();
|
||||
|
||||
|
|
|
@ -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!,
|
||||
password: credentials.password!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
@ -109,7 +111,9 @@ 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) {
|
||||
|
@ -160,7 +164,7 @@ class MoneroWalletService extends WalletService<
|
|||
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||
final currentWallet =
|
||||
MoneroWallet(walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
MoneroWallet(walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource, password: password);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
|
@ -185,7 +189,9 @@ class MoneroWalletService extends WalletService<
|
|||
viewKey: credentials.viewKey,
|
||||
spendKey: credentials.spendKey);
|
||||
final wallet = MoneroWallet(
|
||||
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
|
||||
walletInfo: credentials.walletInfo!,
|
||||
password: credentials.password!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
@ -207,7 +213,9 @@ class MoneroWalletService extends WalletService<
|
|||
seed: credentials.mnemonic,
|
||||
restoreHeight: credentials.height!);
|
||||
final wallet = MoneroWallet(
|
||||
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
|
||||
walletInfo: credentials.walletInfo!,
|
||||
password: credentials.password!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
|
270
cw_monero/linux/CMakeLists.txt
Normal file
270
cw_monero/linux/CMakeLists.txt
Normal 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
|
||||
)
|
70
cw_monero/linux/cw_monero_plugin.cc
Normal file
70
cw_monero/linux/cw_monero_plugin.cc
Normal 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);
|
||||
}
|
26
cw_monero/linux/include/cw_monero/cw_monero_plugin.h
Normal file
26
cw_monero/linux/include/cw_monero/cw_monero_plugin.h
Normal 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_
|
|
@ -20,8 +20,6 @@ using namespace std::chrono_literals;
|
|||
extern "C"
|
||||
{
|
||||
#endif
|
||||
const uint64_t MONERO_BLOCK_SIZE = 1000;
|
||||
|
||||
struct Utf8Box
|
||||
{
|
||||
char *value;
|
||||
|
@ -149,7 +147,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());
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)',
|
||||
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:cw_core/keyable.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
|
@ -36,7 +35,7 @@ class AnonpayInvoiceInfo extends HiveObject with Keyable implements AnonpayInfoB
|
|||
@HiveField(13)
|
||||
final String provider;
|
||||
|
||||
static const typeId = ANONPAY_INVOICE_INFO_TYPE_ID;
|
||||
static const typeId = 10;
|
||||
static const boxName = 'AnonpayInvoiceInfo';
|
||||
|
||||
AnonpayInvoiceInfo({
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,11 +16,11 @@ import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
||||
class MoonPaySellProvider {
|
||||
MoonPaySellProvider({this.isTest = false})
|
||||
: baseUrl = isTest ? _baseTestUrl : _baseProductUrl;
|
||||
MoonPaySellProvider({this.isTest = false}) : baseUrl = isTest ? _baseTestUrl : _baseProductUrl;
|
||||
|
||||
static const _baseTestUrl = 'sell-sandbox.moonpay.com';
|
||||
static const _baseProductUrl = 'sell.moonpay.com';
|
||||
|
||||
static String themeToMoonPayTheme(ThemeBase theme) {
|
||||
switch (theme.type) {
|
||||
case ThemeType.bright:
|
||||
|
@ -31,16 +31,17 @@ class MoonPaySellProvider {
|
|||
return 'dark';
|
||||
}
|
||||
}
|
||||
static String get _apiKey => secrets.moonPayApiKey;
|
||||
static String get _secretKey => secrets.moonPaySecretKey;
|
||||
|
||||
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 {
|
||||
|
||||
required String refundWalletAddress,
|
||||
required SettingsStore settingsStore}) async {
|
||||
final customParams = {
|
||||
'theme': themeToMoonPayTheme(settingsStore.currentTheme),
|
||||
'language': settingsStore.languageCode,
|
||||
|
@ -50,11 +51,13 @@ class MoonPaySellProvider {
|
|||
};
|
||||
|
||||
final originalUri = Uri.https(
|
||||
baseUrl, '', <String, dynamic>{
|
||||
'apiKey': _apiKey,
|
||||
'defaultBaseCurrencyCode': currency.toString().toLowerCase(),
|
||||
'refundWalletAddress': refundWalletAddress
|
||||
}..addAll(customParams));
|
||||
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);
|
||||
|
@ -93,8 +96,7 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
@override
|
||||
BuyProviderDescription get description => BuyProviderDescription.moonPay;
|
||||
|
||||
String get currencyCode =>
|
||||
walletTypeToCryptoCurrency(walletType).title.toLowerCase();
|
||||
String get currencyCode => walletTypeToCryptoCurrency(walletType).title.toLowerCase();
|
||||
|
||||
@override
|
||||
String get trackUrl => baseUrl + '/transaction_receipt?transactionId=';
|
||||
|
@ -103,16 +105,24 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
|
||||
@override
|
||||
Future<String> requestUrl(String amount, String sourceCurrency) async {
|
||||
final enabledPaymentMethods =
|
||||
'credit_debit_card%2Capple_pay%2Cgoogle_pay%2Csamsung_pay'
|
||||
final enabledPaymentMethods = 'credit_debit_card%2Capple_pay%2Cgoogle_pay%2Csamsung_pay'
|
||||
'%2Csepa_bank_transfer%2Cgbp_bank_transfer%2Cgbp_open_banking_payment';
|
||||
|
||||
final suffix = '?apiKey=' + _apiKey + '¤cyCode=' +
|
||||
currencyCode + '&enabledPaymentMethods=' + enabledPaymentMethods +
|
||||
'&walletAddress=' + walletAddress +
|
||||
'&baseCurrencyCode=' + sourceCurrency.toLowerCase() +
|
||||
'&baseCurrencyAmount=' + amount + '&lockAmount=true' +
|
||||
'&showAllCurrencies=false' + '&showWalletAddressForm=false';
|
||||
final suffix = '?apiKey=' +
|
||||
_apiKey +
|
||||
'¤cyCode=' +
|
||||
currencyCode +
|
||||
'&enabledPaymentMethods=' +
|
||||
enabledPaymentMethods +
|
||||
'&walletAddress=' +
|
||||
walletAddress +
|
||||
'&baseCurrencyCode=' +
|
||||
sourceCurrency.toLowerCase() +
|
||||
'&baseCurrencyAmount=' +
|
||||
amount +
|
||||
'&lockAmount=true' +
|
||||
'&showAllCurrencies=false' +
|
||||
'&showWalletAddressForm=false';
|
||||
|
||||
final originalUrl = baseUrl + suffix;
|
||||
|
||||
|
@ -121,25 +131,28 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
final hmac = Hmac(sha256, key);
|
||||
final digest = hmac.convert(messageBytes);
|
||||
final signature = base64.encode(digest.bytes);
|
||||
final urlWithSignature = originalUrl +
|
||||
'&signature=${Uri.encodeComponent(signature)}';
|
||||
final urlWithSignature = originalUrl + '&signature=${Uri.encodeComponent(signature)}';
|
||||
|
||||
return isTestEnvironment ? originalUrl : urlWithSignature;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
|
||||
final url = _apiUrl + _currenciesSuffix + '/$currencyCode' +
|
||||
_quoteSuffix + '/?apiKey=' + _apiKey +
|
||||
'&baseCurrencyAmount=' + amount +
|
||||
'&baseCurrencyCode=' + sourceCurrency.toLowerCase();
|
||||
final url = _apiUrl +
|
||||
_currenciesSuffix +
|
||||
'/$currencyCode' +
|
||||
_quoteSuffix +
|
||||
'/?apiKey=' +
|
||||
_apiKey +
|
||||
'&baseCurrencyAmount=' +
|
||||
amount +
|
||||
'&baseCurrencyCode=' +
|
||||
sourceCurrency.toLowerCase();
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: 'Quote is not found!');
|
||||
throw BuyException(description: description, text: 'Quote is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -148,22 +161,17 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
final minSourceAmount = responseJSON['baseCurrency']['minAmount'] as int;
|
||||
|
||||
return BuyAmount(
|
||||
sourceAmount: sourceAmount,
|
||||
destAmount: destAmount,
|
||||
minAmount: minSourceAmount);
|
||||
sourceAmount: sourceAmount, destAmount: destAmount, minAmount: minSourceAmount);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Order> findOrderById(String id) async {
|
||||
final url = _apiUrl + _transactionsSuffix + '/$id' +
|
||||
'?apiKey=' + _apiKey;
|
||||
final url = _apiUrl + _transactionsSuffix + '/$id' + '?apiKey=' + _apiKey;
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: 'Transaction $id is not found!');
|
||||
throw BuyException(description: description, text: 'Transaction $id is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -181,8 +189,7 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
createdAt: createdAt,
|
||||
amount: amount.toString(),
|
||||
receiveAddress: walletAddress,
|
||||
walletId: walletId
|
||||
);
|
||||
walletId: walletId);
|
||||
}
|
||||
|
||||
static Future<bool> onEnabled() async {
|
||||
|
@ -201,4 +208,4 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
|
||||
return isBuyEnable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cw_core/format_amount.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'order.g.dart';
|
||||
|
||||
|
@ -27,7 +26,7 @@ class Order extends HiveObject {
|
|||
}
|
||||
}
|
||||
|
||||
static const typeId = ORDER_TYPE_ID;
|
||||
static const typeId = 8;
|
||||
static const boxName = 'Orders';
|
||||
static const boxKey = 'ordersBoxKey';
|
||||
|
||||
|
@ -67,4 +66,4 @@ class Order extends HiveObject {
|
|||
BuyProviderDescription.deserialize(raw: providerRaw);
|
||||
|
||||
String amountFormatted() => formatAmount(amount);
|
||||
}
|
||||
}
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:cw_core/root_dir.dart';
|
||||
import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
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';
|
||||
import 'package:archive/archive_io.dart';
|
||||
import 'package:cw_core/cake_hive.dart';
|
||||
import 'package:cake_wallet/core/key_service.dart';
|
||||
import 'package:cake_wallet/entities/encrypt.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
|
@ -17,7 +18,6 @@ import 'package:cake_wallet/entities/secret_store_key.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
|
||||
import 'package:cake_backup/backup.dart' as cake_backup;
|
||||
|
||||
class BackupService {
|
||||
|
@ -32,7 +32,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 +74,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 +114,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 +137,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,19 +170,19 @@ class BackupService {
|
|||
}
|
||||
|
||||
Future<Box<WalletInfo>> _reloadHiveWalletInfoBox() async {
|
||||
final appDir = await getApplicationDocumentsDirectory();
|
||||
await CakeHive.close();
|
||||
CakeHive.init(appDir.path);
|
||||
final appDir = await getAppDir();
|
||||
await Hive.close();
|
||||
Hive.init(appDir.path);
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(WalletInfo.typeId)) {
|
||||
CakeHive.registerAdapter(WalletInfoAdapter());
|
||||
if (!Hive.isAdapterRegistered(WalletInfo.typeId)) {
|
||||
Hive.registerAdapter(WalletInfoAdapter());
|
||||
}
|
||||
|
||||
return await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
return await Hive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
}
|
||||
|
||||
Future<void> _importPreferencesDump() async {
|
||||
final appDir = await getApplicationDocumentsDirectory();
|
||||
final appDir = await getAppDir();
|
||||
final preferencesFile = File('${appDir.path}/~_preferences_dump');
|
||||
|
||||
if (!preferencesFile.existsSync()) {
|
||||
|
@ -375,7 +375,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);
|
||||
|
@ -401,7 +401,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');
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -7,26 +7,24 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class WalletLoadingService {
|
||||
WalletLoadingService(
|
||||
this.sharedPreferences, this.keyService, this.walletServiceFactory);
|
||||
WalletLoadingService(this.sharedPreferences, this.keyService, this.walletServiceFactory);
|
||||
|
||||
final SharedPreferences sharedPreferences;
|
||||
final KeyService keyService;
|
||||
final WalletService Function(WalletType type) walletServiceFactory;
|
||||
|
||||
Future<void> renameWallet(
|
||||
WalletType type, String name, String newName) async {
|
||||
Future<void> renameWallet(WalletType type, String name, String newName,
|
||||
{String? password}) async {
|
||||
final walletService = walletServiceFactory.call(type);
|
||||
final password = await keyService.getWalletPassword(walletName: name);
|
||||
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
|
||||
|
||||
// Save the current wallet's password to the new wallet name's key
|
||||
await keyService.saveWalletPassword(
|
||||
walletName: newName, password: password);
|
||||
await keyService.saveWalletPassword(walletName: newName, password: walletPassword);
|
||||
// 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);
|
||||
await walletService.rename(name, walletPassword, newName);
|
||||
|
||||
// set shared preferences flag based on previous wallet name
|
||||
if (type == WalletType.monero) {
|
||||
|
@ -37,10 +35,10 @@ class WalletLoadingService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<WalletBase> load(WalletType type, String name) async {
|
||||
Future<WalletBase> load(WalletType type, String name, {String? password}) async {
|
||||
final walletService = walletServiceFactory.call(type);
|
||||
final password = await keyService.getWalletPassword(walletName: name);
|
||||
final wallet = await walletService.openWallet(name, password);
|
||||
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
|
||||
final wallet = await walletService.openWallet(name, walletPassword);
|
||||
|
||||
if (type == WalletType.monero) {
|
||||
await updateMoneroWalletPassword(wallet);
|
||||
|
@ -61,11 +59,9 @@ class WalletLoadingService {
|
|||
// Save new generated password with backup key for case where
|
||||
// wallet will change password, but it will fail to update in secure storage
|
||||
final bakWalletName = '#__${wallet.name}_bak__#';
|
||||
await keyService.saveWalletPassword(
|
||||
walletName: bakWalletName, password: password);
|
||||
await keyService.saveWalletPassword(walletName: bakWalletName, password: password);
|
||||
await wallet.changePassword(password);
|
||||
await keyService.saveWalletPassword(
|
||||
walletName: wallet.name, password: password);
|
||||
await keyService.saveWalletPassword(walletName: wallet.name, password: password);
|
||||
isPasswordUpdated = true;
|
||||
await sharedPreferences.setBool(key, isPasswordUpdated);
|
||||
}
|
||||
|
|
107
lib/di.dart
107
lib/di.dart
|
@ -1,3 +1,4 @@
|
|||
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';
|
||||
|
@ -32,6 +33,7 @@ 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/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';
|
||||
|
@ -79,6 +81,8 @@ 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:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cake_wallet/core/backup_service.dart';
|
||||
import 'package:cw_core/wallet_service.dart';
|
||||
|
@ -176,7 +180,7 @@ 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';
|
||||
|
@ -201,6 +205,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';
|
||||
|
@ -269,7 +274,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 +295,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 +350,7 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactory<AuthService>(
|
||||
() => AuthService(
|
||||
secureStorage: getIt.get<FlutterSecureStorage>(),
|
||||
secureStorage: getIt.get<SecureStorage>(),
|
||||
sharedPreferences: getIt.get<SharedPreferences>(),
|
||||
settingsStore: getIt.get<SettingsStore>(),
|
||||
),
|
||||
|
@ -733,11 +737,17 @@ 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,
|
||||
SettingsStoreBase.walletPasswordDirectInput);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumWalletService(_walletInfoSource);
|
||||
return ethereum!.createEthereumWalletService(
|
||||
_walletInfoSource,
|
||||
SettingsStoreBase.walletPasswordDirectInput);
|
||||
default:
|
||||
throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
|
||||
}
|
||||
|
@ -792,16 +802,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>()));
|
||||
|
||||
|
@ -851,8 +864,7 @@ Future<void> setup({
|
|||
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
|
||||
|
||||
getIt.registerFactory(() =>
|
||||
SupportChatPage(
|
||||
getIt.get<SupportViewModel>(), secureStorage: getIt.get<FlutterSecureStorage>()));
|
||||
SupportChatPage(getIt.get<SupportViewModel>(), secureStorage: getIt.get<SecureStorage>()));
|
||||
|
||||
getIt.registerFactory(() => SupportOtherLinksPage(getIt.get<SupportViewModel>()));
|
||||
|
||||
|
@ -892,7 +904,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!));
|
||||
|
@ -930,7 +942,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;
|
||||
|
@ -1033,6 +1045,65 @@ Future<void> setup({
|
|||
getIt.registerFactoryParam<AdvancedPrivacySettingsViewModel, WalletType, void>(
|
||||
(type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>()));
|
||||
|
||||
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,
|
||||
args.authPasswordHandler,
|
||||
closable: closable);
|
||||
}, instanceName: 'wallet_unlock_loadable');
|
||||
|
||||
getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
|
||||
return WalletUnlockPage(
|
||||
getIt.get<WalletUnlockVerifiableViewModel>(param1: args),
|
||||
args.callback,
|
||||
args.authPasswordHandler,
|
||||
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');
|
||||
|
||||
getIt.registerFactoryParam<HomeSettingsPage, BalanceViewModel, void>((balanceViewModel, _) =>
|
||||
HomeSettingsPage(getIt.get<HomeSettingsViewModel>(param1: balanceViewModel)));
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:cw_core/keyable.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cw_core/keyable.dart';
|
||||
|
||||
part 'contact.g.dart';
|
||||
|
||||
|
@ -13,7 +14,7 @@ class Contact extends HiveObject with Keyable {
|
|||
}
|
||||
}
|
||||
|
||||
static const typeId = CONTACT_TYPE_ID;
|
||||
static const typeId = 0;
|
||||
static const boxName = 'Contacts';
|
||||
|
||||
@HiveField(0, defaultValue: '')
|
||||
|
|
|
@ -4,7 +4,7 @@ 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/foundation.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:share_plus/share_plus.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -31,7 +31,7 @@ const ethereumDefaultNodeUri = 'ethereum.publicnode.com';
|
|||
Future 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,
|
||||
|
@ -392,7 +392,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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:cw_core/cake_hive.dart';
|
||||
import 'package:cake_wallet/core/secure_storage.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
Future<List<int>> getEncryptionKey(
|
||||
{required String forKey, required FlutterSecureStorage secureStorage}) async {
|
||||
final stringifiedKey = await secureStorage.read(key: 'transactionDescriptionsBoxKey');
|
||||
{required String forKey, required SecureStorage secureStorage}) async {
|
||||
final stringifiedKey =
|
||||
await secureStorage.read(key: 'transactionDescriptionsBoxKey');
|
||||
List<int> key;
|
||||
|
||||
if (stringifiedKey == null) {
|
||||
key = CakeHive.generateSecureKey();
|
||||
key = Hive.generateSecureKey();
|
||||
final keyStringified = key.join(',');
|
||||
await secureStorage.write(key: 'transactionDescriptionsBoxKey', value: keyStringified);
|
||||
await secureStorage.write(
|
||||
key: 'transactionDescriptionsBoxKey', value: keyStringified);
|
||||
} else {
|
||||
key = stringifiedKey.split(',').map((i) => int.parse(i)).toList();
|
||||
key = stringifiedKey
|
||||
.split(',')
|
||||
.map((i) => int.parse(i))
|
||||
.toList();
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'template.g.dart';
|
||||
|
@ -15,7 +14,7 @@ class Template extends HiveObject {
|
|||
required this.amountFiatRaw,
|
||||
this.additionalRecipientsRaw});
|
||||
|
||||
static const typeId = TEMPLATE_TYPE_ID;
|
||||
static const typeId = 6;
|
||||
static const boxName = 'Template';
|
||||
|
||||
@HiveField(0)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'transaction_description.g.dart';
|
||||
|
@ -7,7 +6,7 @@ part 'transaction_description.g.dart';
|
|||
class TransactionDescription extends HiveObject {
|
||||
TransactionDescription({required this.id, this.recipientAddress, this.transactionNote});
|
||||
|
||||
static const typeId = TRANSACTION_TYPE_ID;
|
||||
static const typeId = 2;
|
||||
static const boxName = 'TransactionDescriptions';
|
||||
static const boxKey = 'transactionDescriptionsBoxKey';
|
||||
|
||||
|
|
|
@ -4,15 +4,16 @@ class CWEthereum extends Ethereum {
|
|||
@override
|
||||
List<String> getEthereumWordList(String language) => EthereumMnemonics.englishWordlist;
|
||||
|
||||
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource) =>
|
||||
EthereumWalletService(walletInfoSource);
|
||||
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect) =>
|
||||
EthereumWalletService(walletInfoSource, isDirect);
|
||||
|
||||
@override
|
||||
WalletCredentials createEthereumNewWalletCredentials({
|
||||
required String name,
|
||||
WalletInfo? walletInfo,
|
||||
String? password,
|
||||
}) =>
|
||||
EthereumNewWalletCredentials(name: name, walletInfo: walletInfo);
|
||||
EthereumNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
|
||||
|
||||
@override
|
||||
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'exchange_template.g.dart';
|
||||
|
@ -15,7 +14,7 @@ class ExchangeTemplate extends HiveObject {
|
|||
required this.depositCurrencyTitleRaw,
|
||||
required this.receiveCurrencyTitleRaw});
|
||||
|
||||
static const typeId = EXCHANGE_TEMPLATE_TYPE_ID;
|
||||
static const typeId = 7;
|
||||
static const boxName = 'ExchangeTemplate';
|
||||
|
||||
@HiveField(0)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cw_core/format_amount.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'trade.g.dart';
|
||||
|
||||
|
@ -42,7 +41,7 @@ class Trade extends HiveObject {
|
|||
}
|
||||
}
|
||||
|
||||
static const typeId = TRADE_TYPE_ID;
|
||||
static const typeId = 3;
|
||||
static const boxName = 'Trades';
|
||||
static const boxKey = 'tradesBoxKey';
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -7,7 +7,8 @@ import 'package:cake_wallet/locales/locale.dart';
|
|||
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:cw_core/root_dir.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -15,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;
|
||||
|
@ -39,7 +40,6 @@ import 'package:uni_links/uni_links.dart';
|
|||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cw_core/cake_hive.dart';
|
||||
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
final rootKey = GlobalKey<RootState>();
|
||||
|
@ -58,8 +58,7 @@ Future<void> main() async {
|
|||
|
||||
return true;
|
||||
};
|
||||
|
||||
await CakeHive.close();
|
||||
await Hive.close();
|
||||
|
||||
await initializeAppConfigs();
|
||||
|
||||
|
@ -70,70 +69,71 @@ Future<void> main() async {
|
|||
}
|
||||
|
||||
Future<void> initializeAppConfigs() async {
|
||||
final appDir = await getApplicationDocumentsDirectory();
|
||||
CakeHive.init(appDir.path);
|
||||
setRootDirFromEnv();
|
||||
final appDir = await getAppDir();
|
||||
Hive.init(appDir.path);
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(Contact.typeId)) {
|
||||
CakeHive.registerAdapter(ContactAdapter());
|
||||
if (!Hive.isAdapterRegistered(Contact.typeId)) {
|
||||
Hive.registerAdapter(ContactAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(Node.typeId)) {
|
||||
CakeHive.registerAdapter(NodeAdapter());
|
||||
if (!Hive.isAdapterRegistered(Node.typeId)) {
|
||||
Hive.registerAdapter(NodeAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(TransactionDescription.typeId)) {
|
||||
CakeHive.registerAdapter(TransactionDescriptionAdapter());
|
||||
if (!Hive.isAdapterRegistered(TransactionDescription.typeId)) {
|
||||
Hive.registerAdapter(TransactionDescriptionAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(Trade.typeId)) {
|
||||
CakeHive.registerAdapter(TradeAdapter());
|
||||
if (!Hive.isAdapterRegistered(Trade.typeId)) {
|
||||
Hive.registerAdapter(TradeAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(WalletInfo.typeId)) {
|
||||
CakeHive.registerAdapter(WalletInfoAdapter());
|
||||
if (!Hive.isAdapterRegistered(WalletInfo.typeId)) {
|
||||
Hive.registerAdapter(WalletInfoAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(WALLET_TYPE_TYPE_ID)) {
|
||||
CakeHive.registerAdapter(WalletTypeAdapter());
|
||||
if (!Hive.isAdapterRegistered(walletTypeTypeId)) {
|
||||
Hive.registerAdapter(WalletTypeAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(Template.typeId)) {
|
||||
CakeHive.registerAdapter(TemplateAdapter());
|
||||
if (!Hive.isAdapterRegistered(Template.typeId)) {
|
||||
Hive.registerAdapter(TemplateAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(ExchangeTemplate.typeId)) {
|
||||
CakeHive.registerAdapter(ExchangeTemplateAdapter());
|
||||
if (!Hive.isAdapterRegistered(ExchangeTemplate.typeId)) {
|
||||
Hive.registerAdapter(ExchangeTemplateAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(Order.typeId)) {
|
||||
CakeHive.registerAdapter(OrderAdapter());
|
||||
if (!Hive.isAdapterRegistered(Order.typeId)) {
|
||||
Hive.registerAdapter(OrderAdapter());
|
||||
}
|
||||
|
||||
if (!isMoneroOnly && !CakeHive.isAdapterRegistered(UnspentCoinsInfo.typeId)) {
|
||||
CakeHive.registerAdapter(UnspentCoinsInfoAdapter());
|
||||
if (!isMoneroOnly && !Hive.isAdapterRegistered(UnspentCoinsInfo.typeId)) {
|
||||
Hive.registerAdapter(UnspentCoinsInfoAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) {
|
||||
CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
|
||||
if (!Hive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) {
|
||||
Hive.registerAdapter(AnonpayInvoiceInfoAdapter());
|
||||
}
|
||||
|
||||
final secureStorage = FlutterSecureStorage();
|
||||
final transactionDescriptionsBoxKey =
|
||||
await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
|
||||
final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
|
||||
final ordersBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Order.boxKey);
|
||||
final contacts = await CakeHive.openBox<Contact>(Contact.boxName);
|
||||
final nodes = await CakeHive.openBox<Node>(Node.boxName);
|
||||
final transactionDescriptions = await CakeHive.openBox<TransactionDescription>(
|
||||
TransactionDescription.boxName,
|
||||
encryptionKey: transactionDescriptionsBoxKey);
|
||||
final trades = await CakeHive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
|
||||
final orders = await CakeHive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
|
||||
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
final templates = await CakeHive.openBox<Template>(Template.boxName);
|
||||
final exchangeTemplates = await CakeHive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
|
||||
final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
|
||||
final unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
|
||||
final secureStorage = secureStorageShared;
|
||||
final transactionDescriptionsBoxKey =
|
||||
await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
|
||||
final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
|
||||
final ordersBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Order.boxKey);
|
||||
final contacts = await Hive.openBox<Contact>(Contact.boxName);
|
||||
final nodes = await Hive.openBox<Node>(Node.boxName);
|
||||
final transactionDescriptions = await Hive.openBox<TransactionDescription>(
|
||||
TransactionDescription.boxName,
|
||||
encryptionKey: transactionDescriptionsBoxKey);
|
||||
final trades = await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
|
||||
final orders = await Hive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
|
||||
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
final templates = await Hive.openBox<Template>(Template.boxName);
|
||||
final exchangeTemplates = await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
|
||||
final anonpayInvoiceInfo = await Hive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
|
||||
final unspentCoinsInfoSource = await Hive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
|
||||
|
||||
await initialSetup(
|
||||
sharedPreferences: await SharedPreferences.getInstance(),
|
||||
|
@ -163,7 +163,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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -7,17 +7,15 @@ import 'package:cw_core/wallet_base.dart';
|
|||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:wakelock/wakelock.dart';
|
||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
|
||||
ReactionDisposer? _onWalletSyncStatusChangeReaction;
|
||||
|
||||
void startWalletSyncStatusChangeReaction(
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
TransactionInfo> wallet,
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet,
|
||||
FiatConversionStore fiatConversionStore) {
|
||||
_onWalletSyncStatusChangeReaction?.reaction.dispose();
|
||||
_onWalletSyncStatusChangeReaction =
|
||||
reaction((_) => wallet.syncStatus, (SyncStatus status) async {
|
||||
_onWalletSyncStatusChangeReaction = reaction((_) => wallet.syncStatus, (SyncStatus status) async {
|
||||
try {
|
||||
if (status is ConnectedSyncStatus) {
|
||||
await wallet.startSync();
|
||||
|
@ -27,12 +25,12 @@ void startWalletSyncStatusChangeReaction(
|
|||
}
|
||||
}
|
||||
if (status is SyncingSyncStatus) {
|
||||
await Wakelock.enable();
|
||||
await WakelockPlus.enable();
|
||||
}
|
||||
if (status is SyncedSyncStatus || status is FailedSyncStatus) {
|
||||
await Wakelock.disable();
|
||||
await WakelockPlus.disable();
|
||||
}
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
@ -545,6 +583,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:
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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');
|
||||
|
|
58
lib/src/screens/buy/payfura_page.dart
Normal file
58
lib/src/screens/buy/payfura_page.dart
Normal file
|
@ -0,0 +1,58 @@
|
|||
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
class PayFuraPage extends BasePage {
|
||||
PayFuraPage(this._PayfuraBuyProvider);
|
||||
|
||||
final PayfuraBuyProvider _PayfuraBuyProvider;
|
||||
|
||||
@override
|
||||
String get title => S.current.buy;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return PayFuraPageBody(_PayfuraBuyProvider);
|
||||
}
|
||||
}
|
||||
|
||||
class PayFuraPageBody extends StatefulWidget {
|
||||
PayFuraPageBody(this._PayfuraBuyProvider);
|
||||
|
||||
final PayfuraBuyProvider _PayfuraBuyProvider;
|
||||
|
||||
Uri get uri => _PayfuraBuyProvider.requestUrl();
|
||||
|
||||
@override
|
||||
PayFuraPageBodyState createState() => PayFuraPageBodyState();
|
||||
}
|
||||
|
||||
class PayFuraPageBodyState extends State<PayFuraPageBody> {
|
||||
PayFuraPageBodyState();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InAppWebView(
|
||||
initialOptions: InAppWebViewGroupOptions(
|
||||
crossPlatform: InAppWebViewOptions(transparentBackground: true),
|
||||
),
|
||||
initialUrlRequest: URLRequest(url: widget.uri),
|
||||
androidOnPermissionRequest: (_, __, resources) async {
|
||||
bool permissionGranted = await Permission.camera.status == PermissionStatus.granted;
|
||||
if (!permissionGranted) {
|
||||
permissionGranted = await Permission.camera.request().isGranted;
|
||||
}
|
||||
|
||||
return PermissionRequestResponse(
|
||||
resources: resources,
|
||||
action: permissionGranted
|
||||
? PermissionRequestResponseAction.GRANT
|
||||
: PermissionRequestResponseAction.DENY,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,9 @@ import 'package:auto_size_text/auto_size_text.dart';
|
|||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DesktopActionButton extends StatelessWidget {
|
||||
|
@ -24,45 +27,48 @@ class DesktopActionButton extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 25),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||
),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset(
|
||||
image,
|
||||
height: 30,
|
||||
width: 30,
|
||||
color: isEnabled
|
||||
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
AutoSizeText(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 25),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||
),
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset(
|
||||
image,
|
||||
height: 30,
|
||||
width: 30,
|
||||
color: isEnabled
|
||||
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
: null,
|
||||
height: 1,
|
||||
: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
|
||||
),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
],
|
||||
const SizedBox(width: 10),
|
||||
AutoSizeText(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
color: isEnabled
|
||||
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
: null,
|
||||
height: 1,
|
||||
),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -4,9 +4,13 @@ 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/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 +38,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 +149,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) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/entities/receive_page_option.dart';
|
||||
|
@ -6,9 +7,12 @@ import 'package:cake_wallet/src/screens/base_page.dart';
|
|||
import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/utils/share_util.dart';
|
||||
|
@ -236,7 +240,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],
|
||||
|
@ -248,7 +252,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(
|
||||
|
@ -258,7 +262,7 @@ class AddressPage extends BasePage {
|
|||
),
|
||||
);
|
||||
} else {
|
||||
Navigator.pushNamed(
|
||||
Navigator.pushReplacementNamed(
|
||||
context,
|
||||
Routes.anonPayInvoicePage,
|
||||
arguments: [addressListViewModel.address.address, option],
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:cake_wallet/routes.dart';
|
|||
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/utils/feature_flag.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -12,6 +13,8 @@ import 'package:cake_wallet/src/widgets/introducing_card.dart';
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
|
||||
class BalancePage extends StatelessWidget {
|
||||
BalancePage({required this.dashboardViewModel, required this.settingsStore});
|
||||
|
|
|
@ -82,7 +82,7 @@ class MarketPlacePage extends StatelessWidget {
|
|||
|
||||
switch (walletType) {
|
||||
case WalletType.haven:
|
||||
showPopUp<void>(
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
|
|
|
@ -46,9 +46,11 @@ class TransactionsPage extends StatelessWidget {
|
|||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
|
||||
child: DashBoardRoundedCardWidget(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.webViewPage,
|
||||
arguments: ['', Uri.parse('https://guides.cakewallet.com/docs/bugs-service-status/why_are_my_funds_not_appearing/')]),
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [
|
||||
'',
|
||||
Uri.parse(
|
||||
'https://guides.cakewallet.com/docs/bugs-service-status/why_are_my_funds_not_appearing/')
|
||||
]),
|
||||
title: S.of(context).syncing_wallet_alert_title,
|
||||
subTitle: S.of(context).syncing_wallet_alert_content,
|
||||
),
|
||||
|
@ -76,40 +78,34 @@ class TransactionsPage extends StatelessWidget {
|
|||
|
||||
return Observer(
|
||||
builder: (_) => TransactionRow(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.transactionDetails,
|
||||
arguments: transaction),
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.transactionDetails, arguments: transaction),
|
||||
direction: transaction.direction,
|
||||
formattedDate: DateFormat('HH:mm')
|
||||
.format(transaction.date),
|
||||
formattedDate: DateFormat('HH:mm').format(transaction.date),
|
||||
formattedAmount: item.formattedCryptoAmount,
|
||||
formattedFiatAmount: dashboardViewModel
|
||||
.balanceViewModel.isFiatDisabled
|
||||
? ''
|
||||
: item.formattedFiatAmount,
|
||||
formattedFiatAmount:
|
||||
dashboardViewModel.balanceViewModel.isFiatDisabled
|
||||
? ''
|
||||
: item.formattedFiatAmount,
|
||||
isPending: transaction.isPending,
|
||||
title: item.formattedTitle +
|
||||
item.formattedStatus));
|
||||
title: item.formattedTitle + item.formattedStatus));
|
||||
}
|
||||
|
||||
if (item is AnonpayTransactionListItem) {
|
||||
final transactionInfo = item.transaction;
|
||||
|
||||
return AnonpayTransactionRow(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.anonPayDetailsPage,
|
||||
arguments: transactionInfo),
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
|
||||
currency: transactionInfo.fiatAmount != null
|
||||
? transactionInfo.fiatEquiv ?? ''
|
||||
: CryptoCurrency.fromFullName(
|
||||
transactionInfo.coinTo)
|
||||
: CryptoCurrency.fromFullName(transactionInfo.coinTo)
|
||||
.name
|
||||
.toUpperCase(),
|
||||
provider: transactionInfo.provider,
|
||||
amount: transactionInfo.fiatAmount?.toString() ??
|
||||
(transactionInfo.amountTo?.toString() ?? ''),
|
||||
createdAt: DateFormat('HH:mm')
|
||||
.format(transactionInfo.createdAt),
|
||||
createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -118,17 +114,14 @@ class TransactionsPage extends StatelessWidget {
|
|||
|
||||
return Observer(
|
||||
builder: (_) => TradeRow(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.tradeDetails,
|
||||
arguments: trade),
|
||||
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,
|
||||
createdAtFormattedDate: trade.createdAt != null
|
||||
? DateFormat('HH:mm').format(trade.createdAt!)
|
||||
: null,
|
||||
formattedAmount: item.tradeFormattedAmount));
|
||||
}
|
||||
|
||||
|
@ -138,13 +131,12 @@ class TransactionsPage extends StatelessWidget {
|
|||
return Observer(
|
||||
builder: (_) => OrderRow(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.orderDetails,
|
||||
arguments: order),
|
||||
.pushNamed(Routes.orderDetails, arguments: order),
|
||||
provider: order.provider,
|
||||
from: order.from!,
|
||||
to: order.to!,
|
||||
createdAtFormattedDate: DateFormat('HH:mm')
|
||||
.format(order.createdAt),
|
||||
createdAtFormattedDate:
|
||||
DateFormat('HH:mm').format(order.createdAt),
|
||||
formattedAmount: item.orderFormattedAmount,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,59 @@ 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).extension<CakeTextTheme>()!.titleColor),
|
||||
decoration: InputDecoration(
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor),
|
||||
hintText: S.of(context).password,
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.underlineColor,
|
||||
width: 1.0)),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.underlineColor,
|
||||
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).extension<CakeTextTheme>()!.titleColor),
|
||||
decoration: InputDecoration(
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.hintTextColor),
|
||||
hintText: S.of(context).repeat_wallet_password,
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.underlineColor,
|
||||
width: 1.0)),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).extension<NewWalletTheme>()!.underlineColor,
|
||||
width: 1.0),
|
||||
)
|
||||
)
|
||||
)],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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: [
|
||||
|
|
|
@ -2,10 +2,12 @@ import 'package:cake_wallet/core/execution_state.dart';
|
|||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/utils/language_list.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
|
||||
import 'package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
|
|
@ -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,22 @@ 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 +78,7 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
nameController.dispose();
|
||||
|
@ -64,6 +86,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 +141,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).repeat_wallet_password,
|
||||
obscureText: true))],
|
||||
Container(height: 20),
|
||||
_restoreFromKeysFormFields(),
|
||||
],
|
||||
|
|
|
@ -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).repeat_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),
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue