mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
Merge main into cw-linux
This commit is contained in:
parent
39cfa265b0
commit
e39d5c6af4
89 changed files with 1400 additions and 654 deletions
3
.github/workflows/cache_dependencies.yml
vendored
3
.github/workflows/cache_dependencies.yml
vendored
|
@ -1,6 +1,7 @@
|
|||
name: Cache Dependencies
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
|
@ -45,7 +46,7 @@ jobs:
|
|||
/opt/android/cake_wallet/cw_monero/android/.cxx
|
||||
/opt/android/cake_wallet/cw_monero/ios/External
|
||||
/opt/android/cake_wallet/cw_shared_external/ios/External
|
||||
key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh') }}
|
||||
key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }}
|
||||
|
||||
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
|
||||
name: Generate Externals
|
||||
|
|
12
.github/workflows/pr_test_build.yml
vendored
12
.github/workflows/pr_test_build.yml
vendored
|
@ -163,7 +163,11 @@ jobs:
|
|||
|
||||
- name: Send Test APK
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cd /opt/android/cake_wallet
|
||||
var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/$GITHUB_HEAD_REF.apk -H "Max-Days: 10")
|
||||
curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}'
|
||||
uses: adrey/slack-file-upload-action@1.0.5
|
||||
with:
|
||||
token: ${{ secrets.SLACK_APP_TOKEN }}
|
||||
path: /opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk
|
||||
channel: ${{ secrets.SLACK_APK_CHANNEL }}
|
||||
title: '${{github.head_ref}}.apk'
|
||||
filename: ${{github.head_ref}}.apk
|
||||
initial_comment: ${{ github.event.head_commit.message }}
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
Bug fixes
|
||||
Fiat Onramp improvements
|
||||
Ability to Auto generate new Monero subaddress when used
|
||||
Coin Control for Monero
|
||||
In-app Live Chat support
|
||||
Additional themes
|
||||
Bug Fixes and performance enhancements
|
|
@ -1,2 +1,6 @@
|
|||
Bug fixes
|
||||
Fiat Onramp improvements
|
||||
Restore Ethereum from private key and QR
|
||||
Ability to Auto generate new Monero subaddress when used
|
||||
Coin Control for Monero
|
||||
In-app Live Chat support
|
||||
Additional themes
|
||||
Bug Fixes and performance enhancements
|
|
@ -37,19 +37,19 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
version: "2.11.0"
|
||||
bech32:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: "cake-0.2.1"
|
||||
resolved-ref: cafd1c270641e95017d57d69f55cca9831d4db56
|
||||
ref: "cake-0.2.2"
|
||||
resolved-ref: "05755063b593aa6cca0a4820a318e0ce17de6192"
|
||||
url: "https://github.com/cake-tech/bech32.git"
|
||||
source: git
|
||||
version: "0.2.1"
|
||||
version: "0.2.2"
|
||||
bip32:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -70,8 +70,8 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: cake-update-v2
|
||||
resolved-ref: "8f86453761c0c26e368392d0ff2c6f12f3b7397b"
|
||||
ref: cake-update-v3
|
||||
resolved-ref: df9204144011ed9419eff7d9ef3143102a40252d
|
||||
url: "https://github.com/cake-tech/bitcoin_flutter.git"
|
||||
source: git
|
||||
version: "2.0.2"
|
||||
|
@ -168,10 +168,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.3.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -200,18 +200,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
|
||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
version: "1.17.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: "196284f26f69444b7f5c50692b55ec25da86d9e500451dc09333bf2e3ad69259"
|
||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
version: "3.1.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -361,10 +361,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
version: "1.1.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -385,10 +385,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.0"
|
||||
version: "0.18.1"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -401,10 +401,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
version: "0.6.7"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -425,10 +425,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
|
||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.13"
|
||||
version: "0.12.15"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -441,10 +441,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.1"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -481,10 +481,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.8.3"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -686,10 +686,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
|
||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.16"
|
||||
version: "0.5.1"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -771,5 +771,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
21
cw_core/lib/address_info.dart
Normal file
21
cw_core/lib/address_info.dart
Normal file
|
@ -0,0 +1,21 @@
|
|||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'address_info.g.dart';
|
||||
|
||||
@HiveType(typeId: ADDRESS_INFO_TYPE_ID)
|
||||
class AddressInfo extends HiveObject {
|
||||
AddressInfo({required this.address, this.accountIndex, required this.label});
|
||||
|
||||
static const typeId = ADDRESS_INFO_TYPE_ID;
|
||||
static const boxName = 'AddressInfo';
|
||||
|
||||
@HiveField(0)
|
||||
int? accountIndex;
|
||||
|
||||
@HiveField(1, defaultValue: '')
|
||||
String address;
|
||||
|
||||
@HiveField(2, defaultValue: '')
|
||||
String label;
|
||||
}
|
4
cw_core/lib/cake_hive.dart
Normal file
4
cw_core/lib/cake_hive.dart
Normal file
|
@ -0,0 +1,4 @@
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:hive/src/hive_impl.dart';
|
||||
|
||||
final HiveInterface CakeHive = HiveImpl();
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'erc20_token.g.dart';
|
||||
|
@ -53,7 +54,7 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin {
|
|||
iconPath: icon,
|
||||
);
|
||||
|
||||
static const typeId = 12;
|
||||
static const typeId = ERC20_TOKEN_TYPE_ID;
|
||||
static const boxName = 'Erc20Tokens';
|
||||
|
||||
@override
|
||||
|
|
13
cw_core/lib/hive_type_ids.dart
Normal file
13
cw_core/lib/hive_type_ids.dart
Normal file
|
@ -0,0 +1,13 @@
|
|||
const CONTACT_TYPE_ID = 0;
|
||||
const NODE_TYPE_ID = 1;
|
||||
const TRANSACTION_TYPE_ID = 2;
|
||||
const TRADE_TYPE_ID = 3;
|
||||
const WALLET_INFO_TYPE_ID = 4;
|
||||
const WALLET_TYPE_TYPE_ID = 5;
|
||||
const TEMPLATE_TYPE_ID = 6;
|
||||
const EXCHANGE_TEMPLATE_TYPE_ID = 7;
|
||||
const ORDER_TYPE_ID = 8;
|
||||
const UNSPENT_COINS_INFO_TYPE_ID = 9;
|
||||
const ANONPAY_INVOICE_INFO_TYPE_ID = 10;
|
||||
const ADDRESS_INFO_TYPE_ID = 11;
|
||||
const ERC20_TOKEN_TYPE_ID = 12;
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:cw_core/address_info.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
abstract class WalletAddresses {
|
||||
WalletAddresses(this.walletInfo)
|
||||
: addressesMap = {};
|
||||
: addressesMap = {},
|
||||
addressInfos = {};
|
||||
|
||||
final WalletInfo walletInfo;
|
||||
|
||||
|
@ -12,6 +14,10 @@ abstract class WalletAddresses {
|
|||
|
||||
Map<String, String> addressesMap;
|
||||
|
||||
Map<int, List<AddressInfo>> addressInfos;
|
||||
|
||||
Set<String> usedAddresses = {};
|
||||
|
||||
Future<void> init();
|
||||
|
||||
Future<void> updateAddressesInBox();
|
||||
|
@ -20,6 +26,8 @@ abstract class WalletAddresses {
|
|||
try {
|
||||
walletInfo.address = address;
|
||||
walletInfo.addresses = addressesMap;
|
||||
walletInfo.addressInfos = addressInfos;
|
||||
walletInfo.usedAddresses = usedAddresses.toList();
|
||||
|
||||
if (walletInfo.isInBox) {
|
||||
await walletInfo.save();
|
||||
|
|
|
@ -52,6 +52,10 @@ abstract class WalletBase<
|
|||
|
||||
late HistoryType transactionHistory;
|
||||
|
||||
set isEnabledAutoGenerateSubaddress(bool value) {}
|
||||
|
||||
bool get isEnabledAutoGenerateSubaddress => false;
|
||||
|
||||
Future<void> connectToNode({required Node node});
|
||||
|
||||
Future<void> startSync();
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'dart:async';
|
||||
import 'package:cw_core/address_info.dart';
|
||||
import 'package:cw_core/hive_type_ids.dart';
|
||||
|
||||
part 'wallet_info.g.dart';
|
||||
|
||||
|
@ -30,7 +31,7 @@ class WalletInfo extends HiveObject {
|
|||
yatEid, yatLastUsedAddressRaw, showIntroCakePayCard);
|
||||
}
|
||||
|
||||
static const typeId = 4;
|
||||
static const typeId = WALLET_INFO_TYPE_ID;
|
||||
static const boxName = 'WalletInfo';
|
||||
|
||||
@HiveField(0, defaultValue: '')
|
||||
|
@ -72,6 +73,12 @@ class WalletInfo extends HiveObject {
|
|||
@HiveField(13)
|
||||
bool? showIntroCakePayCard;
|
||||
|
||||
@HiveField(14)
|
||||
Map<int, List<AddressInfo>>? addressInfos;
|
||||
|
||||
@HiveField(15)
|
||||
List<String>? usedAddresses;
|
||||
|
||||
String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
|
||||
|
||||
set yatLastUsedAddress(String address) {
|
||||
|
|
|
@ -5,191 +5,218 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "4897882604d919befd350648c7f91926a9d5de99e67b455bf0917cc2362f4bb8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "47.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "690e335554a8385bc9d787117d9eb52c0c03ee207a607e593de3c9d71b1cfe80"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.7.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.3.2"
|
||||
asn1lib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.9.0"
|
||||
version: "2.11.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
version: "3.1.0"
|
||||
build_resolvers:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "687cf90a3951affac1bd5f9ecb5e3e90b60487f3d9cdc359bb310f8876bb02a6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.10"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.2.7"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.4.4"
|
||||
version: "8.4.3"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.3.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.16.0"
|
||||
version: "1.17.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.4"
|
||||
encrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: encrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.1.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -199,7 +226,8 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.6+5"
|
||||
flutter_test:
|
||||
|
@ -211,252 +239,288 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
hive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hive
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.3"
|
||||
hive_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: hive_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "81fd20125cb2ce8fd23623d7744ffbaf653aae93706c9bd3bf7019ea0ace3938"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
version: "1.1.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.0"
|
||||
version: "0.18.1"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
version: "0.6.7"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.12"
|
||||
version: "0.12.15"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
version: "0.2.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.1"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
mobx:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: f1862bd92c6a903fab67338f27e2f731117c3cb9ea37cee1a487f9e4e0de314a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.3+1"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "86122e410d8ea24dda0c69adb5c2a6ccadd5ce02ad46e144764e0d0184a06181"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.8.3"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.13"
|
||||
version: "2.0.12"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.24"
|
||||
version: "2.0.22"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
version: "2.1.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.10"
|
||||
version: "2.1.7"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
version: "2.0.5"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "2.1.3"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.3"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.6.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.4"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.2.1"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
sky_engine:
|
||||
|
@ -468,121 +532,138 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "2d79738b6bbf38a43920e2b8d189e9a3ce6cc201f4b8fc76be5e4fe377b1c38d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.6"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
version: "1.9.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.11.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.2.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.12"
|
||||
version: "0.5.1"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.4"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "0.2.0+3"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/cake_hive.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
|
@ -61,14 +62,11 @@ abstract class EthereumWalletBase
|
|||
{CryptoCurrency.eth: initialBalance ?? ERC20Balance(BigInt.zero)}),
|
||||
super(walletInfo) {
|
||||
this.walletInfo = walletInfo;
|
||||
transactionHistory = EthereumTransactionHistory(
|
||||
walletInfo: walletInfo,
|
||||
password: password,
|
||||
encryptionFileUtils: encryptionFileUtils,
|
||||
);
|
||||
transactionHistory = EthereumTransactionHistory(walletInfo: walletInfo, password: password, encryptionFileUtils: encryptionFileUtils,
|
||||
);
|
||||
|
||||
if (!Hive.isAdapterRegistered(Erc20Token.typeId)) {
|
||||
Hive.registerAdapter(Erc20TokenAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(Erc20Token.typeId)) {
|
||||
CakeHive.registerAdapter(Erc20TokenAdapter());
|
||||
}
|
||||
|
||||
_sharedPrefs.complete(SharedPreferences.getInstance());
|
||||
|
@ -107,7 +105,7 @@ abstract class EthereumWalletBase
|
|||
Completer<SharedPreferences> _sharedPrefs = Completer();
|
||||
|
||||
Future<void> init() async {
|
||||
erc20TokensBox = await Hive.openBox<Erc20Token>(Erc20Token.boxName);
|
||||
erc20TokensBox = await CakeHive.openBox<Erc20Token>(Erc20Token.boxName);
|
||||
await walletAddresses.init();
|
||||
await transactionHistory.init();
|
||||
_ethPrivateKey = await getPrivateKey(
|
||||
|
|
|
@ -75,6 +75,7 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
password: credentials.password!,
|
||||
privateKey: credentials.privateKey,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await wallet.init();
|
||||
|
|
|
@ -12,8 +12,7 @@ import 'package:cw_core/monero_wallet_utils.dart';
|
|||
import 'package:cw_haven/api/structs/pending_transaction.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_haven/api/transaction_history.dart'
|
||||
as haven_transaction_history;
|
||||
import 'package:cw_haven/api/transaction_history.dart' as haven_transaction_history;
|
||||
//import 'package:cw_haven/wallet.dart';
|
||||
import 'package:cw_haven/api/wallet.dart' as haven_wallet;
|
||||
import 'package:cw_haven/api/transaction_history.dart' as transaction_history;
|
||||
|
@ -37,8 +36,8 @@ const moneroBlockSize = 1000;
|
|||
|
||||
class HavenWallet = HavenWalletBase with _$HavenWallet;
|
||||
|
||||
abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
||||
HavenTransactionHistory, HavenTransactionInfo> with Store {
|
||||
abstract class HavenWalletBase
|
||||
extends WalletBase<MoneroBalance, HavenTransactionHistory, HavenTransactionInfo> with Store {
|
||||
HavenWalletBase({required WalletInfo walletInfo})
|
||||
: balance = ObservableMap.of(getHavenBalance(accountIndex: 0)),
|
||||
_isTransactionUpdating = false,
|
||||
|
@ -47,8 +46,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
syncStatus = NotConnectedSyncStatus(),
|
||||
super(walletInfo) {
|
||||
transactionHistory = HavenTransactionHistory();
|
||||
_onAccountChangeReaction = reaction((_) => walletAddresses.account,
|
||||
(Account? account) {
|
||||
_onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) {
|
||||
if (account == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -96,14 +94,12 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
haven_wallet.setRecoveringFromSeed(isRecovery: walletInfo.isRecovery);
|
||||
|
||||
if (haven_wallet.getCurrentHeight() <= 1) {
|
||||
haven_wallet.setRefreshFromBlockHeight(
|
||||
height: walletInfo.restoreHeight);
|
||||
haven_wallet.setRefreshFromBlockHeight(height: walletInfo.restoreHeight);
|
||||
}
|
||||
}
|
||||
|
||||
_autoSaveTimer = Timer.periodic(
|
||||
Duration(seconds: _autoSaveInterval),
|
||||
(_) async => await save());
|
||||
_autoSaveTimer =
|
||||
Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -115,7 +111,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
_onAccountChangeReaction?.reaction.dispose();
|
||||
_autoSaveTimer?.cancel();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<void> connectToNode({required Node node}) async {
|
||||
try {
|
||||
|
@ -170,26 +166,25 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
if (hasMultiDestination) {
|
||||
if (outputs.any((item) => item.sendAll
|
||||
|| (item.formattedCryptoAmount ?? 0) <= 0)) {
|
||||
throw HavenTransactionCreationException('You do not have enough coins to send this amount.');
|
||||
if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) {
|
||||
throw HavenTransactionCreationException(
|
||||
'You do not have enough coins to send this amount.');
|
||||
}
|
||||
|
||||
final int totalAmount = outputs.fold(0, (acc, value) =>
|
||||
acc + (value.formattedCryptoAmount ?? 0));
|
||||
final int totalAmount =
|
||||
outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0));
|
||||
|
||||
if (unlockedBalance < totalAmount) {
|
||||
throw HavenTransactionCreationException('You do not have enough coins to send this amount.');
|
||||
throw HavenTransactionCreationException(
|
||||
'You do not have enough coins to send this amount.');
|
||||
}
|
||||
|
||||
final moneroOutputs = outputs.map((output) =>
|
||||
MoneroOutput(
|
||||
address: output.address,
|
||||
amount: output.cryptoAmount!.replaceAll(',', '.')))
|
||||
final moneroOutputs = outputs
|
||||
.map((output) => MoneroOutput(
|
||||
address: output.address, amount: output.cryptoAmount!.replaceAll(',', '.')))
|
||||
.toList();
|
||||
|
||||
pendingTransactionDescription =
|
||||
await transaction_history.createTransactionMultDest(
|
||||
pendingTransactionDescription = await transaction_history.createTransactionMultDest(
|
||||
outputs: moneroOutputs,
|
||||
priorityRaw: _credentials.priority.serialize(),
|
||||
accountIndex: walletAddresses.account!.id);
|
||||
|
@ -198,12 +193,8 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
final address = output.isParsedAddress && (output.extractedAddress?.isNotEmpty ?? false)
|
||||
? output.extractedAddress!
|
||||
: output.address;
|
||||
final amount = output.sendAll
|
||||
? null
|
||||
: output.cryptoAmount!.replaceAll(',', '.');
|
||||
final int? formattedAmount = output.sendAll
|
||||
? null
|
||||
: output.formattedCryptoAmount;
|
||||
final amount = output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
|
||||
final int? formattedAmount = output.sendAll ? null : output.formattedCryptoAmount;
|
||||
|
||||
if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
|
||||
(formattedAmount == null && unlockedBalance <= 0)) {
|
||||
|
@ -213,8 +204,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
|
||||
}
|
||||
|
||||
pendingTransactionDescription =
|
||||
await transaction_history.createTransaction(
|
||||
pendingTransactionDescription = await transaction_history.createTransaction(
|
||||
address: address,
|
||||
assetType: _credentials.assetType,
|
||||
amount: amount,
|
||||
|
@ -307,16 +297,14 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
String getTransactionAddress(int accountIndex, int addressIndex) =>
|
||||
haven_wallet.getAddress(
|
||||
accountIndex: accountIndex,
|
||||
addressIndex: addressIndex);
|
||||
haven_wallet.getAddress(accountIndex: accountIndex, addressIndex: addressIndex);
|
||||
|
||||
@override
|
||||
Future<Map<String, HavenTransactionInfo>> fetchTransactions() async {
|
||||
haven_transaction_history.refreshTransactions();
|
||||
return _getAllTransactions(null).fold<Map<String, HavenTransactionInfo>>(
|
||||
<String, HavenTransactionInfo>{},
|
||||
(Map<String, HavenTransactionInfo> acc, HavenTransactionInfo tx) {
|
||||
return _getAllTransactions(null)
|
||||
.fold<Map<String, HavenTransactionInfo>>(<String, HavenTransactionInfo>{},
|
||||
(Map<String, HavenTransactionInfo> acc, HavenTransactionInfo tx) {
|
||||
acc[tx.id] = tx;
|
||||
return acc;
|
||||
});
|
||||
|
@ -340,9 +328,9 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
List<HavenTransactionInfo> _getAllTransactions(dynamic _) => haven_transaction_history
|
||||
.getAllTransations()
|
||||
.map((row) => HavenTransactionInfo.fromRow(row))
|
||||
.toList();
|
||||
.getAllTransations()
|
||||
.map((row) => HavenTransactionInfo.fromRow(row))
|
||||
.toList();
|
||||
|
||||
void _setListeners() {
|
||||
_listener?.stop();
|
||||
|
@ -364,8 +352,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
int _getHeightDistance(DateTime date) {
|
||||
final distance =
|
||||
DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
|
||||
final distance = DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
|
||||
final daysTmp = (distance / 86400).round();
|
||||
final days = daysTmp < 1 ? 1 : daysTmp;
|
||||
|
||||
|
@ -386,8 +373,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
void _askForUpdateBalance() =>
|
||||
balance.addAll(getHavenBalance(accountIndex: walletAddresses.account!.id));
|
||||
|
||||
Future<void> _askForUpdateTransactionHistory() async =>
|
||||
await updateTransactions();
|
||||
Future<void> _askForUpdateTransactionHistory() async => await updateTransactions();
|
||||
|
||||
void _onNewBlock(int height, int blocksLeft, double ptc) async {
|
||||
try {
|
||||
|
@ -404,9 +390,9 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
syncStatus = SyncedSyncStatus();
|
||||
|
||||
if (!_hasSyncAfterStartup) {
|
||||
_hasSyncAfterStartup = true;
|
||||
await save();
|
||||
}
|
||||
_hasSyncAfterStartup = true;
|
||||
await save();
|
||||
}
|
||||
|
||||
if (walletInfo.isRecovery) {
|
||||
await setAsRecovered();
|
||||
|
|
|
@ -37,10 +37,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
version: "2.11.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -117,10 +117,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.3.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -149,10 +149,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
|
||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
version: "1.17.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -286,10 +286,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
version: "1.1.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -310,10 +310,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.0"
|
||||
version: "0.18.1"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -326,10 +326,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
version: "0.6.7"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -350,10 +350,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
|
||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.13"
|
||||
version: "0.12.15"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -366,10 +366,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.1"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -406,10 +406,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.8.3"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -603,10 +603,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
|
||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.16"
|
||||
version: "0.5.1"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -672,5 +672,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -21,10 +21,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
version: "2.11.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -37,10 +37,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.3.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -53,10 +53,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
|
||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
version: "1.17.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -157,10 +157,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
version: "1.1.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -173,18 +173,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: intl
|
||||
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.0"
|
||||
version: "0.18.1"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
version: "0.6.7"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -197,10 +197,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
|
||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.13"
|
||||
version: "0.12.15"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -213,10 +213,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.1"
|
||||
mobx:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -229,10 +229,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.8.3"
|
||||
path_provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -362,10 +362,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
|
||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.16"
|
||||
version: "0.5.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -399,5 +399,5 @@ packages:
|
|||
source: hosted
|
||||
version: "0.2.0+3"
|
||||
sdks:
|
||||
dart: ">=2.18.1 <3.0.0"
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -145,7 +145,7 @@ extern "C"
|
|||
int8_t direction;
|
||||
int8_t isPending;
|
||||
uint32_t subaddrIndex;
|
||||
|
||||
|
||||
char *hash;
|
||||
char *paymentId;
|
||||
|
||||
|
@ -161,7 +161,7 @@ extern "C"
|
|||
std::set<uint32_t>::iterator it = subIndex.begin();
|
||||
subaddrIndex = *it;
|
||||
confirmations = transaction->confirmations();
|
||||
datetime = static_cast<int64_t>(transaction->timestamp());
|
||||
datetime = static_cast<int64_t>(transaction->timestamp());
|
||||
direction = transaction->direction();
|
||||
isPending = static_cast<int8_t>(transaction->isPending());
|
||||
std::string *hash_str = new std::string(transaction->hash());
|
||||
|
@ -241,7 +241,7 @@ extern "C"
|
|||
}
|
||||
|
||||
void setUnlocked(bool unlocked);
|
||||
|
||||
|
||||
};
|
||||
|
||||
Monero::Coins *m_coins;
|
||||
|
@ -262,7 +262,7 @@ extern "C"
|
|||
{
|
||||
m_wallet = wallet;
|
||||
m_listener = nullptr;
|
||||
|
||||
|
||||
|
||||
if (wallet != nullptr)
|
||||
{
|
||||
|
@ -505,7 +505,7 @@ extern "C"
|
|||
{
|
||||
nice(19);
|
||||
Monero::Wallet *wallet = get_current_wallet();
|
||||
|
||||
|
||||
std::string _login = "";
|
||||
std::string _password = "";
|
||||
std::string _socksProxyAddress = "";
|
||||
|
@ -601,7 +601,7 @@ extern "C"
|
|||
_preferred_inputs.insert(std::string(*preferred_inputs));
|
||||
preferred_inputs++;
|
||||
}
|
||||
|
||||
|
||||
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
|
||||
std::string _payment_id;
|
||||
Monero::PendingTransaction *transaction;
|
||||
|
@ -620,7 +620,7 @@ extern "C"
|
|||
{
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
|
||||
}
|
||||
|
||||
|
||||
int status = transaction->status();
|
||||
|
||||
if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical)
|
||||
|
|
|
@ -6,14 +6,15 @@ import 'package:cw_core/subaddress.dart';
|
|||
|
||||
part 'monero_subaddress_list.g.dart';
|
||||
|
||||
class MoneroSubaddressList = MoneroSubaddressListBase
|
||||
with _$MoneroSubaddressList;
|
||||
class MoneroSubaddressList = MoneroSubaddressListBase with _$MoneroSubaddressList;
|
||||
|
||||
abstract class MoneroSubaddressListBase with Store {
|
||||
MoneroSubaddressListBase()
|
||||
: _isRefreshing = false,
|
||||
_isUpdating = false,
|
||||
subaddresses = ObservableList<Subaddress>();
|
||||
: _isRefreshing = false,
|
||||
_isUpdating = false,
|
||||
subaddresses = ObservableList<Subaddress>();
|
||||
|
||||
final List<String> _usedAddresses = [];
|
||||
|
||||
@observable
|
||||
ObservableList<Subaddress> subaddresses;
|
||||
|
@ -49,20 +50,24 @@ abstract class MoneroSubaddressListBase with Store {
|
|||
subaddresses = [primary] + rest.toList();
|
||||
}
|
||||
|
||||
return subaddresses
|
||||
.map((subaddressRow) => Subaddress(
|
||||
return subaddresses.map((subaddressRow) {
|
||||
final hasDefaultAddressName =
|
||||
subaddressRow.getLabel().toLowerCase() == 'Primary account'.toLowerCase() ||
|
||||
subaddressRow.getLabel().toLowerCase() == 'Untitled account'.toLowerCase();
|
||||
final isPrimaryAddress = subaddressRow.getId() == 0 && hasDefaultAddressName;
|
||||
return Subaddress(
|
||||
id: subaddressRow.getId(),
|
||||
address: subaddressRow.getAddress(),
|
||||
label: subaddressRow.getId() == 0 &&
|
||||
subaddressRow.getLabel().toLowerCase() == 'Primary account'.toLowerCase()
|
||||
? 'Primary address'
|
||||
: subaddressRow.getLabel()))
|
||||
.toList();
|
||||
label: isPrimaryAddress
|
||||
? 'Primary address'
|
||||
: hasDefaultAddressName
|
||||
? ''
|
||||
: subaddressRow.getLabel());
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future<void> addSubaddress({required int accountIndex, required String label}) async {
|
||||
await subaddress_list.addSubaddress(
|
||||
accountIndex: accountIndex, label: label);
|
||||
await subaddress_list.addSubaddress(accountIndex: accountIndex, label: label);
|
||||
update(accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
|
@ -88,4 +93,59 @@ abstract class MoneroSubaddressListBase with Store {
|
|||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateWithAutoGenerate({
|
||||
required int accountIndex,
|
||||
required String defaultLabel,
|
||||
required List<String> usedAddresses,
|
||||
}) async {
|
||||
_usedAddresses.addAll(usedAddresses);
|
||||
if (_isUpdating) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
_isUpdating = true;
|
||||
refresh(accountIndex: accountIndex);
|
||||
subaddresses.clear();
|
||||
final newSubAddresses =
|
||||
await _getAllUnusedAddresses(accountIndex: accountIndex, label: defaultLabel);
|
||||
subaddresses.addAll(newSubAddresses);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} finally {
|
||||
_isUpdating = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Subaddress>> _getAllUnusedAddresses(
|
||||
{required int accountIndex, required String label}) async {
|
||||
final allAddresses = subaddress_list.getAllSubaddresses();
|
||||
|
||||
if (allAddresses.isEmpty || _usedAddresses.contains(allAddresses.last.getAddress())) {
|
||||
final isAddressUnused = await _newSubaddress(accountIndex: accountIndex, label: label);
|
||||
if (!isAddressUnused) {
|
||||
return await _getAllUnusedAddresses(accountIndex: accountIndex, label: label);
|
||||
}
|
||||
}
|
||||
|
||||
return allAddresses
|
||||
.map((subaddressRow) => Subaddress(
|
||||
id: subaddressRow.getId(),
|
||||
address: subaddressRow.getAddress(),
|
||||
label: subaddressRow.getId() == 0 &&
|
||||
subaddressRow.getLabel().toLowerCase() == 'Primary account'.toLowerCase()
|
||||
? 'Primary address'
|
||||
: subaddressRow.getLabel()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<bool> _newSubaddress({required int accountIndex, required String label}) async {
|
||||
await subaddress_list.addSubaddress(accountIndex: accountIndex, label: label);
|
||||
|
||||
return subaddress_list
|
||||
.getAllSubaddresses()
|
||||
.where((subaddressRow) => !_usedAddresses.contains(subaddressRow.getAddress()))
|
||||
.isNotEmpty;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,12 +51,14 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
_isTransactionUpdating = false,
|
||||
_hasSyncAfterStartup = false,
|
||||
_password = password,
|
||||
walletAddresses = MoneroWalletAddresses(walletInfo),
|
||||
isEnabledAutoGenerateSubaddress = false,
|
||||
syncStatus = NotConnectedSyncStatus(),
|
||||
unspentCoins = [],
|
||||
this.unspentCoinsInfo = unspentCoinsInfo,
|
||||
super(walletInfo) {
|
||||
transactionHistory = MoneroTransactionHistory();
|
||||
walletAddresses = MoneroWalletAddresses(walletInfo, transactionHistory);
|
||||
|
||||
_onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) {
|
||||
if (account == null) {
|
||||
return;
|
||||
|
@ -67,7 +69,11 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
|
||||
unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: account.id))
|
||||
});
|
||||
walletAddresses.updateSubaddressList(accountIndex: account.id);
|
||||
_updateSubAddress(isEnabledAutoGenerateSubaddress, account: account);
|
||||
});
|
||||
|
||||
reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
|
||||
_updateSubAddress(enabled, account: walletAddresses.account);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -76,7 +82,11 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
Box<UnspentCoinsInfo> unspentCoinsInfo;
|
||||
|
||||
@override
|
||||
MoneroWalletAddresses walletAddresses;
|
||||
late MoneroWalletAddresses walletAddresses;
|
||||
|
||||
@override
|
||||
@observable
|
||||
bool isEnabledAutoGenerateSubaddress;
|
||||
|
||||
@override
|
||||
@observable
|
||||
|
@ -294,6 +304,14 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
|
||||
@override
|
||||
Future<void> save() async {
|
||||
await walletAddresses.updateUsedSubaddress();
|
||||
|
||||
if (isEnabledAutoGenerateSubaddress) {
|
||||
walletAddresses.updateUnusedSubaddress(
|
||||
accountIndex: walletAddresses.account?.id ?? 0,
|
||||
defaultLabel: walletAddresses.account?.label ?? '');
|
||||
}
|
||||
|
||||
await walletAddresses.updateAddressesInBox();
|
||||
await backupWalletFiles(name);
|
||||
await monero_wallet.store();
|
||||
|
@ -386,7 +404,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
Future<void> updateUnspent() async {
|
||||
// refreshCoins(walletAddresses.account!.id);
|
||||
refreshCoins(walletAddresses.account!.id);
|
||||
|
||||
unspentCoins.clear();
|
||||
|
||||
|
@ -618,4 +636,15 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
print(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void _updateSubAddress(bool enableAutoGenerate, {Account? account}) {
|
||||
if (enableAutoGenerate) {
|
||||
walletAddresses.updateUnusedSubaddress(
|
||||
accountIndex: account?.id ?? 0,
|
||||
defaultLabel: account?.label ?? '',
|
||||
);
|
||||
} else {
|
||||
walletAddresses.updateSubaddressList(accountIndex: account?.id ?? 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,32 @@
|
|||
import 'package:cw_core/address_info.dart';
|
||||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/account.dart';
|
||||
import 'package:cw_monero/api/wallet.dart';
|
||||
import 'package:cw_monero/monero_account_list.dart';
|
||||
import 'package:cw_monero/monero_subaddress_list.dart';
|
||||
import 'package:cw_core/subaddress.dart';
|
||||
import 'package:cw_monero/monero_transaction_history.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'monero_wallet_addresses.g.dart';
|
||||
|
||||
class MoneroWalletAddresses = MoneroWalletAddressesBase
|
||||
with _$MoneroWalletAddresses;
|
||||
class MoneroWalletAddresses = MoneroWalletAddressesBase with _$MoneroWalletAddresses;
|
||||
|
||||
abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
|
||||
MoneroWalletAddressesBase(WalletInfo walletInfo)
|
||||
: accountList = MoneroAccountList(),
|
||||
subaddressList = MoneroSubaddressList(),
|
||||
address = '',
|
||||
super(walletInfo);
|
||||
MoneroWalletAddressesBase(
|
||||
WalletInfo walletInfo, MoneroTransactionHistory moneroTransactionHistory)
|
||||
: accountList = MoneroAccountList(),
|
||||
_moneroTransactionHistory = moneroTransactionHistory,
|
||||
subaddressList = MoneroSubaddressList(),
|
||||
address = '',
|
||||
super(walletInfo);
|
||||
|
||||
final MoneroTransactionHistory _moneroTransactionHistory;
|
||||
@override
|
||||
@observable
|
||||
String address;
|
||||
|
||||
|
||||
@observable
|
||||
Account? account;
|
||||
|
||||
|
@ -46,11 +51,15 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
|
|||
final _subaddressList = MoneroSubaddressList();
|
||||
|
||||
addressesMap.clear();
|
||||
addressInfos.clear();
|
||||
|
||||
accountList.accounts.forEach((account) {
|
||||
_subaddressList.update(accountIndex: account.id);
|
||||
_subaddressList.subaddresses.forEach((subaddress) {
|
||||
addressesMap[subaddress.address] = subaddress.label;
|
||||
addressInfos[account.id] ??= [];
|
||||
addressInfos[account.id]?.add(AddressInfo(
|
||||
address: subaddress.address, label: subaddress.label, accountIndex: account.id));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -62,14 +71,14 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
|
|||
|
||||
bool validate() {
|
||||
accountList.update();
|
||||
final accountListLength = accountList.accounts.length ?? 0;
|
||||
final accountListLength = accountList.accounts.length;
|
||||
|
||||
if (accountListLength <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
subaddressList.update(accountIndex: accountList.accounts.first.id);
|
||||
final subaddressListLength = subaddressList.subaddresses.length ?? 0;
|
||||
final subaddressListLength = subaddressList.subaddresses.length;
|
||||
|
||||
if (subaddressListLength <= 0) {
|
||||
return false;
|
||||
|
@ -83,4 +92,24 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
|
|||
subaddress = subaddressList.subaddresses.first;
|
||||
address = subaddress!.address;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateUsedSubaddress() async {
|
||||
final transactions = _moneroTransactionHistory.transactions.values.toList();
|
||||
|
||||
transactions.forEach((element) {
|
||||
final accountIndex = element.accountIndex;
|
||||
final addressIndex = element.addressIndex;
|
||||
usedAddresses.add(getAddress(accountIndex: accountIndex, addressIndex: addressIndex));
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> updateUnusedSubaddress(
|
||||
{required int accountIndex, required String defaultLabel}) async {
|
||||
await subaddressList.updateWithAutoGenerate(
|
||||
accountIndex: accountIndex,
|
||||
defaultLabel: defaultLabel,
|
||||
usedAddresses: usedAddresses.toList());
|
||||
subaddress = subaddressList.subaddresses.last;
|
||||
address = subaddress!.address;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ class MoneroWalletService extends WalletService<
|
|||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
||||
|
||||
|
||||
static bool walletFilesExist(String path) =>
|
||||
!File(path).existsSync() && !File('$path.keys').existsSync();
|
||||
|
||||
|
@ -128,13 +128,20 @@ class MoneroWalletService extends WalletService<
|
|||
} catch (e) {
|
||||
// TODO: Implement Exception for wallet list service.
|
||||
|
||||
if ((e.toString().contains('bad_alloc') ||
|
||||
final bool isBadAlloc = e.toString().contains('bad_alloc') ||
|
||||
(e is WalletOpeningException &&
|
||||
(e.message == 'std::bad_alloc' ||
|
||||
e.message.contains('bad_alloc')))) ||
|
||||
(e.toString().contains('does not correspond') ||
|
||||
(e is WalletOpeningException &&
|
||||
e.message.contains('does not correspond')))) {
|
||||
(e.message == 'std::bad_alloc' || e.message.contains('bad_alloc')));
|
||||
|
||||
final bool doesNotCorrespond = e.toString().contains('does not correspond') ||
|
||||
(e is WalletOpeningException && e.message.contains('does not correspond'));
|
||||
|
||||
final bool isMissingCacheFilesIOS = e.toString().contains('basic_string') ||
|
||||
(e is WalletOpeningException && e.message.contains('basic_string'));
|
||||
|
||||
final bool isMissingCacheFilesAndroid = e.toString().contains('input_stream') ||
|
||||
(e is WalletOpeningException && e.message.contains('input_stream'));
|
||||
|
||||
if (isBadAlloc || doesNotCorrespond || isMissingCacheFilesIOS || isMissingCacheFilesAndroid) {
|
||||
await restoreOrResetWalletFiles(name);
|
||||
return openWallet(name, password);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
#include <list>
|
||||
#include "thread"
|
||||
#include "CwWalletListener.h"
|
||||
#if __APPLE__
|
||||
|
@ -135,7 +137,7 @@ extern "C"
|
|||
int8_t direction;
|
||||
int8_t isPending;
|
||||
uint32_t subaddrIndex;
|
||||
|
||||
|
||||
char *hash;
|
||||
char *paymentId;
|
||||
|
||||
|
@ -151,7 +153,7 @@ extern "C"
|
|||
std::set<uint32_t>::iterator it = subIndex.begin();
|
||||
subaddrIndex = *it;
|
||||
confirmations = transaction->confirmations();
|
||||
datetime = static_cast<int64_t>(transaction->timestamp());
|
||||
datetime = static_cast<int64_t>(transaction->timestamp());
|
||||
direction = transaction->direction();
|
||||
isPending = static_cast<int8_t>(transaction->isPending());
|
||||
std::string *hash_str = new std::string(transaction->hash());
|
||||
|
@ -180,6 +182,62 @@ extern "C"
|
|||
}
|
||||
};
|
||||
|
||||
struct CoinsInfoRow
|
||||
{
|
||||
uint64_t blockHeight;
|
||||
char *hash;
|
||||
uint64_t internalOutputIndex;
|
||||
uint64_t globalOutputIndex;
|
||||
bool spent;
|
||||
bool frozen;
|
||||
uint64_t spentHeight;
|
||||
uint64_t amount;
|
||||
bool rct;
|
||||
bool keyImageKnown;
|
||||
uint64_t pkIndex;
|
||||
uint32_t subaddrIndex;
|
||||
uint32_t subaddrAccount;
|
||||
char *address;
|
||||
char *addressLabel;
|
||||
char *keyImage;
|
||||
uint64_t unlockTime;
|
||||
bool unlocked;
|
||||
char *pubKey;
|
||||
bool coinbase;
|
||||
char *description;
|
||||
|
||||
CoinsInfoRow(Monero::CoinsInfo *coinsInfo)
|
||||
{
|
||||
blockHeight = coinsInfo->blockHeight();
|
||||
std::string *hash_str = new std::string(coinsInfo->hash());
|
||||
hash = strdup(hash_str->c_str());
|
||||
internalOutputIndex = coinsInfo->internalOutputIndex();
|
||||
globalOutputIndex = coinsInfo->globalOutputIndex();
|
||||
spent = coinsInfo->spent();
|
||||
frozen = coinsInfo->frozen();
|
||||
spentHeight = coinsInfo->spentHeight();
|
||||
amount = coinsInfo->amount();
|
||||
rct = coinsInfo->rct();
|
||||
keyImageKnown = coinsInfo->keyImageKnown();
|
||||
pkIndex = coinsInfo->pkIndex();
|
||||
subaddrIndex = coinsInfo->subaddrIndex();
|
||||
subaddrAccount = coinsInfo->subaddrAccount();
|
||||
address = strdup(coinsInfo->address().c_str()) ;
|
||||
addressLabel = strdup(coinsInfo->addressLabel().c_str());
|
||||
keyImage = strdup(coinsInfo->keyImage().c_str());
|
||||
unlockTime = coinsInfo->unlockTime();
|
||||
unlocked = coinsInfo->unlocked();
|
||||
pubKey = strdup(coinsInfo->pubKey().c_str());
|
||||
coinbase = coinsInfo->coinbase();
|
||||
description = strdup(coinsInfo->description().c_str());
|
||||
}
|
||||
|
||||
void setUnlocked(bool unlocked);
|
||||
|
||||
};
|
||||
|
||||
Monero::Coins *m_coins;
|
||||
|
||||
Monero::Wallet *m_wallet;
|
||||
Monero::TransactionHistory *m_transaction_history;
|
||||
MoneroWalletListener *m_listener;
|
||||
|
@ -187,6 +245,7 @@ extern "C"
|
|||
Monero::SubaddressAccount *m_account;
|
||||
uint64_t m_last_known_wallet_height;
|
||||
uint64_t m_cached_syncing_blockchain_height = 0;
|
||||
std::list<Monero::CoinsInfo*> m_coins_info;
|
||||
std::mutex store_lock;
|
||||
bool is_storing = false;
|
||||
|
||||
|
@ -194,7 +253,7 @@ extern "C"
|
|||
{
|
||||
m_wallet = wallet;
|
||||
m_listener = nullptr;
|
||||
|
||||
|
||||
|
||||
if (wallet != nullptr)
|
||||
{
|
||||
|
@ -222,6 +281,17 @@ extern "C"
|
|||
{
|
||||
m_subaddress = nullptr;
|
||||
}
|
||||
|
||||
m_coins_info = std::list<Monero::CoinsInfo*>();
|
||||
|
||||
if (wallet != nullptr)
|
||||
{
|
||||
m_coins = wallet->coins();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_coins = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Monero::Wallet *get_current_wallet()
|
||||
|
@ -404,13 +474,14 @@ extern "C"
|
|||
return is_connected;
|
||||
}
|
||||
|
||||
bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *error)
|
||||
bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *socksProxyAddress, char *error)
|
||||
{
|
||||
nice(19);
|
||||
Monero::Wallet *wallet = get_current_wallet();
|
||||
|
||||
|
||||
std::string _login = "";
|
||||
std::string _password = "";
|
||||
std::string _socksProxyAddress = "";
|
||||
|
||||
if (login != nullptr)
|
||||
{
|
||||
|
@ -422,7 +493,12 @@ extern "C"
|
|||
_password = std::string(password);
|
||||
}
|
||||
|
||||
bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet);
|
||||
if (socksProxyAddress != nullptr)
|
||||
{
|
||||
_socksProxyAddress = std::string(socksProxyAddress);
|
||||
}
|
||||
|
||||
bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet, _socksProxyAddress);
|
||||
|
||||
if (!inited)
|
||||
{
|
||||
|
@ -479,10 +555,19 @@ extern "C"
|
|||
}
|
||||
|
||||
bool transaction_create(char *address, char *payment_id, char *amount,
|
||||
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
uint8_t priority_raw, uint32_t subaddr_account,
|
||||
char **preferred_inputs, uint32_t preferred_inputs_size,
|
||||
Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
{
|
||||
nice(19);
|
||||
|
||||
|
||||
std::set<std::string> _preferred_inputs;
|
||||
|
||||
for (int i = 0; i < preferred_inputs_size; i++) {
|
||||
_preferred_inputs.insert(std::string(*preferred_inputs));
|
||||
preferred_inputs++;
|
||||
}
|
||||
|
||||
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
|
||||
std::string _payment_id;
|
||||
Monero::PendingTransaction *transaction;
|
||||
|
@ -495,13 +580,13 @@ extern "C"
|
|||
if (amount != nullptr)
|
||||
{
|
||||
uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount));
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account);
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account);
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
|
||||
}
|
||||
|
||||
|
||||
int status = transaction->status();
|
||||
|
||||
if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical)
|
||||
|
@ -519,7 +604,9 @@ extern "C"
|
|||
}
|
||||
|
||||
bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size,
|
||||
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
uint8_t priority_raw, uint32_t subaddr_account,
|
||||
char **preferred_inputs, uint32_t preferred_inputs_size,
|
||||
Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
{
|
||||
nice(19);
|
||||
|
||||
|
@ -533,6 +620,13 @@ extern "C"
|
|||
amounts++;
|
||||
}
|
||||
|
||||
std::set<std::string> _preferred_inputs;
|
||||
|
||||
for (int i = 0; i < preferred_inputs_size; i++) {
|
||||
_preferred_inputs.insert(std::string(*preferred_inputs));
|
||||
preferred_inputs++;
|
||||
}
|
||||
|
||||
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
|
||||
std::string _payment_id;
|
||||
Monero::PendingTransaction *transaction;
|
||||
|
@ -792,6 +886,91 @@ extern "C"
|
|||
return m_wallet->trustedDaemon();
|
||||
}
|
||||
|
||||
CoinsInfoRow* coin(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_coins_info.size()) {
|
||||
std::list<Monero::CoinsInfo*>::iterator it = m_coins_info.begin();
|
||||
std::advance(it, index);
|
||||
Monero::CoinsInfo* element = *it;
|
||||
std::cout << "Element at index " << index << ": " << element << std::endl;
|
||||
return new CoinsInfoRow(element);
|
||||
} else {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
return nullptr; // Return a default value (nullptr) for invalid index
|
||||
}
|
||||
}
|
||||
|
||||
void refresh_coins(uint32_t accountIndex)
|
||||
{
|
||||
m_coins_info.clear();
|
||||
|
||||
m_coins->refresh();
|
||||
for (const auto i : m_coins->getAll()) {
|
||||
if (i->subaddrAccount() == accountIndex && !(i->spent())) {
|
||||
m_coins_info.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t coins_count()
|
||||
{
|
||||
return m_coins_info.size();
|
||||
}
|
||||
|
||||
CoinsInfoRow** coins_from_account(uint32_t accountIndex)
|
||||
{
|
||||
std::vector<CoinsInfoRow*> matchingCoins;
|
||||
|
||||
for (int i = 0; i < coins_count(); i++) {
|
||||
CoinsInfoRow* coinInfo = coin(i);
|
||||
if (coinInfo->subaddrAccount == accountIndex) {
|
||||
matchingCoins.push_back(coinInfo);
|
||||
}
|
||||
}
|
||||
|
||||
CoinsInfoRow** result = new CoinsInfoRow*[matchingCoins.size()];
|
||||
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
CoinsInfoRow** coins_from_txid(const char* txid, size_t* count)
|
||||
{
|
||||
std::vector<CoinsInfoRow*> matchingCoins;
|
||||
|
||||
for (int i = 0; i < coins_count(); i++) {
|
||||
CoinsInfoRow* coinInfo = coin(i);
|
||||
if (std::string(coinInfo->hash) == txid) {
|
||||
matchingCoins.push_back(coinInfo);
|
||||
}
|
||||
}
|
||||
|
||||
*count = matchingCoins.size();
|
||||
CoinsInfoRow** result = new CoinsInfoRow*[*count];
|
||||
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
CoinsInfoRow** coins_from_key_image(const char** keyimages, size_t keyimageCount, size_t* count)
|
||||
{
|
||||
std::vector<CoinsInfoRow*> matchingCoins;
|
||||
|
||||
for (int i = 0; i < coins_count(); i++) {
|
||||
CoinsInfoRow* coinsInfoRow = coin(i);
|
||||
for (size_t j = 0; j < keyimageCount; j++) {
|
||||
if (coinsInfoRow->keyImageKnown && std::string(coinsInfoRow->keyImage) == keyimages[j]) {
|
||||
matchingCoins.push_back(coinsInfoRow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*count = matchingCoins.size();
|
||||
CoinsInfoRow** result = new CoinsInfoRow*[*count];
|
||||
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,10 +37,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
version: "2.11.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -117,10 +117,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.3.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -149,10 +149,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
|
||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
version: "1.17.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -286,10 +286,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
version: "1.1.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -310,10 +310,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.0"
|
||||
version: "0.18.1"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -326,10 +326,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
version: "0.6.7"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -350,10 +350,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
|
||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.13"
|
||||
version: "0.12.15"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -366,10 +366,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.1"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -406,10 +406,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.8.3"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -603,10 +603,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
|
||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.16"
|
||||
version: "0.5.1"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -672,5 +672,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -8,25 +8,6 @@ PODS:
|
|||
- Flutter
|
||||
- ReachabilitySwift
|
||||
- CryptoSwift (1.7.1)
|
||||
- cw_haven (0.0.1):
|
||||
- cw_haven/Boost (= 0.0.1)
|
||||
- cw_haven/Haven (= 0.0.1)
|
||||
- cw_haven/OpenSSL (= 0.0.1)
|
||||
- cw_haven/Sodium (= 0.0.1)
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/Boost (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/Haven (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/OpenSSL (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/Sodium (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_monero (0.0.2):
|
||||
- cw_monero/Boost (= 0.0.2)
|
||||
- cw_monero/Monero (= 0.0.2)
|
||||
|
@ -159,7 +140,6 @@ DEPENDENCIES:
|
|||
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||
- CryptoSwift
|
||||
- cw_haven (from `.symlinks/plugins/cw_haven/ios`)
|
||||
- cw_monero (from `.symlinks/plugins/cw_monero/ios`)
|
||||
- cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`)
|
||||
- device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`)
|
||||
|
@ -205,8 +185,6 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/barcode_scan2/ios"
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||
cw_haven:
|
||||
:path: ".symlinks/plugins/cw_haven/ios"
|
||||
cw_monero:
|
||||
:path: ".symlinks/plugins/cw_monero/ios"
|
||||
cw_shared_external:
|
||||
|
@ -261,7 +239,6 @@ SPEC CHECKSUMS:
|
|||
BigInt: f668a80089607f521586bbe29513d708491ef2f7
|
||||
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
|
||||
CryptoSwift: d3d18dc357932f7e6d580689e065cf1f176007c1
|
||||
cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
|
||||
cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d
|
||||
cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
|
||||
device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
|
||||
|
|
|
@ -232,6 +232,7 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
|
|
|
@ -246,6 +246,7 @@ class BackupService {
|
|||
final useEtherscan = data[PreferencesKey.useEtherscan] as bool?;
|
||||
final syncAll = data[PreferencesKey.syncAllKey] as bool?;
|
||||
final syncMode = data[PreferencesKey.syncModeKey] as int?;
|
||||
final autoGenerateSubaddressStatus = data[PreferencesKey.autoGenerateSubaddressStatusKey] as int?;
|
||||
|
||||
await _sharedPreferences.setString(PreferencesKey.currentWalletName, currentWalletName);
|
||||
|
||||
|
@ -296,6 +297,9 @@ class BackupService {
|
|||
|
||||
if (fiatApiMode != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentFiatApiModeKey, fiatApiMode);
|
||||
if (autoGenerateSubaddressStatus != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.autoGenerateSubaddressStatusKey,
|
||||
autoGenerateSubaddressStatus);
|
||||
|
||||
if (currentPinLength != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentPinLength, currentPinLength);
|
||||
|
@ -523,6 +527,8 @@ class BackupService {
|
|||
_sharedPreferences.getInt(PreferencesKey.syncModeKey),
|
||||
PreferencesKey.syncAllKey:
|
||||
_sharedPreferences.getBool(PreferencesKey.syncAllKey),
|
||||
PreferencesKey.autoGenerateSubaddressStatusKey:
|
||||
_sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey),
|
||||
};
|
||||
|
||||
return json.encode(preferences);
|
||||
|
|
|
@ -21,7 +21,7 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
|
|||
'key': secrets.fiatApiKey,
|
||||
};
|
||||
|
||||
double price = 0.0;
|
||||
num price = 0.0;
|
||||
|
||||
try {
|
||||
late final Uri uri;
|
||||
|
@ -41,12 +41,12 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
|
|||
final results = responseJSON['results'] as Map<String, dynamic>;
|
||||
|
||||
if (results.isNotEmpty) {
|
||||
price = results.values.first as double;
|
||||
price = results.values.first as num;
|
||||
}
|
||||
|
||||
return price;
|
||||
return price.toDouble();
|
||||
} catch (e) {
|
||||
return price;
|
||||
return price.toDouble();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
|
|||
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
|
||||
import 'package:cake_wallet/core/yat_service.dart';
|
||||
import 'package:cake_wallet/entities/background_tasks.dart';
|
||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/entities/receive_page_option.dart';
|
||||
|
@ -250,7 +251,6 @@ Future<void> setup({
|
|||
if (!_isSetupFinished) {
|
||||
getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
|
||||
}
|
||||
|
||||
if (!_isSetupFinished) {
|
||||
getIt.registerFactory(() => BackgroundTasks());
|
||||
}
|
||||
|
|
13
lib/entities/auto_generate_subaddress_status.dart
Normal file
13
lib/entities/auto_generate_subaddress_status.dart
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
enum AutoGenerateSubaddressStatus {
|
||||
initialized(1),
|
||||
enabled(2),
|
||||
disabled(3);
|
||||
|
||||
const AutoGenerateSubaddressStatus(this.value);
|
||||
final int value;
|
||||
|
||||
static AutoGenerateSubaddressStatus deserialize({required int raw}) =>
|
||||
AutoGenerateSubaddressStatus.values.firstWhere((e) => e.value == raw);
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import 'dart:io' show File, Platform;
|
||||
import 'dart:io' show Directory, File, Platform;
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
|
@ -6,7 +6,7 @@ import 'package:cake_wallet/entities/secret_store_key.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cake_wallet/core/secure_storage.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
@ -28,7 +28,7 @@ const cakeWalletLitecoinElectrumUri = 'ltc-electrum.cakewallet.com:50002';
|
|||
const havenDefaultNodeUri = 'nodes.havenprotocol.org:443';
|
||||
const ethereumDefaultNodeUri = 'ethereum.publicnode.com';
|
||||
|
||||
Future defaultSettingsMigration(
|
||||
Future<void> defaultSettingsMigration(
|
||||
{required int version,
|
||||
required SharedPreferences sharedPreferences,
|
||||
required SecureStorage secureStorage,
|
||||
|
@ -43,6 +43,8 @@ Future defaultSettingsMigration(
|
|||
// check current nodes for nullability regardless of the version
|
||||
await checkCurrentNodes(nodes, sharedPreferences);
|
||||
|
||||
await _validateWalletInfoBoxData(walletInfoSource);
|
||||
|
||||
final isNewInstall = sharedPreferences
|
||||
.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion) == null;
|
||||
|
||||
|
@ -179,6 +181,66 @@ Future defaultSettingsMigration(
|
|||
PreferencesKey.currentDefaultSettingsMigrationVersion, version);
|
||||
}
|
||||
|
||||
Future<void> _validateWalletInfoBoxData(Box<WalletInfo> walletInfoSource) async {
|
||||
final root = await getApplicationDocumentsDirectory();
|
||||
|
||||
for (var type in WalletType.values) {
|
||||
if (type == WalletType.none) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String prefix = walletTypeToString(type).toLowerCase();
|
||||
Directory walletsDir = Directory('${root.path}/wallets/$prefix/');
|
||||
|
||||
if (!walletsDir.existsSync()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> walletNames = walletsDir.listSync().map((e) => e.path.split("/").last).toList();
|
||||
|
||||
for (var name in walletNames) {
|
||||
final dir = Directory(await pathForWalletDir(name: name, type: type));
|
||||
|
||||
final walletFiles = dir.listSync();
|
||||
final hasCacheFile = walletFiles.any((element) => element.path.contains("$name/$name"));
|
||||
|
||||
if (!hasCacheFile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type == WalletType.monero || type == WalletType.haven) {
|
||||
final hasKeysFile = walletFiles.any((element) => element.path.contains(".keys"));
|
||||
|
||||
if (!hasKeysFile) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final id = prefix + '_' + name;
|
||||
final exist = walletInfoSource.values.any((el) => el.id == id);
|
||||
|
||||
if (exist) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final walletInfo = WalletInfo.external(
|
||||
id: id,
|
||||
type: type,
|
||||
name: name,
|
||||
isRecovery: true,
|
||||
restoreHeight: 0,
|
||||
date: DateTime.now(),
|
||||
dirPath: dir.path,
|
||||
path: '${dir.path}/$name',
|
||||
address: '',
|
||||
showIntroCakePayCard: false,
|
||||
);
|
||||
|
||||
walletInfoSource.add(walletInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> validateBitcoinSavedTransactionPriority(SharedPreferences sharedPreferences) async {
|
||||
if (bitcoin == null) {
|
||||
return;
|
||||
|
@ -226,7 +288,7 @@ Future<void> changeMoneroCurrentNodeToDefault(
|
|||
{required SharedPreferences sharedPreferences,
|
||||
required Box<Node> nodes}) async {
|
||||
final node = getMoneroDefaultNode(nodes: nodes);
|
||||
final nodeId = node?.key as int ?? 0; // 0 - England
|
||||
final nodeId = node.key as int? ?? 0; // 0 - England
|
||||
|
||||
await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, nodeId);
|
||||
}
|
||||
|
@ -279,7 +341,7 @@ Future<void> changeBitcoinCurrentElectrumServerToDefault(
|
|||
{required SharedPreferences sharedPreferences,
|
||||
required Box<Node> nodes}) async {
|
||||
final server = getBitcoinDefaultElectrumServer(nodes: nodes);
|
||||
final serverId = server?.key as int ?? 0;
|
||||
final serverId = server?.key as int? ?? 0;
|
||||
|
||||
await sharedPreferences.setInt(PreferencesKey.currentBitcoinElectrumSererIdKey, serverId);
|
||||
}
|
||||
|
@ -288,7 +350,7 @@ Future<void> changeLitecoinCurrentElectrumServerToDefault(
|
|||
{required SharedPreferences sharedPreferences,
|
||||
required Box<Node> nodes}) async {
|
||||
final server = getLitecoinDefaultElectrumServer(nodes: nodes);
|
||||
final serverId = server?.key as int ?? 0;
|
||||
final serverId = server?.key as int? ?? 0;
|
||||
|
||||
await sharedPreferences.setInt(PreferencesKey.currentLitecoinElectrumSererIdKey, serverId);
|
||||
}
|
||||
|
@ -297,7 +359,7 @@ Future<void> changeHavenCurrentNodeToDefault(
|
|||
{required SharedPreferences sharedPreferences,
|
||||
required Box<Node> nodes}) async {
|
||||
final node = getHavenDefaultNode(nodes: nodes);
|
||||
final nodeId = node?.key as int ?? 0;
|
||||
final nodeId = node?.key as int? ?? 0;
|
||||
|
||||
await sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, nodeId);
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ class PreferencesKey {
|
|||
'${PreferencesKey.moneroWalletPasswordUpdateV1Base}_${name}';
|
||||
|
||||
static const exchangeProvidersSelection = 'exchange-providers-selection';
|
||||
static const autoGenerateSubaddressStatusKey = 'auto_generate_subaddress_status';
|
||||
static const clearnetDonationLink = 'clearnet_donation_link';
|
||||
static const onionDonationLink = 'onion_donation_link';
|
||||
static const lastSeenAppVersion = 'last_seen_app_version';
|
||||
|
|
|
@ -6,7 +6,9 @@ import 'package:cake_wallet/buy/order.dart';
|
|||
import 'package:cake_wallet/locales/locale.dart';
|
||||
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||
import 'package:cw_core/address_info.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cw_core/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';
|
||||
|
@ -40,6 +42,7 @@ import 'package:uni_links/uni_links.dart';
|
|||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cw_core/cake_hive.dart';
|
||||
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
final rootKey = GlobalKey<RootState>();
|
||||
|
@ -58,7 +61,8 @@ Future<void> main() async {
|
|||
|
||||
return true;
|
||||
};
|
||||
await Hive.close();
|
||||
|
||||
await CakeHive.close();
|
||||
|
||||
await initializeAppConfigs();
|
||||
|
||||
|
@ -71,69 +75,73 @@ Future<void> main() async {
|
|||
Future<void> initializeAppConfigs() async {
|
||||
setRootDirFromEnv();
|
||||
final appDir = await getAppDir();
|
||||
Hive.init(appDir.path);
|
||||
CakeHive.init(appDir.path);
|
||||
|
||||
if (!Hive.isAdapterRegistered(Contact.typeId)) {
|
||||
Hive.registerAdapter(ContactAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(Contact.typeId)) {
|
||||
CakeHive.registerAdapter(ContactAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(Node.typeId)) {
|
||||
Hive.registerAdapter(NodeAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(Node.typeId)) {
|
||||
CakeHive.registerAdapter(NodeAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(TransactionDescription.typeId)) {
|
||||
Hive.registerAdapter(TransactionDescriptionAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(TransactionDescription.typeId)) {
|
||||
CakeHive.registerAdapter(TransactionDescriptionAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(Trade.typeId)) {
|
||||
Hive.registerAdapter(TradeAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(Trade.typeId)) {
|
||||
CakeHive.registerAdapter(TradeAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(WalletInfo.typeId)) {
|
||||
Hive.registerAdapter(WalletInfoAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(AddressInfo.typeId)) {
|
||||
CakeHive.registerAdapter(AddressInfoAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(walletTypeTypeId)) {
|
||||
Hive.registerAdapter(WalletTypeAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(WalletInfo.typeId)) {
|
||||
CakeHive.registerAdapter(WalletInfoAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(Template.typeId)) {
|
||||
Hive.registerAdapter(TemplateAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(WALLET_TYPE_TYPE_ID)) {
|
||||
CakeHive.registerAdapter(WalletTypeAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(ExchangeTemplate.typeId)) {
|
||||
Hive.registerAdapter(ExchangeTemplateAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(Template.typeId)) {
|
||||
CakeHive.registerAdapter(TemplateAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(Order.typeId)) {
|
||||
Hive.registerAdapter(OrderAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(ExchangeTemplate.typeId)) {
|
||||
CakeHive.registerAdapter(ExchangeTemplateAdapter());
|
||||
}
|
||||
|
||||
if (!isMoneroOnly && !Hive.isAdapterRegistered(UnspentCoinsInfo.typeId)) {
|
||||
Hive.registerAdapter(UnspentCoinsInfoAdapter());
|
||||
if (!CakeHive.isAdapterRegistered(Order.typeId)) {
|
||||
CakeHive.registerAdapter(OrderAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) {
|
||||
Hive.registerAdapter(AnonpayInvoiceInfoAdapter());
|
||||
if (!isMoneroOnly && !CakeHive.isAdapterRegistered(UnspentCoinsInfo.typeId)) {
|
||||
CakeHive.registerAdapter(UnspentCoinsInfoAdapter());
|
||||
}
|
||||
|
||||
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);
|
||||
if (!CakeHive.isAdapterRegistered(AnonpayInvoiceInfo.typeId)) {
|
||||
CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
await initialSetup(
|
||||
sharedPreferences: await SharedPreferences.getInstance(),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/update_haven_rate.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
|
@ -21,36 +22,36 @@ ReactionDisposer? _onCurrentWalletChangeReaction;
|
|||
ReactionDisposer? _onCurrentWalletChangeFiatRateUpdateReaction;
|
||||
//ReactionDisposer _onCurrentWalletAddressChangeReaction;
|
||||
|
||||
void startCurrentWalletChangeReaction(AppStore appStore,
|
||||
SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
|
||||
void startCurrentWalletChangeReaction(
|
||||
AppStore appStore, SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
|
||||
_onCurrentWalletChangeReaction?.reaction.dispose();
|
||||
_onCurrentWalletChangeFiatRateUpdateReaction?.reaction.dispose();
|
||||
//_onCurrentWalletAddressChangeReaction?.reaction?dispose();
|
||||
|
||||
//_onCurrentWalletAddressChangeReaction = reaction((_) => appStore.wallet.walletAddresses.address,
|
||||
//(String address) async {
|
||||
//if (address == appStore.wallet.walletInfo.yatLastUsedAddress) {
|
||||
// return;
|
||||
//}
|
||||
//(String address) async {
|
||||
//if (address == appStore.wallet.walletInfo.yatLastUsedAddress) {
|
||||
// return;
|
||||
//}
|
||||
|
||||
//try {
|
||||
// final yatStore = getIt.get<YatStore>();
|
||||
// await updateEmojiIdAddress(
|
||||
// appStore.wallet.walletInfo.yatEmojiId,
|
||||
// appStore.wallet.walletAddresses.address,
|
||||
// yatStore.apiKey,
|
||||
// appStore.wallet.type
|
||||
// );
|
||||
// appStore.wallet.walletInfo.yatLastUsedAddress = address;
|
||||
// await appStore.wallet.walletInfo.save();
|
||||
//} catch (e) {
|
||||
// print(e.toString());
|
||||
//}
|
||||
//try {
|
||||
// final yatStore = getIt.get<YatStore>();
|
||||
// await updateEmojiIdAddress(
|
||||
// appStore.wallet.walletInfo.yatEmojiId,
|
||||
// appStore.wallet.walletAddresses.address,
|
||||
// yatStore.apiKey,
|
||||
// appStore.wallet.type
|
||||
// );
|
||||
// appStore.wallet.walletInfo.yatLastUsedAddress = address;
|
||||
// await appStore.wallet.walletInfo.save();
|
||||
//} catch (e) {
|
||||
// print(e.toString());
|
||||
//}
|
||||
//});
|
||||
|
||||
_onCurrentWalletChangeReaction = reaction((_) => appStore.wallet, (WalletBase<
|
||||
Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
|
||||
wallet) async {
|
||||
_onCurrentWalletChangeReaction = reaction((_) => appStore.wallet,
|
||||
(WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
|
||||
wallet) async {
|
||||
try {
|
||||
if (wallet == null) {
|
||||
return;
|
||||
|
@ -59,11 +60,13 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
|||
final node = settingsStore.getCurrentNode(wallet.type);
|
||||
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
|
||||
startCheckConnectionReaction(wallet, settingsStore);
|
||||
await getIt.get<SharedPreferences>().setString(PreferencesKey.currentWalletName, wallet.name);
|
||||
await getIt
|
||||
.get<SharedPreferences>()
|
||||
.setString(PreferencesKey.currentWalletName, wallet.name);
|
||||
await getIt.get<SharedPreferences>().setInt(
|
||||
PreferencesKey.currentWalletType, serializeToInt(wallet.type));
|
||||
.setInt(PreferencesKey.currentWalletType, serializeToInt(wallet.type));
|
||||
if (wallet.type == WalletType.monero) {
|
||||
_setAutoGenerateSubaddressStatus(wallet, settingsStore);
|
||||
}
|
||||
await wallet.connectToNode(node: node);
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
|
@ -82,9 +85,8 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
|||
}
|
||||
});
|
||||
|
||||
_onCurrentWalletChangeFiatRateUpdateReaction =
|
||||
reaction((_) => appStore.wallet, (WalletBase<Balance,
|
||||
TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
|
||||
_onCurrentWalletChangeFiatRateUpdateReaction = reaction((_) => appStore.wallet,
|
||||
(WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
|
||||
wallet) async {
|
||||
try {
|
||||
if (wallet == null || settingsStore.fiatApiMode == FiatApiMode.disabled) {
|
||||
|
@ -92,11 +94,10 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
|||
}
|
||||
|
||||
fiatConversionStore.prices[wallet.currency] = 0;
|
||||
fiatConversionStore.prices[wallet.currency] =
|
||||
await FiatConversionService.fetchPrice(
|
||||
crypto: wallet.currency,
|
||||
fiat: settingsStore.fiatCurrency,
|
||||
torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
|
||||
fiatConversionStore.prices[wallet.currency] = await FiatConversionService.fetchPrice(
|
||||
crypto: wallet.currency,
|
||||
fiat: settingsStore.fiatCurrency,
|
||||
torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
|
||||
|
||||
if (wallet.type == WalletType.ethereum) {
|
||||
final currencies =
|
||||
|
@ -116,3 +117,17 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _setAutoGenerateSubaddressStatus(
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet,
|
||||
SettingsStore settingsStore,
|
||||
) async {
|
||||
final walletHasAddresses = await wallet.walletAddresses.addressesMap.length > 1;
|
||||
if (settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.initialized &&
|
||||
walletHasAddresses) {
|
||||
settingsStore.autoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.disabled;
|
||||
}
|
||||
wallet.isEnabledAutoGenerateSubaddress =
|
||||
settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.enabled ||
|
||||
settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.initialized;
|
||||
}
|
||||
|
|
|
@ -73,12 +73,12 @@ class DesktopDashboardActions extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: MarketPlacePage(
|
||||
dashboardViewModel: dashboardViewModel,
|
||||
marketPlaceViewModel: getIt.get<MarketPlaceViewModel>(),
|
||||
),
|
||||
Expanded(
|
||||
child: MarketPlacePage(
|
||||
dashboardViewModel: dashboardViewModel,
|
||||
marketPlaceViewModel: getIt.get<MarketPlaceViewModel>(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.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';
|
||||
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';
|
||||
|
@ -28,7 +29,6 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
|||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
|
||||
|
@ -178,7 +178,11 @@ class AddressPage extends BasePage {
|
|||
Observer(builder: (_) {
|
||||
if (addressListViewModel.hasAddressList) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.receive),
|
||||
onTap: () async => dashboardViewModel.isAutoGenerateSubaddressesEnabled
|
||||
? await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (_) => getIt.get<MoneroAccountListPage>())
|
||||
: Navigator.of(context).pushNamed(Routes.receive),
|
||||
child: Container(
|
||||
height: 50,
|
||||
padding: EdgeInsets.only(left: 24, right: 12),
|
||||
|
@ -197,17 +201,26 @@ class AddressPage extends BasePage {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Observer(
|
||||
builder: (_) => Text(
|
||||
addressListViewModel.hasAccounts
|
||||
? S.of(context).accounts_subaddresses
|
||||
: S.of(context).addresses,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
builder: (_) {
|
||||
String label = addressListViewModel.hasAccounts
|
||||
? S.of(context).accounts_subaddresses
|
||||
: S.of(context).addresses;
|
||||
|
||||
if (dashboardViewModel.isAutoGenerateSubaddressesEnabled) {
|
||||
label = addressListViewModel.hasAccounts
|
||||
? S.of(context).accounts
|
||||
: S.of(context).account;
|
||||
}
|
||||
return Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.extension<SyncIndicatorTheme>()!
|
||||
.textColor),
|
||||
)),
|
||||
);
|
||||
},),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
|
@ -217,7 +230,7 @@ class AddressPage extends BasePage {
|
|||
),
|
||||
),
|
||||
);
|
||||
} else if (addressListViewModel.showElectrumAddressDisclaimer) {
|
||||
} else if (dashboardViewModel.isAutoGenerateSubaddressesEnabled || addressListViewModel.showElectrumAddressDisclaimer) {
|
||||
return Text(S.of(context).electrum_address_disclaimer,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
|
|
|
@ -48,15 +48,15 @@ class MarketPlacePage extends StatelessWidget {
|
|||
child: ListView(
|
||||
controller: _scrollController,
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20),
|
||||
DashBoardRoundedCardWidget(
|
||||
onTap: () => launchUrl(
|
||||
Uri.parse("https://cakelabs.com/news/cake-pay-mobile-to-shut-down/"),
|
||||
mode: LaunchMode.externalApplication,
|
||||
),
|
||||
title: S.of(context).cake_pay_title,
|
||||
subTitle: S.of(context).cake_pay_subtitle,
|
||||
),
|
||||
// SizedBox(height: 20),
|
||||
// DashBoardRoundedCardWidget(
|
||||
// onTap: () => launchUrl(
|
||||
// Uri.parse("https://cakelabs.com/news/cake-pay-mobile-to-shut-down/"),
|
||||
// mode: LaunchMode.externalApplication,
|
||||
// ),
|
||||
// title: S.of(context).cake_pay_title,
|
||||
// subTitle: S.of(context).cake_pay_subtitle,
|
||||
// ),
|
||||
SizedBox(height: 20),
|
||||
DashBoardRoundedCardWidget(
|
||||
onTap: () => launchUrl(
|
||||
|
|
|
@ -5,13 +5,14 @@ import 'package:flutter_slidable/flutter_slidable.dart';
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class AccountTile extends StatelessWidget {
|
||||
AccountTile(
|
||||
{required this.isCurrent,
|
||||
required this.accountName,
|
||||
this.accountBalance,
|
||||
required this.currency,
|
||||
required this.onTap,
|
||||
required this.onEdit});
|
||||
AccountTile({
|
||||
required this.isCurrent,
|
||||
required this.accountName,
|
||||
this.accountBalance,
|
||||
required this.currency,
|
||||
required this.onTap,
|
||||
required this.onEdit,
|
||||
});
|
||||
|
||||
final bool isCurrent;
|
||||
final String accountName;
|
||||
|
|
|
@ -75,7 +75,7 @@ class RestoreOptionsPage extends BasePage {
|
|||
await restoreFromQRViewModel.create(restoreWallet: restoreWallet);
|
||||
if (restoreFromQRViewModel.state is FailureState) {
|
||||
_onWalletCreateFailure(context,
|
||||
'Create wallet state: ${restoreFromQRViewModel.state.runtimeType.toString()}');
|
||||
'Create wallet state: ${(restoreFromQRViewModel.state as FailureState).error}');
|
||||
}
|
||||
} catch (e) {
|
||||
_onWalletCreateFailure(context, e.toString());
|
||||
|
|
0
lib/src/screens/restore/widgets/backup_file_button.dart
Normal file
0
lib/src/screens/restore/widgets/backup_file_button.dart
Normal file
|
@ -21,60 +21,66 @@ class DisplaySettingsPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Observer(builder: (_) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
SettingsSwitcherCell(
|
||||
title: S.current.settings_display_balance,
|
||||
value: _displaySettingsViewModel.shouldDisplayBalance,
|
||||
onValueChange: (_, bool value) {
|
||||
_displaySettingsViewModel.setShouldDisplayBalance(value);
|
||||
}),
|
||||
SettingsSwitcherCell(
|
||||
title: S.current.show_market_place,
|
||||
value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
|
||||
onValueChange: (_, bool value) {
|
||||
_displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(value);
|
||||
},
|
||||
),
|
||||
//if (!isHaven) it does not work correctly
|
||||
if(!_displaySettingsViewModel.disabledFiatApiMode)
|
||||
SettingsPickerCell<FiatCurrency>(
|
||||
title: S.current.settings_currency,
|
||||
searchHintText: S.current.search_currency,
|
||||
items: FiatCurrency.all,
|
||||
selectedItem: _displaySettingsViewModel.fiatCurrency,
|
||||
onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency),
|
||||
images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(),
|
||||
isGridView: true,
|
||||
matchingCriteria: (FiatCurrency currency, String searchText) {
|
||||
return currency.title.toLowerCase().contains(searchText) ||
|
||||
currency.fullName.toLowerCase().contains(searchText);
|
||||
return SingleChildScrollView(
|
||||
child: Observer(builder: (_) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
SettingsSwitcherCell(
|
||||
title: S.current.settings_display_balance,
|
||||
value: _displaySettingsViewModel.shouldDisplayBalance,
|
||||
onValueChange: (_, bool value) {
|
||||
_displaySettingsViewModel.setShouldDisplayBalance(value);
|
||||
}),
|
||||
SettingsSwitcherCell(
|
||||
title: S.current.show_market_place,
|
||||
value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
|
||||
onValueChange: (_, bool value) {
|
||||
_displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(value);
|
||||
},
|
||||
),
|
||||
SettingsPickerCell<String>(
|
||||
title: S.current.settings_change_language,
|
||||
searchHintText: S.current.search_language,
|
||||
items: LanguageService.list.keys.toList(),
|
||||
displayItem: (dynamic code) {
|
||||
return LanguageService.list[code] ?? '';
|
||||
},
|
||||
selectedItem: _displaySettingsViewModel.languageCode,
|
||||
onItemSelected: _displaySettingsViewModel.onLanguageSelected,
|
||||
images: LanguageService.list.keys
|
||||
.map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
|
||||
.toList(),
|
||||
matchingCriteria: (String code, String searchText) {
|
||||
return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
|
||||
},
|
||||
),
|
||||
if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile)
|
||||
SettingsThemeChoicesCell(_displaySettingsViewModel),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
//if (!isHaven) it does not work correctly
|
||||
if (!_displaySettingsViewModel.disabledFiatApiMode)
|
||||
SettingsPickerCell<FiatCurrency>(
|
||||
title: S.current.settings_currency,
|
||||
searchHintText: S.current.search_currency,
|
||||
items: FiatCurrency.all,
|
||||
selectedItem: _displaySettingsViewModel.fiatCurrency,
|
||||
onItemSelected: (FiatCurrency currency) =>
|
||||
_displaySettingsViewModel.setFiatCurrency(currency),
|
||||
images: FiatCurrency.all
|
||||
.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
|
||||
.toList(),
|
||||
isGridView: true,
|
||||
matchingCriteria: (FiatCurrency currency, String searchText) {
|
||||
return currency.title.toLowerCase().contains(searchText) ||
|
||||
currency.fullName.toLowerCase().contains(searchText);
|
||||
},
|
||||
),
|
||||
SettingsPickerCell<String>(
|
||||
title: S.current.settings_change_language,
|
||||
searchHintText: S.current.search_language,
|
||||
items: LanguageService.list.keys.toList(),
|
||||
displayItem: (dynamic code) {
|
||||
return LanguageService.list[code] ?? '';
|
||||
},
|
||||
selectedItem: _displaySettingsViewModel.languageCode,
|
||||
onItemSelected: _displaySettingsViewModel.onLanguageSelected,
|
||||
images: LanguageService.list.keys
|
||||
.map((e) => Image.asset(
|
||||
"assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
|
||||
.toList(),
|
||||
matchingCriteria: (String code, String searchText) {
|
||||
return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
|
||||
},
|
||||
),
|
||||
if (ResponsiveLayoutUtil.instance.isMobile && DeviceInfo.instance.isMobile)
|
||||
SettingsThemeChoicesCell(_displaySettingsViewModel),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,36 +42,40 @@ class ManageNodesPage extends BasePage {
|
|||
return nodeListViewModel.nodes.length;
|
||||
},
|
||||
itemBuilder: (_, index) {
|
||||
final node = nodeListViewModel.nodes[index];
|
||||
final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
|
||||
final nodeListRow = NodeListRow(
|
||||
title: node.uriRaw,
|
||||
node: node,
|
||||
isSelected: isSelected,
|
||||
onTap: (_) async {
|
||||
if (isSelected) {
|
||||
return;
|
||||
}
|
||||
return Observer(
|
||||
builder: (context) {
|
||||
final node = nodeListViewModel.nodes[index];
|
||||
final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
|
||||
final nodeListRow = NodeListRow(
|
||||
title: node.uriRaw,
|
||||
node: node,
|
||||
isSelected: isSelected,
|
||||
onTap: (_) async {
|
||||
if (isSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context).change_current_node_title,
|
||||
alertContent: nodeListViewModel.getAlertContent(node.uriRaw),
|
||||
leftButtonText: S.of(context).cancel,
|
||||
rightButtonText: S.of(context).change,
|
||||
actionLeftButton: () => Navigator.of(context).pop(),
|
||||
actionRightButton: () async {
|
||||
await nodeListViewModel.setAsCurrent(node);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
);
|
||||
});
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context).change_current_node_title,
|
||||
alertContent: nodeListViewModel.getAlertContent(node.uriRaw),
|
||||
leftButtonText: S.of(context).cancel,
|
||||
rightButtonText: S.of(context).change,
|
||||
actionLeftButton: () => Navigator.of(context).pop(),
|
||||
actionRightButton: () async {
|
||||
await nodeListViewModel.setAsCurrent(node);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
return nodeListRow;
|
||||
},
|
||||
);
|
||||
|
||||
return nodeListRow;
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
|
@ -50,6 +50,14 @@ class PrivacyPage extends BasePage {
|
|||
onValueChange: (BuildContext _, bool value) {
|
||||
_privacySettingsViewModel.setShouldSaveRecipientAddress(value);
|
||||
}),
|
||||
if (_privacySettingsViewModel.isAutoGenerateSubaddressesVisible)
|
||||
SettingsSwitcherCell(
|
||||
title: S.current.auto_generate_subaddresses,
|
||||
value: _privacySettingsViewModel.isAutoGenerateSubaddressesEnabled,
|
||||
onValueChange: (BuildContext _, bool value) {
|
||||
_privacySettingsViewModel.setAutoGenerateSubaddresses(value);
|
||||
},
|
||||
),
|
||||
if (DeviceInfo.instance.isMobile)
|
||||
SettingsSwitcherCell(
|
||||
title: S.current.prevent_screenshots,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
@ -44,7 +45,7 @@ class SupportTile extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).dialogTheme.backgroundColor,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
|
|
|
@ -17,7 +17,7 @@ class SearchBarWidget extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return TextFormField(
|
||||
controller: searchController,
|
||||
style: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchTextColor),
|
||||
style: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
|
||||
decoration: InputDecoration(
|
||||
hintText: hintText ?? S.of(context).search_currency,
|
||||
hintStyle: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
|
||||
import 'package:cake_wallet/entities/background_tasks.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
|
@ -43,6 +44,7 @@ abstract class SettingsStoreBase with Store {
|
|||
required FiatCurrency initialFiatCurrency,
|
||||
required BalanceDisplayMode initialBalanceDisplayMode,
|
||||
required bool initialSaveRecipientAddress,
|
||||
required AutoGenerateSubaddressStatus initialAutoGenerateSubaddressStatus,
|
||||
required bool initialAppSecure,
|
||||
required bool initialDisableBuy,
|
||||
required bool initialDisableSell,
|
||||
|
@ -88,6 +90,7 @@ abstract class SettingsStoreBase with Store {
|
|||
fiatCurrency = initialFiatCurrency,
|
||||
balanceDisplayMode = initialBalanceDisplayMode,
|
||||
shouldSaveRecipientAddress = initialSaveRecipientAddress,
|
||||
autoGenerateSubaddressStatus = initialAutoGenerateSubaddressStatus,
|
||||
fiatApiMode = initialFiatMode,
|
||||
allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
|
||||
selectedCake2FAPreset = initialCake2FAPresetOptions,
|
||||
|
@ -198,6 +201,11 @@ abstract class SettingsStoreBase with Store {
|
|||
(bool disableSell) =>
|
||||
sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell));
|
||||
|
||||
reaction(
|
||||
(_) => autoGenerateSubaddressStatus,
|
||||
(AutoGenerateSubaddressStatus autoGenerateSubaddressStatus) => sharedPreferences.setInt(
|
||||
PreferencesKey.autoGenerateSubaddressStatusKey, autoGenerateSubaddressStatus.value));
|
||||
|
||||
reaction(
|
||||
(_) => fiatApiMode,
|
||||
(FiatApiMode mode) =>
|
||||
|
@ -339,6 +347,7 @@ abstract class SettingsStoreBase with Store {
|
|||
static const defaultActionsMode = 11;
|
||||
static const defaultPinCodeTimeOutDuration = PinCodeRequiredDuration.tenminutes;
|
||||
static final walletPasswordDirectInput = Platform.isLinux;
|
||||
static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
|
||||
|
||||
@observable
|
||||
FiatCurrency fiatCurrency;
|
||||
|
@ -361,6 +370,9 @@ abstract class SettingsStoreBase with Store {
|
|||
@observable
|
||||
bool shouldSaveRecipientAddress;
|
||||
|
||||
@observable
|
||||
AutoGenerateSubaddressStatus autoGenerateSubaddressStatus;
|
||||
|
||||
@observable
|
||||
bool isAppSecure;
|
||||
|
||||
|
@ -601,15 +613,15 @@ abstract class SettingsStoreBase with Store {
|
|||
final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
|
||||
final havenNode = nodeSource.get(havenNodeId);
|
||||
final ethereumNode = nodeSource.get(ethereumNodeId);
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final deviceName = await _getDeviceName() ?? '';
|
||||
final shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
|
||||
var appVersion = '';
|
||||
|
||||
try {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
appVersion = packageInfo.version;
|
||||
} catch(_) {}
|
||||
final generateSubaddresses =
|
||||
sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
|
||||
|
||||
final autoGenerateSubaddressStatus = generateSubaddresses != null
|
||||
? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
|
||||
: defaultAutoGenerateSubaddressStatus;
|
||||
final nodes = <WalletType, Node>{};
|
||||
|
||||
if (moneroNode != null) {
|
||||
|
@ -641,12 +653,13 @@ abstract class SettingsStoreBase with Store {
|
|||
sharedPreferences: sharedPreferences,
|
||||
initialShouldShowMarketPlaceInDashboard: shouldShowMarketPlaceInDashboard,
|
||||
nodes: nodes,
|
||||
appVersion: appVersion,
|
||||
appVersion: packageInfo.version,
|
||||
deviceName: deviceName,
|
||||
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
|
||||
initialFiatCurrency: currentFiatCurrency,
|
||||
initialBalanceDisplayMode: currentBalanceDisplayMode,
|
||||
initialSaveRecipientAddress: shouldSaveRecipientAddress,
|
||||
initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus,
|
||||
initialAppSecure: isAppSecure,
|
||||
initialDisableBuy: disableBuy,
|
||||
initialDisableSell: disableSell,
|
||||
|
@ -716,6 +729,13 @@ abstract class SettingsStoreBase with Store {
|
|||
priority[WalletType.ethereum]!;
|
||||
}
|
||||
|
||||
final generateSubaddresses =
|
||||
sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
|
||||
|
||||
autoGenerateSubaddressStatus = generateSubaddresses != null
|
||||
? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
|
||||
: defaultAutoGenerateSubaddressStatus;
|
||||
|
||||
balanceDisplayMode = BalanceDisplayMode.deserialize(
|
||||
raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
|
||||
shouldSaveRecipientAddress =
|
||||
|
@ -726,8 +746,6 @@ abstract class SettingsStoreBase with Store {
|
|||
|
||||
numberOfFailedTokenTrials =
|
||||
sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? numberOfFailedTokenTrials;
|
||||
sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ??
|
||||
shouldSaveRecipientAddress;
|
||||
isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure;
|
||||
disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? disableBuy;
|
||||
disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? disableSell;
|
||||
|
@ -856,7 +874,6 @@ abstract class SettingsStoreBase with Store {
|
|||
if (Platform.isAndroid) {
|
||||
final androidInfo = await deviceInfoPlugin.androidInfo;
|
||||
deviceName = '${androidInfo.brand}%20${androidInfo.manufacturer}%20${androidInfo.model}';
|
||||
print(deviceName);
|
||||
} else if (Platform.isIOS) {
|
||||
final iosInfo = await deviceInfoPlugin.iosInfo;
|
||||
deviceName = iosInfo.model;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/contact_base.dart';
|
||||
import 'package:cake_wallet/entities/wallet_contact.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
|
@ -10,6 +11,7 @@ import 'package:cake_wallet/entities/contact_record.dart';
|
|||
import 'package:cake_wallet/entities/contact.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
part 'contact_list_view_model.g.dart';
|
||||
|
||||
|
@ -20,12 +22,26 @@ abstract class ContactListViewModelBase with Store {
|
|||
ContactListViewModelBase(this.contactSource, this.walletInfoSource,
|
||||
this._currency, this.settingsStore)
|
||||
: contacts = ObservableList<ContactRecord>(),
|
||||
walletContacts = [] {
|
||||
walletContacts = [],
|
||||
isAutoGenerateEnabled =
|
||||
settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.enabled {
|
||||
walletInfoSource.values.forEach((info) {
|
||||
if (info.addresses?.isNotEmpty ?? false) {
|
||||
info.addresses?.forEach((address, label) {
|
||||
final name = label.isNotEmpty ? info.name + ' ($label)' : info.name;
|
||||
|
||||
if (isAutoGenerateEnabled && info.type == WalletType.monero && info.addressInfos != null) {
|
||||
info.addressInfos!.forEach((key, value) {
|
||||
final nextUnusedAddress = value.firstWhereOrNull(
|
||||
(addressInfo) => !(info.usedAddresses?.contains(addressInfo.address) ?? false));
|
||||
if (nextUnusedAddress != null) {
|
||||
final name = _createName(info.name, nextUnusedAddress.label);
|
||||
walletContacts.add(WalletContact(
|
||||
nextUnusedAddress.address,
|
||||
name,
|
||||
walletTypeToCryptoCurrency(info.type),
|
||||
));
|
||||
}
|
||||
});
|
||||
} else if (info.addresses?.isNotEmpty == true) {
|
||||
info.addresses!.forEach((address, label) {
|
||||
final name = _createName(info.name, label);
|
||||
walletContacts.add(WalletContact(
|
||||
address,
|
||||
name,
|
||||
|
@ -40,6 +56,11 @@ abstract class ContactListViewModelBase with Store {
|
|||
initialFire: true);
|
||||
}
|
||||
|
||||
String _createName(String walletName, String label) {
|
||||
return label.isNotEmpty ? '$walletName ($label)' : walletName;
|
||||
}
|
||||
|
||||
final bool isAutoGenerateEnabled;
|
||||
final Box<Contact> contactSource;
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final ObservableList<ContactRecord> contacts;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
|
||||
|
@ -235,6 +236,10 @@ abstract class DashboardViewModelBase with Store {
|
|||
@computed
|
||||
double get price => balanceViewModel.price;
|
||||
|
||||
@computed
|
||||
bool get isAutoGenerateSubaddressesEnabled =>
|
||||
settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled;
|
||||
|
||||
@computed
|
||||
List<ActionListItem> get items {
|
||||
final _items = <ActionListItem>[];
|
||||
|
|
|
@ -76,6 +76,7 @@ abstract class NodeListViewModelBase with Store {
|
|||
@action
|
||||
Future<void> delete(Node node) async => node.delete();
|
||||
|
||||
@action
|
||||
Future<void> setAsCurrent(Node node) async => settingsStore.nodes[_appStore.wallet!.type] = node;
|
||||
|
||||
@action
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -14,11 +18,27 @@ abstract class PrivacySettingsViewModelBase with Store {
|
|||
PrivacySettingsViewModelBase(this._settingsStore, this._wallet);
|
||||
|
||||
final SettingsStore _settingsStore;
|
||||
final WalletBase _wallet;
|
||||
final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
|
||||
|
||||
@computed
|
||||
ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus;
|
||||
|
||||
@computed
|
||||
bool get isAutoGenerateSubaddressesEnabled =>
|
||||
_settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled;
|
||||
|
||||
@action
|
||||
void setAutoGenerateSubaddresses(bool value) {
|
||||
_wallet.isEnabledAutoGenerateSubaddress = value;
|
||||
if (value) {
|
||||
_settingsStore.autoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.enabled;
|
||||
} else {
|
||||
_settingsStore.autoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
bool get isAutoGenerateSubaddressesVisible => _wallet.type == WalletType.monero;
|
||||
|
||||
@computed
|
||||
bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress;
|
||||
|
||||
|
|
|
@ -3,11 +3,9 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
|||
import 'package:cake_wallet/entities/unspent_transaction_output.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_wallet.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@ DEPENDENCIES:
|
|||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
|
||||
- package_info (from `Flutter/ephemeral/.symlinks/plugins/package_info/macos`)
|
||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`)
|
||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- platform_device_id (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id/macos`)
|
||||
- platform_device_id_macos (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id_macos/macos`)
|
||||
- share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`)
|
||||
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`)
|
||||
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||
- wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`)
|
||||
|
||||
|
@ -87,7 +87,7 @@ EXTERNAL SOURCES:
|
|||
package_info:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info/macos
|
||||
path_provider_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
|
||||
platform_device_id:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/platform_device_id/macos
|
||||
platform_device_id_macos:
|
||||
|
@ -95,7 +95,7 @@ EXTERNAL SOURCES:
|
|||
share_plus_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos
|
||||
shared_preferences_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
|
||||
url_launcher_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||
wakelock_macos:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||
cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||
cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||
cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||
cd cw_ethereum && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
|
||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||
cd cw_core; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_monero; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_bitcoin; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_haven; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd ..
|
||||
cd cw_ethereum; flutter pub get; flutter packages pub run build_runner build --delete-conflicting-outputs; cd ..
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
|
|
|
@ -683,6 +683,8 @@
|
|||
"support_description_other_links": "انضم إلى مجتمعاتنا أو تصل إلينا شركائنا من خلال أساليب أخرى",
|
||||
"select_destination": ".ﻲﻃﺎﻴﺘﺣﻻﺍ ﺦﺴﻨﻟﺍ ﻒﻠﻣ ﺔﻬﺟﻭ ﺪﻳﺪﺤﺗ ءﺎﺟﺮﻟﺍ",
|
||||
"save_to_downloads": "ﺕﻼﻳﺰﻨﺘﻟﺍ ﻲﻓ ﻆﻔﺣ",
|
||||
"support_description_other_links": "انضم إلى مجتمعاتنا أو تصل إلينا شركائنا من خلال أساليب أخرى",
|
||||
"auto_generate_subaddresses": "تلقائي توليد subddresses",
|
||||
"invalid_password": "رمز مرور خاطئ",
|
||||
"unlock": "الغاء القفل",
|
||||
"enter_wallet_password": "أدخل كلمة مرور المحفظة",
|
||||
|
|
|
@ -626,6 +626,7 @@
|
|||
"setup_totp_recommended": "Настройка на TOTP (препоръчително)",
|
||||
"disable_buy": "Деактивирайте действието за покупка",
|
||||
"disable_sell": "Деактивирайте действието за продажба",
|
||||
"auto_generate_subaddresses": "Автоматично генериране на подадреси",
|
||||
"cake_2fa_preset": "Торта 2FA Preset",
|
||||
"narrow": "Тесен",
|
||||
"normal": "нормално",
|
||||
|
|
|
@ -626,6 +626,7 @@
|
|||
"setup_totp_recommended": "Nastavit TOTP (doporučeno)",
|
||||
"disable_buy": "Zakázat akci nákupu",
|
||||
"disable_sell": "Zakázat akci prodeje",
|
||||
"auto_generate_subaddresses": "Automaticky generovat podadresy",
|
||||
"cake_2fa_preset": "Předvolba Cake 2FA",
|
||||
"narrow": "Úzký",
|
||||
"normal": "Normální",
|
||||
|
|
|
@ -640,6 +640,7 @@
|
|||
"high_contrast_theme": "Kontrastreiches Thema",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Theme",
|
||||
"monero_light_theme": "Monero Light-Thema",
|
||||
"auto_generate_subaddresses": "Unteradressen automatisch generieren",
|
||||
"cake_2fa_preset": "Cake 2FA-Voreinstellung",
|
||||
"narrow": "Eng",
|
||||
"normal": "Normal",
|
||||
|
@ -693,4 +694,4 @@
|
|||
"repeat_wallet_password": "Wiederholen Sie das Brieftaschenkennwort",
|
||||
"wallet_password_is_empty": "Brieftaschenkennwort ist leer. Brieftaschenkennwort sollte nicht leer sein",
|
||||
"repeated_password_is_incorrect": "Wiederholtes Passwort ist falsch. Bitte wiederholen Sie das Brieftaschenkennwort erneut."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -568,6 +568,7 @@
|
|||
"privacy": "Privacy",
|
||||
"display_settings": "Display settings",
|
||||
"other_settings": "Other settings",
|
||||
"auto_generate_subaddresses": "Auto generate subaddresses",
|
||||
"require_pin_after": "Require PIN after",
|
||||
"always": "Always",
|
||||
"minutes_to_pin_code": "${minute} minutes",
|
||||
|
|
|
@ -640,6 +640,7 @@
|
|||
"high_contrast_theme": "Tema de alto contraste",
|
||||
"matrix_green_dark_theme": "Matrix verde oscuro tema",
|
||||
"monero_light_theme": "Tema ligero de Monero",
|
||||
"auto_generate_subaddresses": "Generar subdirecciones automáticamente",
|
||||
"cake_2fa_preset": "Pastel 2FA preestablecido",
|
||||
"narrow": "Angosto",
|
||||
"normal": "Normal",
|
||||
|
|
|
@ -640,6 +640,7 @@
|
|||
"high_contrast_theme": "Thème à contraste élevé",
|
||||
"matrix_green_dark_theme": "Thème Matrix Green Dark",
|
||||
"monero_light_theme": "Thème de lumière Monero",
|
||||
"auto_generate_subaddresses": "Générer automatiquement des sous-adresses",
|
||||
"cake_2fa_preset": "Gâteau 2FA prédéfini",
|
||||
"narrow": "Étroit",
|
||||
"normal": "Normal",
|
||||
|
|
|
@ -618,6 +618,7 @@
|
|||
"high_contrast_theme": "Babban Jigon Kwatance",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Jigo",
|
||||
"monero_light_theme": "Jigon Hasken Monero",
|
||||
"auto_generate_subaddresses": "Saɓaƙa subaddresses ta kai tsaye",
|
||||
"cake_2fa_preset": "Cake 2FA saiti",
|
||||
"narrow": "kunkuntar",
|
||||
"normal": "Na al'ada",
|
||||
|
|
|
@ -640,6 +640,7 @@
|
|||
"high_contrast_theme": "उच्च कंट्रास्ट थीम",
|
||||
"matrix_green_dark_theme": "मैट्रिक्स ग्रीन डार्क थीम",
|
||||
"monero_light_theme": "मोनेरो लाइट थीम",
|
||||
"auto_generate_subaddresses": "स्वचालित रूप से उप-पते उत्पन्न करें",
|
||||
"cake_2fa_preset": "केक 2एफए प्रीसेट",
|
||||
"narrow": "सँकरा",
|
||||
"normal": "सामान्य",
|
||||
|
|
|
@ -640,6 +640,7 @@
|
|||
"high_contrast_theme": "Tema visokog kontrasta",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Theme",
|
||||
"monero_light_theme": "Monero lagana tema",
|
||||
"auto_generate_subaddresses": "Automatski generirajte podadrese",
|
||||
"cake_2fa_preset": "Cake 2FA Preset",
|
||||
"narrow": "Usko",
|
||||
"normal": "Normalno",
|
||||
|
|
|
@ -622,6 +622,7 @@
|
|||
"setup_totp_recommended": "Siapkan TOTP (Disarankan)",
|
||||
"disable_buy": "Nonaktifkan tindakan beli",
|
||||
"disable_sell": "Nonaktifkan aksi jual",
|
||||
"auto_generate_subaddresses": "Menghasilkan subalamat secara otomatis",
|
||||
"cake_2fa_preset": "Preset Kue 2FA",
|
||||
"narrow": "Sempit",
|
||||
"normal": "Normal",
|
||||
|
|
|
@ -634,6 +634,7 @@
|
|||
"setup_totp_recommended": "Imposta TOTP (consigliato)",
|
||||
"disable_buy": "Disabilita l'azione di acquisto",
|
||||
"disable_sell": "Disabilita l'azione di vendita",
|
||||
"auto_generate_subaddresses": "Genera automaticamente sottindirizzi",
|
||||
"cake_2fa_preset": "Torta 2FA Preset",
|
||||
"narrow": "Stretto",
|
||||
"normal": "Normale",
|
||||
|
|
|
@ -687,10 +687,11 @@
|
|||
"support_description_other_links": "私たちのコミュニティに参加するか、他の方法を通して私たちのパートナーに連絡してください",
|
||||
"select_destination": "バックアップファイルの保存先を選択してください。",
|
||||
"save_to_downloads": "ダウンロードに保存",
|
||||
"auto_generate_subaddresses": "Autoはサブアドレスを生成します",
|
||||
"invalid_password": "無効なパスワード",
|
||||
"unlock": "ロックを解除します",
|
||||
"enter_wallet_password": "ウォレットパスワードを入力します",
|
||||
"repeat_wallet_password": "ウォレットパスワードを繰り返します",
|
||||
"wallet_password_is_empty": "ウォレットパスワードは空です。ウォレットのパスワードは空にしてはいけません",
|
||||
"repeated_password_is_incorrect": "繰り返しパスワードが正しくありません。ウォレットのパスワードをもう一度繰り返してください。"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -687,10 +687,11 @@
|
|||
"support_description_other_links": "다른 방법을 통해 커뮤니티에 가입하거나 파트너에게 연락하십시오.",
|
||||
"select_destination": "백업 파일의 대상을 선택하십시오.",
|
||||
"save_to_downloads": "다운로드에 저장",
|
||||
"auto_generate_subaddresses": "자동 생성 서브 아드 드레스",
|
||||
"invalid_password": "유효하지 않은 비밀번호",
|
||||
"unlock": "터놓다",
|
||||
"enter_wallet_password": "지갑 암호를 입력하십시오",
|
||||
"repeat_wallet_password": "지갑 암호를 반복하십시오",
|
||||
"wallet_password_is_empty": "지갑 암호는 비어 있습니다. 지갑 암호는 비어 있지 않아야합니다",
|
||||
"repeated_password_is_incorrect": "반복 된 비밀번호가 올바르지 않습니다. 지갑 암호를 다시 반복하십시오."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -685,10 +685,11 @@
|
|||
"support_description_other_links": "ကျွန်ုပ်တို့၏လူမှုအသိုင်းအဝိုင်းများသို့ 0 င်ရောက်ပါ",
|
||||
"select_destination": "အရန်ဖိုင်အတွက် ဦးတည်ရာကို ရွေးပါ။",
|
||||
"save_to_downloads": "ဒေါင်းလုဒ်များထံ သိမ်းဆည်းပါ။",
|
||||
"auto_generate_subaddresses": "အော်တို Generate Subaddresses",
|
||||
"invalid_password": "မမှန်ကန်သောစကားဝှက်",
|
||||
"unlock": "သော့ဖွင့်",
|
||||
"enter_wallet_password": "ပိုက်ဆံအိတ်စကားဝှက်ကိုရိုက်ထည့်ပါ",
|
||||
"repeat_wallet_password": "ပိုက်ဆံအိတ်စကားဝှက်ကိုပြန်လုပ်ပါ",
|
||||
"wallet_password_is_empty": "ပိုက်ဆံအိတ်စကားဝှက်သည်ဗလာဖြစ်သည်။ ပိုက်ဆံအိတ်စကားဝှက်သည်အချည်းနှီးဖြစ်သင့်သည်",
|
||||
"repeated_password_is_incorrect": "ထပ်ခါတလဲလဲစကားဝှက်မမှန်ကန်ပါ ကျေးဇူးပြုပြီးပိုက်ဆံအိတ်စကားဝှက်ကိုပြန်လုပ်ပါ။"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -634,6 +634,7 @@
|
|||
"setup_totp_recommended": "TOTP instellen (aanbevolen)",
|
||||
"disable_buy": "Koopactie uitschakelen",
|
||||
"disable_sell": "Verkoopactie uitschakelen",
|
||||
"auto_generate_subaddresses": "Automatisch subadressen genereren",
|
||||
"cake_2fa_preset": "Taart 2FA Voorinstelling",
|
||||
"narrow": "Smal",
|
||||
"normal": "Normaal",
|
||||
|
|
|
@ -634,6 +634,7 @@
|
|||
"setup_totp_recommended": "Skonfiguruj TOTP (zalecane)",
|
||||
"disable_buy": "Wyłącz akcję kupna",
|
||||
"disable_sell": "Wyłącz akcję sprzedaży",
|
||||
"auto_generate_subaddresses": "Automatycznie generuj podadresy",
|
||||
"cake_2fa_preset": "Ciasto 2FA Preset",
|
||||
"narrow": "Wąski",
|
||||
"normal": "Normalna",
|
||||
|
|
|
@ -633,6 +633,7 @@
|
|||
"setup_totp_recommended": "Configurar TOTP (recomendado)",
|
||||
"disable_buy": "Desativar ação de compra",
|
||||
"disable_sell": "Desativar ação de venda",
|
||||
"auto_generate_subaddresses": "Gerar subendereços automaticamente",
|
||||
"cake_2fa_preset": "Predefinição de bolo 2FA",
|
||||
"narrow": "Estreito",
|
||||
"normal": "Normal",
|
||||
|
|
|
@ -687,10 +687,11 @@
|
|||
"support_description_other_links": "Присоединяйтесь к нашим сообществам или охватите нас наших партнеров с помощью других методов",
|
||||
"select_destination": "Пожалуйста, выберите место для файла резервной копии.",
|
||||
"save_to_downloads": "Сохранить в загрузках",
|
||||
"auto_generate_subaddresses": "Авто генерируйте Subaddresses",
|
||||
"invalid_password": "Неверный пароль",
|
||||
"unlock": "Разблокировать",
|
||||
"enter_wallet_password": "Введите пароль кошелька",
|
||||
"repeat_wallet_password": "Повторите пароль кошелька",
|
||||
"wallet_password_is_empty": "Пароль кошелька пуст. Пароль кошелька не должен быть пустым",
|
||||
"repeated_password_is_incorrect": "Повторный пароль неверен. Пожалуйста, повторите пароль кошелька снова."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -685,10 +685,11 @@
|
|||
"support_description_other_links": "เข้าร่วมชุมชนของเราหรือเข้าถึงเราพันธมิตรของเราผ่านวิธีการอื่น ๆ",
|
||||
"select_destination": "โปรดเลือกปลายทางสำหรับไฟล์สำรอง",
|
||||
"save_to_downloads": "บันทึกลงดาวน์โหลด",
|
||||
"auto_generate_subaddresses": "Auto สร้าง subaddresses",
|
||||
"invalid_password": "รหัสผ่านไม่ถูกต้อง",
|
||||
"unlock": "ปลดล็อค",
|
||||
"enter_wallet_password": "ป้อนรหัสผ่านกระเป๋าเงิน",
|
||||
"repeat_wallet_password": "ทำซ้ำรหัสผ่านกระเป๋าเงิน",
|
||||
"wallet_password_is_empty": "รหัสผ่านกระเป๋าเงินว่างเปล่า รหัสผ่านกระเป๋าเงินไม่ควรว่างเปล่า",
|
||||
"repeated_password_is_incorrect": "รหัสผ่านซ้ำไม่ถูกต้อง โปรดทำซ้ำรหัสผ่านกระเป๋าเงินอีกครั้ง"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -632,6 +632,7 @@
|
|||
"setup_totp_recommended": "TOTP'yi kurun (Önerilir)",
|
||||
"disable_buy": "Satın alma işlemini devre dışı bırak",
|
||||
"disable_sell": "Satış işlemini devre dışı bırak",
|
||||
"auto_generate_subaddresses": "Alt adresleri otomatik olarak oluştur",
|
||||
"cake_2fa_preset": "Kek 2FA Ön Ayarı",
|
||||
"narrow": "Dar",
|
||||
"normal": "Normal",
|
||||
|
|
|
@ -634,6 +634,7 @@
|
|||
"setup_totp_recommended": "Налаштувати TOTP (рекомендовано)",
|
||||
"disable_buy": "Вимкнути дію покупки",
|
||||
"disable_sell": "Вимкнути дію продажу",
|
||||
"auto_generate_subaddresses": "Автоматично генерувати підадреси",
|
||||
"cake_2fa_preset": "Торт 2FA Preset",
|
||||
"narrow": "вузькі",
|
||||
"normal": "нормальний",
|
||||
|
|
|
@ -679,10 +679,11 @@
|
|||
"support_description_other_links": "ہماری برادریوں میں شامل ہوں یا دوسرے طریقوں سے ہمارے شراکت داروں تک پہنچیں",
|
||||
"select_destination": "۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﻝﺰﻨﻣ ﮯﯿﻟ ﮯﮐ ﻞﺋﺎﻓ ﭖﺍ ﮏﯿﺑ ﻡﺮﮐ ﮦﺍﺮﺑ",
|
||||
"save_to_downloads": "۔ﮟﯾﺮﮐ ﻅﻮﻔﺤﻣ ﮟﯿﻣ ﺯﮈﻮﻟ ﻥﺅﺍﮈ",
|
||||
"auto_generate_subaddresses": "آٹو سب ایڈریس تیار کرتا ہے",
|
||||
"invalid_password": "غلط پاسورڈ",
|
||||
"unlock": "غیر مقفل",
|
||||
"enter_wallet_password": "پرس کا پاس ورڈ درج کریں",
|
||||
"repeat_wallet_password": "بٹوے کا پاس ورڈ دہرائیں",
|
||||
"wallet_password_is_empty": "پرس کا پاس ورڈ خالی ہے۔ پرس کا پاس ورڈ خالی نہیں ہونا چاہئے",
|
||||
"repeated_password_is_incorrect": "بار بار پاس ورڈ غلط ہے۔ براہ کرم دوبارہ پرس کا پاس ورڈ دہرائیں۔"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -681,10 +681,11 @@
|
|||
"monero_light_theme": "Monero Light Akori",
|
||||
"select_destination": "Jọwọ yan ibi ti o nlo fun faili afẹyinti.",
|
||||
"save_to_downloads": "Fipamọ si Awọn igbasilẹ",
|
||||
"auto_generate_subaddresses": "Aṣiṣe Ibi-Afọwọkọ",
|
||||
"invalid_password": "Ọrọ igbaniwọle ti ko wulo",
|
||||
"unlock": "Sisalẹ",
|
||||
"enter_wallet_password": "Tẹ ọrọ igbaniwọle apamọwọ",
|
||||
"repeat_wallet_password": "Tun ọrọ igbaniwọle apamọwọ naa",
|
||||
"wallet_password_is_empty": "Ọrọ igbaniwọle apamọwọ ti ṣofo. Ọrọ igbaniwọle apamọwọ ko yẹ ki o ṣofo",
|
||||
"repeated_password_is_incorrect": "Ọrọ igbaniwọle tun jẹ aṣiṣe. Jọwọ tun ọrọigbaniwọle apamọwọ lẹẹkansi."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -686,10 +686,11 @@
|
|||
"monero_light_theme": "门罗币浅色主题",
|
||||
"select_destination": "请选择备份文件的目的地。",
|
||||
"save_to_downloads": "保存到下载",
|
||||
"auto_generate_subaddresses": "自动生成子辅助",
|
||||
"invalid_password": "无效的密码",
|
||||
"unlock": "开锁",
|
||||
"enter_wallet_password": "输入钱包密码",
|
||||
"repeat_wallet_password": "重复钱包密码",
|
||||
"wallet_password_is_empty": "钱包密码为空。钱包密码不应为空",
|
||||
"repeated_password_is_incorrect": "重复密码不正确。请再次重复钱包密码。"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,14 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
|
|||
APP_ANDROID_TYPE=$1
|
||||
|
||||
MONERO_COM_NAME="Monero.com"
|
||||
MONERO_COM_VERSION="1.5.1"
|
||||
MONERO_COM_BUILD_NUMBER=55
|
||||
MONERO_COM_VERSION="1.6.0"
|
||||
MONERO_COM_BUILD_NUMBER=56
|
||||
MONERO_COM_BUNDLE_ID="com.monero.app"
|
||||
MONERO_COM_PACKAGE="com.monero.app"
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="4.8.1"
|
||||
CAKEWALLET_BUILD_NUMBER=168
|
||||
CAKEWALLET_VERSION="4.9.0"
|
||||
CAKEWALLET_BUILD_NUMBER=169
|
||||
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
|
||||
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ HAVEN_VERSION=tags/v3.0.7
|
|||
HAVEN_SRC_DIR=${WORKDIR}/haven
|
||||
|
||||
git clone https://github.com/haven-protocol-org/haven-main.git ${HAVEN_SRC_DIR}
|
||||
git checkout ${HAVEN_VERSION}
|
||||
cd $HAVEN_SRC_DIR
|
||||
git checkout ${HAVEN_VERSION}
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
|
|||
APP_IOS_TYPE=$1
|
||||
|
||||
MONERO_COM_NAME="Monero.com"
|
||||
MONERO_COM_VERSION="1.5.1"
|
||||
MONERO_COM_BUILD_NUMBER=53
|
||||
MONERO_COM_VERSION="1.6.0"
|
||||
MONERO_COM_BUILD_NUMBER=54
|
||||
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="4.8.1"
|
||||
CAKEWALLET_BUILD_NUMBER=176
|
||||
CAKEWALLET_VERSION="4.9.0"
|
||||
CAKEWALLET_BUILD_NUMBER=178
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
HAVEN_NAME="Haven"
|
||||
|
|
|
@ -14,8 +14,8 @@ if [ -n "$1" ]; then
|
|||
fi
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="1.0.2"
|
||||
CAKEWALLET_BUILD_NUMBER=3
|
||||
CAKEWALLET_VERSION="1.1.0"
|
||||
CAKEWALLET_BUILD_NUMBER=4
|
||||
|
||||
if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
|
||||
echo "Wrong app type."
|
||||
|
|
|
@ -15,8 +15,8 @@ if [ -n "$1" ]; then
|
|||
fi
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="1.1.1"
|
||||
CAKEWALLET_BUILD_NUMBER=30
|
||||
CAKEWALLET_VERSION="1.2.0"
|
||||
CAKEWALLET_BUILD_NUMBER=31
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:translator/translator.dart';
|
||||
|
||||
const defaultLang = "en";
|
||||
const langs = [
|
||||
"ar", "bg", "cs", "de", "en", "es", "fr", "ha", "hi", "hr", "id", "it",
|
||||
"ja", "ko", "my", "nl", "pl", "pt", "ru", "th", "tr", "uk", "ur", "yo",
|
||||
"zh-cn" // zh, but Google Translate uses zh-cn for Chinese (Simplified)
|
||||
];
|
||||
final translator = GoogleTranslator();
|
||||
import 'utils/translation/arb_file_utils.dart';
|
||||
import 'utils/translation/translation_constants.dart';
|
||||
import 'utils/translation/translation_utils.dart';
|
||||
|
||||
void main(List<String> args) async {
|
||||
if (args.length != 2) {
|
||||
|
@ -23,44 +14,9 @@ void main(List<String> args) async {
|
|||
print('Appending "$name": "$text"');
|
||||
|
||||
for (var lang in langs) {
|
||||
final fileName = getFileName(lang);
|
||||
final fileName = getArbFileName(lang);
|
||||
final translation = await getTranslation(text, lang);
|
||||
|
||||
appendArbFile(fileName, name, translation);
|
||||
appendStringToArbFile(fileName, name, translation);
|
||||
}
|
||||
}
|
||||
|
||||
void appendArbFile(String fileName, String name, String text) {
|
||||
final file = File(fileName);
|
||||
final inputContent = file.readAsStringSync();
|
||||
final arbObj = json.decode(inputContent) as Map<String, dynamic>;
|
||||
|
||||
if (arbObj.containsKey(name)) {
|
||||
print("String $name already exists in $fileName!");
|
||||
return;
|
||||
}
|
||||
|
||||
arbObj.addAll({name: text});
|
||||
|
||||
final outputContent = json
|
||||
.encode(arbObj)
|
||||
.replaceAll('","', '",\n "')
|
||||
.replaceAll('{"', '{\n "')
|
||||
.replaceAll('"}', '"\n}')
|
||||
.replaceAll('":"', '": "');
|
||||
|
||||
file.writeAsStringSync(outputContent);
|
||||
}
|
||||
|
||||
|
||||
Future<String> getTranslation(String text, String lang) async {
|
||||
if (lang == defaultLang) return text;
|
||||
return (await translator.translate(text, from: defaultLang, to: lang)).text;
|
||||
}
|
||||
|
||||
String getFileName(String lang) {
|
||||
final shortLang = lang
|
||||
.split("-")
|
||||
.first;
|
||||
return "./res/values/strings_$shortLang.arb";
|
||||
}
|
||||
|
|
37
tool/translation_consistence.dart
Normal file
37
tool/translation_consistence.dart
Normal file
|
@ -0,0 +1,37 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'utils/translation/arb_file_utils.dart';
|
||||
import 'utils/translation/translation_constants.dart';
|
||||
import 'utils/translation/translation_utils.dart';
|
||||
|
||||
void main(List<String> args) async {
|
||||
print('Checking Consistency of all arb-files. Default: $defaultLang');
|
||||
|
||||
final doFix = args.contains("--fix");
|
||||
|
||||
if (doFix)
|
||||
print('Auto fixing enabled!\n');
|
||||
else
|
||||
print('Auto fixing disabled!\nRun with arg "--fix" to enable autofix\n');
|
||||
|
||||
final fileName = getArbFileName(defaultLang);
|
||||
final file = File(fileName);
|
||||
final arbObj = readArbFile(file);
|
||||
|
||||
for (var lang in langs) {
|
||||
final fileName = getArbFileName(lang);
|
||||
final missingKeys = getMissingKeysInArbFile(fileName, arbObj.keys);
|
||||
if (missingKeys.isNotEmpty) {
|
||||
final missingDefaults = <String, String>{};
|
||||
|
||||
missingKeys.forEach((key) {
|
||||
print('Missing in "$lang": "$key"');
|
||||
if (doFix)
|
||||
missingDefaults[key] = arbObj[key] as String;
|
||||
});
|
||||
|
||||
if (missingDefaults.isNotEmpty)
|
||||
await appendTranslations(lang, missingDefaults);
|
||||
}
|
||||
}
|
||||
}
|
66
tool/utils/translation/arb_file_utils.dart
Normal file
66
tool/utils/translation/arb_file_utils.dart
Normal file
|
@ -0,0 +1,66 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
void appendStringToArbFile(String fileName, String name, String text) {
|
||||
final file = File(fileName);
|
||||
final arbObj = readArbFile(file);
|
||||
|
||||
if (arbObj.containsKey(name)) {
|
||||
print("String $name already exists in $fileName!");
|
||||
return;
|
||||
}
|
||||
|
||||
arbObj.addAll({name: text});
|
||||
|
||||
final outputContent = json
|
||||
.encode(arbObj)
|
||||
.replaceAll('","', '",\n "')
|
||||
.replaceAll('{"', '{\n "')
|
||||
.replaceAll('"}', '"\n}')
|
||||
.replaceAll('":"', '": "');
|
||||
|
||||
file.writeAsStringSync(outputContent);
|
||||
}
|
||||
|
||||
void appendStringsToArbFile(String fileName, Map<String, String> strings) {
|
||||
final file = File(fileName);
|
||||
final arbObj = readArbFile(file);
|
||||
|
||||
arbObj.addAll(strings);
|
||||
|
||||
final outputContent = json
|
||||
.encode(arbObj)
|
||||
.replaceAll('","', '",\n "')
|
||||
.replaceAll('{"', '{\n "')
|
||||
.replaceAll('"}', '"\n}')
|
||||
.replaceAll('":"', '": "');
|
||||
|
||||
file.writeAsStringSync(outputContent);
|
||||
}
|
||||
|
||||
Map<String, dynamic> readArbFile(File file) {
|
||||
final inputContent = file.readAsStringSync();
|
||||
|
||||
return json.decode(inputContent) as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
String getArbFileName(String lang) {
|
||||
final shortLang = lang
|
||||
.split("-")
|
||||
.first;
|
||||
return "./res/values/strings_$shortLang.arb";
|
||||
}
|
||||
|
||||
List<String> getMissingKeysInArbFile(String fileName, Iterable<String> langKeys) {
|
||||
final file = File(fileName);
|
||||
final arbObj = readArbFile(file);
|
||||
final results = <String>[];
|
||||
|
||||
for (var langKey in langKeys) {
|
||||
if (!arbObj.containsKey(langKey)) {
|
||||
results.add(langKey);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
6
tool/utils/translation/translation_constants.dart
Normal file
6
tool/utils/translation/translation_constants.dart
Normal file
|
@ -0,0 +1,6 @@
|
|||
const defaultLang = "en";
|
||||
const langs = [
|
||||
"ar", "bg", "cs", "de", "en", "es", "fr", "ha", "hi", "hr", "id", "it",
|
||||
"ja", "ko", "my", "nl", "pl", "pt", "ru", "th", "tr", "uk", "ur", "yo",
|
||||
"zh-cn" // zh, but Google Translate uses zh-cn for Chinese (Simplified)
|
||||
];
|
37
tool/utils/translation/translation_utils.dart
Normal file
37
tool/utils/translation/translation_utils.dart
Normal file
|
@ -0,0 +1,37 @@
|
|||
import 'package:translator/translator.dart';
|
||||
|
||||
import 'arb_file_utils.dart';
|
||||
import 'translation_constants.dart';
|
||||
|
||||
final translator = GoogleTranslator();
|
||||
|
||||
Future<void> appendTranslation(String lang, String key, String text) async {
|
||||
final fileName = getArbFileName(lang);
|
||||
final translation = await getTranslation(text, lang);
|
||||
|
||||
appendStringToArbFile(fileName, key, translation);
|
||||
}
|
||||
|
||||
Future<void> appendTranslations(String lang, Map<String, String> defaults) async {
|
||||
final fileName = getArbFileName(lang);
|
||||
final translations = <String, String>{};
|
||||
|
||||
for (var key in defaults.keys) {
|
||||
final value = defaults[key]!;
|
||||
|
||||
if (value.contains("{")) continue;
|
||||
final translation = await getTranslation(value, lang);
|
||||
|
||||
translations[key] = translation;
|
||||
}
|
||||
|
||||
print(translations);
|
||||
|
||||
appendStringsToArbFile(fileName, translations);
|
||||
}
|
||||
|
||||
Future<String> getTranslation(String text, String lang) async {
|
||||
if (lang == defaultLang) return text;
|
||||
return (await translator.translate(text, from: defaultLang, to: lang)).text;
|
||||
}
|
||||
|
Loading…
Reference in a new issue