Merge remote-tracking branch 'origin/main' into CW-453-bitcoin-silent-payments

This commit is contained in:
Rafael Saes 2023-11-30 14:39:02 -03:00
commit fe5f0018b6
116 changed files with 2964 additions and 972 deletions

View file

@ -38,6 +38,8 @@ jobs:
sudo mkdir -p /opt/android sudo mkdir -p /opt/android
sudo chown $USER /opt/android sudo chown $USER /opt/android
cd /opt/android cd /opt/android
-y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install cargo-ndk
git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF
cd cake_wallet/scripts/android/ cd cake_wallet/scripts/android/
./install_ndk.sh ./install_ndk.sh
@ -134,6 +136,7 @@ jobs:
echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
echo "const robinhoodCIdApiSecret = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart echo "const robinhoodCIdApiSecret = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
- name: Rename app - name: Rename app
run: echo -e "id=com.cakewallet.test\nname=$GITHUB_HEAD_REF" > /opt/android/cake_wallet/android/app.properties run: echo -e "id=com.cakewallet.test\nname=$GITHUB_HEAD_REF" > /opt/android/cake_wallet/android/app.properties

View file

@ -1,4 +1,2 @@
UI enhancements Monero Polyseed support, under Advanced privacy settings, create and restore from a 16 words phrase and without the need to remember the wallet creation date
Privacy settings enhancements Minor bug fixes and enhancements
Tablet/iPad fixes
Bug fixes

View file

@ -1,5 +1,3 @@
WalletConnect enhancements Monero Polyseed support, under Advanced privacy settings, create and restore from a 16 words phrase and without the need to remember the wallet creation date
UI enhancements Add Ethereum NFTs tab to see all of your purchased NFTs
Privacy settings enhancements Minor bug fixes and enhancements
Tablet/iPad fixes
Bug fixes

View file

@ -2,6 +2,7 @@ cd scripts/android
source ./app_env.sh cakewallet source ./app_env.sh cakewallet
./app_config.sh ./app_config.sh
cd ../.. && flutter pub get cd ../.. && flutter pub get
flutter packages pub run tool/generate_localization.dart
cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. 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_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_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..

View file

@ -633,6 +633,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
socks5_proxy:
dependency: transitive
description:
name: socks5_proxy
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
source_gen: source_gen:
dependency: transitive dependency: transitive
description: description:
@ -713,6 +721,15 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
tor:
dependency: transitive
description:
path: "."
ref: main
resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
url: "https://github.com/cake-tech/tor.git"
source: git
version: "0.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:

View file

@ -1,11 +0,0 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}

View file

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

View file

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

View file

@ -1,12 +0,0 @@
//
// Generated file. Do not edit.
//
import FlutterMacOS
import Foundation
import path_provider_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
}

View file

@ -1,11 +0,0 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=C:\Users\borod\flutter
FLUTTER_APPLICATION_PATH=C:\cake_wallet\cw_bitcoin_cash
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=0.0.1
FLUTTER_BUILD_NUMBER=0.0.1
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=.dart_tool/package_config.json

View file

@ -1,12 +0,0 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=C:\Users\borod\flutter"
export "FLUTTER_APPLICATION_PATH=C:\cake_wallet\cw_bitcoin_cash"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=0.0.1"
export "FLUTTER_BUILD_NUMBER=0.0.1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"

View file

@ -1,11 +0,0 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void RegisterPlugins(flutter::PluginRegistry* registry) {
}

View file

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

View file

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

View file

@ -84,7 +84,41 @@ final dates = {
"2020-8": 2153983, "2020-8": 2153983,
"2020-9": 2176466, "2020-9": 2176466,
"2020-10": 2198453, "2020-10": 2198453,
"2020-11": 2220000 "2020-11": 2220000,
"2020-12": 2242240,
"2021-1": 2264584,
"2021-2": 2286892,
"2021-3": 2307079,
"2021-4": 2329385,
"2021-5": 2351004,
"2021-6": 2373306,
"2021-7": 2394882,
"2021-8": 2417162,
"2021-9": 2439490,
"2021-10": 2461020,
"2021-11": 2483377,
"2021-12": 2504932,
"2022-1": 2527316,
"2022-2": 2549605,
"2022-3": 2569711,
"2022-4": 2591995,
"2022-5": 2613603,
"2022-6": 2635840,
"2022-7": 2657395,
"2022-8": 2679705,
"2022-9": 2701991,
"2022-10": 2723607,
"2022-11": 2745899,
"2022-12": 2767427,
"2023-1": 2789763,
"2023-2": 2811996,
"2023-3": 2832118,
"2023-4": 2854365,
"2023-5": 2875972,
"2023-6": 2898234,
"2023-7": 2919771,
"2023-8": 2942045,
"2023-9": 2964280
}; };
int getMoneroHeigthByDate({required DateTime date}) { int getMoneroHeigthByDate({required DateTime date}) {

View file

@ -6,6 +6,7 @@ import 'package:hive/hive.dart';
import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:http/io_client.dart' as ioc; import 'package:http/io_client.dart' as ioc;
import 'package:tor/tor.dart';
part 'node.g.dart'; part 'node.g.dart';
@ -92,6 +93,8 @@ class Node extends HiveObject with Keyable {
} }
} }
bool get isValidProxyAddress => socksProxyAddress?.contains(':') ?? false;
@override @override
bool operator ==(other) => bool operator ==(other) =>
other is Node && other is Node &&
@ -129,9 +132,7 @@ class Node extends HiveObject with Keyable {
try { try {
switch (type) { switch (type) {
case WalletType.monero: case WalletType.monero:
return useSocksProxy return requestMoneroNode();
? requestNodeWithProxy(socksProxyAddress ?? '')
: requestMoneroNode();
case WalletType.bitcoin: case WalletType.bitcoin:
return requestElectrumServer(); return requestElectrumServer();
case WalletType.litecoin: case WalletType.litecoin:
@ -154,6 +155,9 @@ class Node extends HiveObject with Keyable {
} }
Future<bool> requestMoneroNode() async { Future<bool> requestMoneroNode() async {
if (uri.toString().contains(".onion") || useSocksProxy) {
return await requestNodeWithProxy();
}
final path = '/json_rpc'; final path = '/json_rpc';
final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path); final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
final realm = 'monero-rpc'; final realm = 'monero-rpc';
@ -205,11 +209,17 @@ class Node extends HiveObject with Keyable {
} }
} }
Future<bool> requestNodeWithProxy(String proxy) async { Future<bool> requestNodeWithProxy() async {
if (proxy.isEmpty || !proxy.contains(':')) { if (!isValidProxyAddress && !Tor.instance.enabled) {
return false; return false;
} }
final proxyAddress = proxy.split(':')[0];
String? proxy = socksProxyAddress;
if ((proxy?.isEmpty ?? true) && Tor.instance.enabled) {
proxy = "${InternetAddress.loopbackIPv4.address}:${Tor.instance.port}";
}
final proxyAddress = proxy!.split(':')[0];
final proxyPort = int.parse(proxy.split(':')[1]); final proxyPort = int.parse(proxy.split(':')[1]);
try { try {
final socket = await Socket.connect(proxyAddress, proxyPort, timeout: Duration(seconds: 5)); final socket = await Socket.connect(proxyAddress, proxyPort, timeout: Duration(seconds: 5));

View file

@ -44,6 +44,8 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
String? get privateKey => null; String? get privateKey => null;
String? get hexSeed => null;
Object get keys; Object get keys;
WalletAddresses get walletAddresses; WalletAddresses get walletAddresses;

View file

@ -271,10 +271,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: hive_generator name: hive_generator
sha256: "81fd20125cb2ce8fd23623d7744ffbaf653aae93706c9bd3bf7019ea0ace3938" sha256: "06cb8f58ace74de61f63500564931f9505368f45f98958bd7a6c35ba24159db4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.3" version: "2.0.1"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@ -407,50 +407,50 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: path_provider name: path_provider
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.12" version: "2.1.1"
path_provider_android: path_provider_android:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.22" version: "2.2.1"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.3.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
name: path_provider_linux name: path_provider_linux
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.2.1"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.5" version: "2.1.1"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.3" version: "2.2.1"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -528,6 +528,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
socks5_proxy:
dependency: "direct main"
description:
name: socks5_proxy
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
source_gen: source_gen:
dependency: transitive dependency: transitive
description: description:
@ -608,6 +616,15 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
tor:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
url: "https://github.com/cake-tech/tor.git"
source: git
version: "0.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -666,4 +683,4 @@ packages:
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=3.0.0 <4.0.0" dart: ">=3.0.0 <4.0.0"
flutter: ">=3.0.0" flutter: ">=3.7.0"

View file

@ -19,6 +19,11 @@ dependencies:
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.18.0 intl: ^0.18.0
encrypt: ^5.0.1 encrypt: ^5.0.1
socks5_proxy: ^1.0.4
tor:
git:
url: https://github.com/cake-tech/tor.git
ref: main
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -26,7 +31,7 @@ dev_dependencies:
build_runner: ^2.1.11 build_runner: ^2.1.11
build_resolvers: ^2.0.9 build_resolvers: ^2.0.9
mobx_codegen: ^2.0.7 mobx_codegen: ^2.0.7
hive_generator: ^1.1.3 hive_generator: ^2.0.1
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec

View file

@ -17,7 +17,6 @@ dependencies:
mobx: ^2.0.7+4 mobx: ^2.0.7+4
bip39: ^1.0.6 bip39: ^1.0.6
bip32: ^2.0.0 bip32: ^2.0.0
ed25519_hd_key: ^2.2.0
hex: ^0.2.0 hex: ^0.2.0
http: ^1.1.0 http: ^1.1.0
shared_preferences: ^2.0.15 shared_preferences: ^2.0.15

View file

@ -414,50 +414,50 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: path_provider name: path_provider
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.12" version: "2.1.1"
path_provider_android: path_provider_android:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.22" version: "2.2.1"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.3.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
name: path_provider_linux name: path_provider_linux
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.2.1"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.5" version: "2.1.1"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130 sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.2.1"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -535,6 +535,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
socks5_proxy:
dependency: transitive
description:
name: socks5_proxy
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
source_gen: source_gen:
dependency: transitive dependency: transitive
description: description:
@ -615,6 +623,15 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
tor:
dependency: transitive
description:
path: "."
ref: main
resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
url: "https://github.com/cake-tech/tor.git"
source: git
version: "0.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -673,4 +690,4 @@ packages:
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=3.0.0 <4.0.0" dart: ">=3.0.0 <4.0.0"
flutter: ">=3.0.0" flutter: ">=3.7.0"

View file

@ -237,50 +237,50 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider name: path_provider
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.12" version: "2.1.1"
path_provider_android: path_provider_android:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.22" version: "2.2.1"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.3.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
name: path_provider_linux name: path_provider_linux
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.2.1"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.5" version: "2.1.1"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130 sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.2.1"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -301,10 +301,19 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: pointycastle name: pointycastle
sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.6.2" version: "3.7.3"
polyseed:
dependency: transitive
description:
path: "."
ref: HEAD
resolved-ref: "504d58a5b147fccd3bc85a25f2e72fb32771ddd7"
url: "https://github.com/cake-tech/polyseed_dart.git"
source: git
version: "0.0.1"
process: process:
dependency: transitive dependency: transitive
description: description:
@ -318,6 +327,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
socks5_proxy:
dependency: transitive
description:
name: socks5_proxy
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@ -366,6 +383,15 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.5.1"
tor:
dependency: transitive
description:
path: "."
ref: main
resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
url: "https://github.com/cake-tech/tor.git"
source: git
version: "0.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -399,5 +425,5 @@ packages:
source: hosted source: hosted
version: "0.2.0+3" version: "0.2.0+3"
sdks: sdks:
dart: ">=3.0.0 <4.0.0" dart: ">=3.0.6 <4.0.0"
flutter: ">=3.0.0" flutter: ">=3.7.0"

View file

@ -374,6 +374,35 @@ extern "C"
return true; return true;
} }
bool restore_wallet_from_spend_key(char *path, char *password, char *seed, char *language, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error)
{
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->createDeterministicWalletFromSpendKey(
std::string(path),
std::string(password),
std::string(language),
_networkType,
(uint64_t)restoreHeight,
std::string(spendKey));
int status;
std::string errorString;
wallet->statusWithErrorString(status, errorString);
if (status != Monero::Wallet::Status_Ok || !errorString.empty())
{
error = strdup(errorString.c_str());
return false;
}
// Cache Raw to support Polyseed
wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
change_current_wallet(wallet);
return true;
}
bool load_wallet(char *path, char *password, int32_t nettype) bool load_wallet(char *path, char *password, int32_t nettype)
{ {
nice(19); nice(19);
@ -438,6 +467,11 @@ extern "C"
const char *seed() const char *seed()
{ {
std::string _rawSeed = get_current_wallet()->getCacheAttribute("cakewallet.seed");
if (!_rawSeed.empty())
{
return strdup(_rawSeed.c_str());
}
return strdup(get_current_wallet()->seed().c_str()); return strdup(get_current_wallet()->seed().c_str());
} }

View file

@ -14,6 +14,9 @@ typedef restore_wallet_from_seed = Int8 Function(
typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>,
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>); Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
typedef restore_wallet_from_spend_key = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>,
Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
typedef is_wallet_exist = Int8 Function(Pointer<Utf8>); typedef is_wallet_exist = Int8 Function(Pointer<Utf8>);
typedef load_wallet = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Int8); typedef load_wallet = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Int8);

View file

@ -14,6 +14,9 @@ typedef RestoreWalletFromSeed = int Function(
typedef RestoreWalletFromKeys = int Function(Pointer<Utf8>, Pointer<Utf8>, typedef RestoreWalletFromKeys = int Function(Pointer<Utf8>, Pointer<Utf8>,
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, int, int, Pointer<Utf8>); Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, int, int, Pointer<Utf8>);
typedef RestoreWalletFromSpendKey = int Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>,
Pointer<Utf8>, Pointer<Utf8>, int, int, Pointer<Utf8>);
typedef IsWalletExist = int Function(Pointer<Utf8>); typedef IsWalletExist = int Function(Pointer<Utf8>);
typedef LoadWallet = int Function(Pointer<Utf8>, Pointer<Utf8>, int); typedef LoadWallet = int Function(Pointer<Utf8>, Pointer<Utf8>, int);

View file

@ -5,7 +5,6 @@ import 'package:cw_monero/api/convert_utf8_to_string.dart';
import 'package:cw_monero/api/signatures.dart'; import 'package:cw_monero/api/signatures.dart';
import 'package:cw_monero/api/types.dart'; import 'package:cw_monero/api/types.dart';
import 'package:cw_monero/api/monero_api.dart'; import 'package:cw_monero/api/monero_api.dart';
import 'package:cw_monero/api/wallet.dart';
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_creation_exception.dart';
import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart';
@ -25,6 +24,11 @@ final restoreWalletFromKeysNative = moneroApi
'restore_wallet_from_keys') 'restore_wallet_from_keys')
.asFunction<RestoreWalletFromKeys>(); .asFunction<RestoreWalletFromKeys>();
final restoreWalletFromSpendKeyNative = moneroApi
.lookup<NativeFunction<restore_wallet_from_spend_key>>(
'restore_wallet_from_spend_key')
.asFunction<RestoreWalletFromSpendKey>();
final isWalletExistNative = moneroApi final isWalletExistNative = moneroApi
.lookup<NativeFunction<is_wallet_exist>>('is_wallet_exist') .lookup<NativeFunction<is_wallet_exist>>('is_wallet_exist')
.asFunction<IsWalletExist>(); .asFunction<IsWalletExist>();
@ -141,6 +145,42 @@ void restoreWalletFromKeysSync(
} }
} }
void restoreWalletFromSpendKeySync(
{required String path,
required String password,
required String seed,
required String language,
required String spendKey,
int nettype = 0,
int restoreHeight = 0}) {
final pathPointer = path.toNativeUtf8();
final passwordPointer = password.toNativeUtf8();
final seedPointer = seed.toNativeUtf8();
final languagePointer = language.toNativeUtf8();
final spendKeyPointer = spendKey.toNativeUtf8();
final errorMessagePointer = ''.toNativeUtf8();
final isWalletRestored = restoreWalletFromSpendKeyNative(
pathPointer,
passwordPointer,
seedPointer,
languagePointer,
spendKeyPointer,
nettype,
restoreHeight,
errorMessagePointer) !=
0;
calloc.free(pathPointer);
calloc.free(passwordPointer);
calloc.free(languagePointer);
calloc.free(spendKeyPointer);
if (!isWalletRestored) {
throw WalletRestoreFromKeysException(
message: convertUTF8ToString(pointer: errorMessagePointer));
}
}
void loadWallet({ void loadWallet({
required String path, required String path,
required String password, required String password,
@ -194,6 +234,23 @@ void _restoreFromKeys(Map<String, dynamic> args) {
spendKey: spendKey); spendKey: spendKey);
} }
void _restoreFromSpendKey(Map<String, dynamic> args) {
final path = args['path'] as String;
final password = args['password'] as String;
final seed = args['seed'] as String;
final language = args['language'] as String;
final spendKey = args['spendKey'] as String;
final restoreHeight = args['restoreHeight'] as int;
restoreWalletFromSpendKeySync(
path: path,
password: password,
seed: seed,
language: language,
restoreHeight: restoreHeight,
spendKey: spendKey);
}
Future<void> _openWallet(Map<String, String> args) async => Future<void> _openWallet(Map<String, String> args) async =>
loadWallet(path: args['path'] as String, password: args['password'] as String); loadWallet(path: args['path'] as String, password: args['password'] as String);
@ -251,4 +308,22 @@ Future<void> restoreFromKeys(
'restoreHeight': restoreHeight 'restoreHeight': restoreHeight
}); });
Future<void> restoreFromSpendKey(
{required String path,
required String password,
required String seed,
required String language,
required String spendKey,
int nettype = 0,
int restoreHeight = 0}) async =>
compute<Map<String, Object>, void>(_restoreFromSpendKey, {
'path': path,
'password': password,
'seed': seed,
'language': language,
'spendKey': spendKey,
'nettype': nettype,
'restoreHeight': restoreHeight
});
Future<bool> isWalletExist({required String path}) => compute(_isWalletExist, path); Future<bool> isWalletExist({required String path}) => compute(_isWalletExist, path);

View file

@ -29,6 +29,7 @@ import 'package:cw_monero/monero_transaction_info.dart';
import 'package:cw_monero/monero_unspent.dart'; import 'package:cw_monero/monero_unspent.dart';
import 'package:cw_monero/monero_wallet_addresses.dart'; import 'package:cw_monero/monero_wallet_addresses.dart';
import 'package:cw_monero/pending_monero_transaction.dart'; import 'package:cw_monero/pending_monero_transaction.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
@ -78,6 +79,8 @@ abstract class MoneroWalletBase
Box<UnspentCoinsInfo> unspentCoinsInfo; Box<UnspentCoinsInfo> unspentCoinsInfo;
void Function(FlutterErrorDetails)? _onError;
@override @override
late MoneroWalletAddresses walletAddresses; late MoneroWalletAddresses walletAddresses;
@ -388,6 +391,7 @@ abstract class MoneroWalletBase
} }
Future<void> updateUnspent() async { Future<void> updateUnspent() async {
try {
refreshCoins(walletAddresses.account!.id); refreshCoins(walletAddresses.account!.id);
unspentCoins.clear(); unspentCoins.clear();
@ -397,7 +401,11 @@ abstract class MoneroWalletBase
final coin = getCoin(i); final coin = getCoin(i);
if (coin.spent == 0) { if (coin.spent == 0) {
final unspent = MoneroUnspent.fromCoinsInfoRow(coin); final unspent = MoneroUnspent.fromCoinsInfoRow(coin);
unspent.isChange = transaction_history.getTransaction(unspent.hash).direction == 1; if (unspent.hash.isNotEmpty) {
unspent.isChange = transaction_history
.getTransaction(unspent.hash)
.direction == 1;
}
unspentCoins.add(unspent); unspentCoins.add(unspent);
} }
} }
@ -428,6 +436,14 @@ abstract class MoneroWalletBase
await _refreshUnspentCoinsInfo(); await _refreshUnspentCoinsInfo();
_askForUpdateBalance(); _askForUpdateBalance();
} catch (e, s) {
print(e.toString());
_onError?.call(FlutterErrorDetails(
exception: e,
stack: s,
library: this.runtimeType.toString(),
));
}
} }
Future<void> _addCoinInfo(MoneroUnspent coin) async { Future<void> _addCoinInfo(MoneroUnspent coin) async {
@ -632,4 +648,7 @@ abstract class MoneroWalletBase
walletAddresses.updateSubaddressList(accountIndex: account?.id ?? 0); walletAddresses.updateSubaddressList(accountIndex: account?.id ?? 0);
} }
} }
@override
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
} }

View file

@ -7,16 +7,20 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager; import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
import 'package:cw_monero/monero_wallet.dart'; import 'package:cw_monero/monero_wallet.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:polyseed/polyseed.dart';
import 'package:polyseed/src/utils/key_utils.dart';
class MoneroNewWalletCredentials extends WalletCredentials { class MoneroNewWalletCredentials extends WalletCredentials {
MoneroNewWalletCredentials({required String name, required this.language, String? password}) MoneroNewWalletCredentials({required String name, required this.language, required this.isPolyseed, String? password})
: super(name: name, password: password); : super(name: name, password: password);
final String language; final String language;
final bool isPolyseed;
} }
class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials { class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials {
@ -68,10 +72,17 @@ class MoneroWalletService extends WalletService<
Future<MoneroWallet> create(MoneroNewWalletCredentials credentials, {bool? isTestnet}) async { Future<MoneroWallet> create(MoneroNewWalletCredentials credentials, {bool? isTestnet}) async {
try { try {
final path = await pathForWallet(name: credentials.name, type: getType()); final path = await pathForWallet(name: credentials.name, type: getType());
if (credentials.isPolyseed) {
final polyseed = Polyseed.create();
final lang = PolyseedLang.getByEnglishName(credentials.language);
return _restoreFromPolyseed(
path, credentials.password!, polyseed, credentials.walletInfo!, lang);
}
await monero_wallet_manager.createWallet( await monero_wallet_manager.createWallet(
path: path, path: path, password: credentials.password!, language: credentials.language);
password: credentials.password!,
language: credentials.language);
final wallet = MoneroWallet( final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource); walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
await wallet.init(); await wallet.init();
@ -215,6 +226,12 @@ class MoneroWalletService extends WalletService<
@override @override
Future<MoneroWallet> restoreFromSeed( Future<MoneroWallet> restoreFromSeed(
MoneroRestoreWalletFromSeedCredentials credentials, {bool? isTestnet}) async { MoneroRestoreWalletFromSeedCredentials credentials, {bool? isTestnet}) async {
// Restore from Polyseed
if (Polyseed.isValidSeed(credentials.mnemonic)) {
return restoreFromPolyseed(credentials);
}
try { try {
final path = await pathForWallet(name: credentials.name, type: getType()); final path = await pathForWallet(name: credentials.name, type: getType());
await monero_wallet_manager.restoreFromSeed( await monero_wallet_manager.restoreFromSeed(
@ -234,6 +251,45 @@ class MoneroWalletService extends WalletService<
} }
} }
Future<MoneroWallet> restoreFromPolyseed(MoneroRestoreWalletFromSeedCredentials credentials) async {
try {
final path = await pathForWallet(name: credentials.name, type: getType());
final polyseedCoin = PolyseedCoin.POLYSEED_MONERO;
final lang = PolyseedLang.getByPhrase(credentials.mnemonic);
final polyseed = Polyseed.decode(credentials.mnemonic, lang, polyseedCoin);
return _restoreFromPolyseed(path, credentials.password!, polyseed, credentials.walletInfo!, lang);
} catch (e) {
// TODO: Implement Exception for wallet list service.
print('MoneroWalletsManager Error: $e');
rethrow;
}
}
Future<MoneroWallet> _restoreFromPolyseed(String path, String password, Polyseed polyseed,
WalletInfo walletInfo, PolyseedLang lang,
{PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO}) async {
final height = getMoneroHeigthByDate(
date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000));
final spendKey = keyToHexString(polyseed.generateKey(coin, 32));
walletInfo.isRecovery = true;
walletInfo.restoreHeight = height;
await monero_wallet_manager.restoreFromSpendKey(
path: path,
password: password,
seed: polyseed.encode(lang, coin),
language: lang.nameEnglish,
restoreHeight: height,
spendKey: spendKey);
final wallet = MoneroWallet(
walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
await wallet.init();
return wallet;
}
Future<void> repairOldAndroidWallet(String name) async { Future<void> repairOldAndroidWallet(String name) async {
try { try {
if (!Platform.isAndroid) { if (!Platform.isAndroid) {

View file

@ -234,7 +234,6 @@ extern "C"
} }
void setUnlocked(bool unlocked); void setUnlocked(bool unlocked);
}; };
Monero::Coins *m_coins; Monero::Coins *m_coins;
@ -375,6 +374,35 @@ extern "C"
return true; return true;
} }
bool restore_wallet_from_spend_key(char *path, char *password, char *seed, char *language, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error)
{
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->createDeterministicWalletFromSpendKey(
std::string(path),
std::string(password),
std::string(language),
_networkType,
(uint64_t)restoreHeight,
std::string(spendKey));
int status;
std::string errorString;
wallet->statusWithErrorString(status, errorString);
if (status != Monero::Wallet::Status_Ok || !errorString.empty())
{
error = strdup(errorString.c_str());
return false;
}
// Cache Raw to support Polyseed
wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
change_current_wallet(wallet);
return true;
}
bool load_wallet(char *path, char *password, int32_t nettype) bool load_wallet(char *path, char *password, int32_t nettype)
{ {
nice(19); nice(19);
@ -439,6 +467,11 @@ extern "C"
const char *seed() const char *seed()
{ {
std::string _rawSeed = get_current_wallet()->getCacheAttribute("cakewallet.seed");
if (!_rawSeed.empty())
{
return strdup(_rawSeed.c_str());
}
return strdup(get_current_wallet()->seed().c_str()); return strdup(get_current_wallet()->seed().c_str());
} }
@ -842,6 +875,12 @@ extern "C"
return m_transaction_history->count(); return m_transaction_history->count();
} }
TransactionInfoRow* get_transaction(char * txId)
{
Monero::TransactionInfo *row = m_transaction_history->transaction(std::string(txId));
return new TransactionInfoRow(row);
}
int LedgerExchange( int LedgerExchange(
unsigned char *command, unsigned char *command,
unsigned int cmd_len, unsigned int cmd_len,
@ -971,6 +1010,15 @@ extern "C"
return result; return result;
} }
void freeze_coin(int index)
{
m_coins->setFrozen(index);
}
void thaw_coin(int index)
{
m_coins->thaw(index);
}
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -414,50 +414,50 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: path_provider name: path_provider
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.12" version: "2.1.1"
path_provider_android: path_provider_android:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.22" version: "2.2.1"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.3.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
name: path_provider_linux name: path_provider_linux
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.2.1"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.5" version: "2.1.1"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130 sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.2.1"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -478,10 +478,19 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: pointycastle name: pointycastle
sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.6.2" version: "3.7.3"
polyseed:
dependency: "direct main"
description:
path: "."
ref: HEAD
resolved-ref: "504d58a5b147fccd3bc85a25f2e72fb32771ddd7"
url: "https://github.com/cake-tech/polyseed_dart.git"
source: git
version: "0.0.1"
pool: pool:
dependency: transitive dependency: transitive
description: description:
@ -535,6 +544,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
socks5_proxy:
dependency: transitive
description:
name: socks5_proxy
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
source_gen: source_gen:
dependency: transitive dependency: transitive
description: description:
@ -615,6 +632,15 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
tor:
dependency: transitive
description:
path: "."
ref: main
resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
url: "https://github.com/cake-tech/tor.git"
source: git
version: "0.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -672,5 +698,5 @@ packages:
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=3.0.0 <4.0.0" dart: ">=3.0.6 <4.0.0"
flutter: ">=3.0.0" flutter: ">=3.7.0"

View file

@ -19,6 +19,9 @@ dependencies:
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.18.0 intl: ^0.18.0
encrypt: ^5.0.1 encrypt: ^5.0.1
polyseed:
git:
url: https://github.com/cake-tech/polyseed_dart.git
cw_core: cw_core:
path: ../cw_core path: ../cw_core

View file

@ -58,13 +58,13 @@ abstract class NanoWalletBase
} }
} }
final String _mnemonic; String _mnemonic;
final String _password; final String _password;
final DerivationType _derivationType; DerivationType _derivationType;
String? _privateKey; String? _privateKey;
String? _publicAddress; String? _publicAddress;
String? _seedKey; String? _hexSeed;
String? _representativeAddress; String? _representativeAddress;
Timer? _receiveTimer; Timer? _receiveTimer;
@ -85,22 +85,26 @@ abstract class NanoWalletBase
// initialize the different forms of private / public key we'll need: // initialize the different forms of private / public key we'll need:
Future<void> init() async { Future<void> init() async {
if (_derivationType == DerivationType.unknown) {
_derivationType = DerivationType.nano;
}
final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd"; final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd";
// our "mnemonic" is actually a seedkey: // our "mnemonic" is actually a hex form seed:
if (!_mnemonic.contains(' ')) { if (!_mnemonic.contains(' ')) {
_seedKey = _mnemonic; _hexSeed = _mnemonic;
_mnemonic = "";
} }
if (_seedKey == null) { if (_hexSeed == null) {
if (_derivationType == DerivationType.nano) { if (_derivationType == DerivationType.nano) {
_seedKey = bip39.mnemonicToEntropy(_mnemonic).toUpperCase(); _hexSeed = bip39.mnemonicToEntropy(_mnemonic).toUpperCase();
} else { } else {
_seedKey = await NanoUtil.hdMnemonicListToSeed(_mnemonic.split(' ')); _hexSeed = await NanoUtil.hdMnemonicListToSeed(_mnemonic.split(' '));
} }
} }
_privateKey = await NanoUtil.uniSeedToPrivate(_seedKey!, 0, type); _privateKey = await NanoUtil.uniSeedToPrivate(_hexSeed!, 0, type);
_publicAddress = await NanoUtil.uniSeedToAddress(_seedKey!, 0, type); _publicAddress = await NanoUtil.uniSeedToAddress(_hexSeed!, 0, type);
this.walletInfo.address = _publicAddress!; this.walletInfo.address = _publicAddress!;
await walletAddresses.init(); await walletAddresses.init();
@ -182,9 +186,9 @@ abstract class NanoWalletBase
final block = await _client.constructSendBlock( final block = await _client.constructSendBlock(
amountRaw: amt.toString(), amountRaw: amt.toString(),
destinationAddress: credentials.outputs.first.isParsedAddress destinationAddress: txOut.isParsedAddress
? credentials.outputs.first.extractedAddress! ? txOut.extractedAddress!
: credentials.outputs.first.address, : txOut.address,
privateKey: _privateKey!, privateKey: _privateKey!,
balanceAfterTx: runningBalance, balanceAfterTx: runningBalance,
previousHash: previousHash, previousHash: previousHash,
@ -275,11 +279,11 @@ abstract class NanoWalletBase
@override @override
NanoWalletKeys get keys { NanoWalletKeys get keys {
return NanoWalletKeys(seedKey: _seedKey!); return NanoWalletKeys(seedKey: _hexSeed!);
} }
@override @override
String? get privateKey => _seedKey!; String? get privateKey => _privateKey!;
@override @override
Future<void> rescan({required int height}) async { Future<void> rescan({required int height}) async {
@ -297,7 +301,9 @@ abstract class NanoWalletBase
} }
@override @override
String get seed => _mnemonic; String? get seed => _mnemonic.isNotEmpty ? _mnemonic : null;
String get hexSeed => _hexSeed!;
String get representative => _representativeAddress ?? ""; String get representative => _representativeAddress ?? "";
@ -330,7 +336,7 @@ abstract class NanoWalletBase
Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type); Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
String toJSON() => json.encode({ String toJSON() => json.encode({
'seedKey': _seedKey, 'seedKey': _hexSeed,
'mnemonic': _mnemonic, 'mnemonic': _mnemonic,
'currentBalance': balance[currency]?.currentBalance.toString() ?? "0", 'currentBalance': balance[currency]?.currentBalance.toString() ?? "0",
'receivableBalance': balance[currency]?.receivableBalance.toString() ?? "0", 'receivableBalance': balance[currency]?.receivableBalance.toString() ?? "0",
@ -351,9 +357,9 @@ abstract class NanoWalletBase
formattedCurrentBalance: data['currentBalance'] as String? ?? "0", formattedCurrentBalance: data['currentBalance'] as String? ?? "0",
formattedReceivableBalance: data['receivableBalance'] as String? ?? "0"); formattedReceivableBalance: data['receivableBalance'] as String? ?? "0");
DerivationType derivationType = DerivationType.bip39; DerivationType derivationType = DerivationType.nano;
if (data['derivationType'] == "DerivationType.nano") { if (data['derivationType'] == "DerivationType.bip39") {
derivationType = DerivationType.nano; derivationType = DerivationType.bip39;
} }
walletInfo.derivationType = derivationType; walletInfo.derivationType = derivationType;
@ -390,9 +396,9 @@ abstract class NanoWalletBase
Future<void> regenerateAddress() async { Future<void> regenerateAddress() async {
final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd"; final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd";
_privateKey = _privateKey =
await NanoUtil.uniSeedToPrivate(_seedKey!, this.walletAddresses.account!.id, type); await NanoUtil.uniSeedToPrivate(_hexSeed!, this.walletAddresses.account!.id, type);
_publicAddress = _publicAddress =
await NanoUtil.uniSeedToAddress(_seedKey!, this.walletAddresses.account!.id, type); await NanoUtil.uniSeedToAddress(_hexSeed!, this.walletAddresses.account!.id, type);
this.walletInfo.address = _publicAddress!; this.walletInfo.address = _publicAddress!;
this.walletAddresses.address = _publicAddress!; this.walletAddresses.address = _publicAddress!;

View file

@ -491,50 +491,50 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider name: path_provider
sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.15" version: "2.1.1"
path_provider_android: path_provider_android:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.27" version: "2.2.1"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297" sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.4" version: "2.3.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
name: path_provider_linux name: path_provider_linux
sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.11" version: "2.2.1"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.6" version: "2.1.1"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.2.1"
pinenacl: pinenacl:
dependency: transitive dependency: transitive
description: description:
@ -676,6 +676,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
socks5_proxy:
dependency: transitive
description:
name: socks5_proxy
sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
source_gen: source_gen:
dependency: transitive dependency: transitive
description: description:
@ -756,6 +764,15 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
tor:
dependency: transitive
description:
path: "."
ref: main
resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
url: "https://github.com/cake-tech/tor.git"
source: git
version: "0.0.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:

View file

@ -63,8 +63,6 @@ PODS:
- Flutter - Flutter
- device_display_brightness (0.0.1): - device_display_brightness (0.0.1):
- Flutter - Flutter
- device_info (0.0.1):
- Flutter
- device_info_plus (0.0.1): - device_info_plus (0.0.1):
- Flutter - Flutter
- devicelocale (0.0.1): - devicelocale (0.0.1):
@ -124,15 +122,13 @@ PODS:
- Flutter - Flutter
- MTBBarcodeScanner (5.0.11) - MTBBarcodeScanner (5.0.11)
- OrderedSet (5.0.0) - OrderedSet (5.0.0)
- package_info (0.0.1): - package_info_plus (0.4.5):
- Flutter - Flutter
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- permission_handler_apple (9.1.1): - permission_handler_apple (9.1.1):
- Flutter - Flutter
- platform_device_id (0.0.1):
- Flutter
- ReachabilitySwift (5.0.0) - ReachabilitySwift (5.0.0)
- SDWebImage (5.16.0): - SDWebImage (5.16.0):
- SDWebImage/Core (= 5.16.0) - SDWebImage/Core (= 5.16.0)
@ -147,6 +143,8 @@ PODS:
- SwiftProtobuf (1.22.0) - SwiftProtobuf (1.22.0)
- SwiftyGif (5.4.4) - SwiftyGif (5.4.4)
- Toast (4.0.0) - Toast (4.0.0)
- tor (0.0.1):
- Flutter
- uni_links (0.0.1): - uni_links (0.0.1):
- Flutter - Flutter
- UnstoppableDomainsResolution (4.0.0): - UnstoppableDomainsResolution (4.0.0):
@ -154,7 +152,7 @@ PODS:
- CryptoSwift - CryptoSwift
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
- Flutter - Flutter
- wakelock (0.0.1): - wakelock_plus (0.0.1):
- Flutter - Flutter
- workmanager (0.0.1): - workmanager (0.0.1):
- Flutter - Flutter
@ -167,7 +165,6 @@ DEPENDENCIES:
- cw_monero (from `.symlinks/plugins/cw_monero/ios`) - cw_monero (from `.symlinks/plugins/cw_monero/ios`)
- cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`) - cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`)
- device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`) - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`)
- device_info (from `.symlinks/plugins/device_info/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- devicelocale (from `.symlinks/plugins/devicelocale/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`)
@ -178,17 +175,17 @@ DEPENDENCIES:
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- in_app_review (from `.symlinks/plugins/in_app_review/ios`) - in_app_review (from `.symlinks/plugins/in_app_review/ios`)
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`) - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
- sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`) - sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- tor (from `.symlinks/plugins/tor/ios`)
- uni_links (from `.symlinks/plugins/uni_links/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`)
- UnstoppableDomainsResolution (~> 4.0.0) - UnstoppableDomainsResolution (~> 4.0.0)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- wakelock (from `.symlinks/plugins/wakelock/ios`) - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
- workmanager (from `.symlinks/plugins/workmanager/ios`) - workmanager (from `.symlinks/plugins/workmanager/ios`)
SPEC REPOS: SPEC REPOS:
@ -219,8 +216,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/cw_shared_external/ios" :path: ".symlinks/plugins/cw_shared_external/ios"
device_display_brightness: device_display_brightness:
:path: ".symlinks/plugins/device_display_brightness/ios" :path: ".symlinks/plugins/device_display_brightness/ios"
device_info:
:path: ".symlinks/plugins/device_info/ios"
device_info_plus: device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios" :path: ".symlinks/plugins/device_info_plus/ios"
devicelocale: devicelocale:
@ -241,26 +236,26 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/in_app_review/ios" :path: ".symlinks/plugins/in_app_review/ios"
local_auth_ios: local_auth_ios:
:path: ".symlinks/plugins/local_auth_ios/ios" :path: ".symlinks/plugins/local_auth_ios/ios"
package_info: package_info_plus:
:path: ".symlinks/plugins/package_info/ios" :path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation: path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin" :path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple: permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios" :path: ".symlinks/plugins/permission_handler_apple/ios"
platform_device_id:
:path: ".symlinks/plugins/platform_device_id/ios"
sensitive_clipboard: sensitive_clipboard:
:path: ".symlinks/plugins/sensitive_clipboard/ios" :path: ".symlinks/plugins/sensitive_clipboard/ios"
share_plus: share_plus:
:path: ".symlinks/plugins/share_plus/ios" :path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation: shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin" :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
tor:
:path: ".symlinks/plugins/tor/ios"
uni_links: uni_links:
:path: ".symlinks/plugins/uni_links/ios" :path: ".symlinks/plugins/uni_links/ios"
url_launcher_ios: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios" :path: ".symlinks/plugins/url_launcher_ios/ios"
wakelock: wakelock_plus:
:path: ".symlinks/plugins/wakelock/ios" :path: ".symlinks/plugins/wakelock_plus/ios"
workmanager: workmanager:
:path: ".symlinks/plugins/workmanager/ios" :path: ".symlinks/plugins/workmanager/ios"
@ -273,12 +268,11 @@ SPEC CHECKSUMS:
cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d
cw_shared_external: 2972d872b8917603478117c9957dfca611845a92 cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7 device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
devicelocale: b22617f40038496deffba44747101255cee005b0 devicelocale: b22617f40038496deffba44747101255cee005b0
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: ce3938a0df3cc1ef404671531facef740d03f920 file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_inappwebview: 3d32228f1304635e7c028b0d4252937730bbc6cf flutter_inappwebview: 3d32228f1304635e7c028b0d4252937730bbc6cf
flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83 flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83
@ -288,10 +282,9 @@ SPEC CHECKSUMS:
local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605 local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
SDWebImage: 2aea163b50bfcb569a2726b6a754c54a4506fcf6 SDWebImage: 2aea163b50bfcb569a2726b6a754c54a4506fcf6
sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986 sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
@ -300,10 +293,11 @@ SPEC CHECKSUMS:
SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989 SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
tor: 662a9f5b980b5c86decb8ba611de9bcd4c8286eb
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841 UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
url_launcher_ios: 68d46cc9766d0c41dbdc884310529557e3cd7a86 url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
PODFILE CHECKSUM: 09df1114e7c360f55770d35a79356bf5446e0100 PODFILE CHECKSUM: 09df1114e7c360f55770d35a79356bf5446e0100

View file

@ -436,6 +436,7 @@ class BackupService {
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
final backupPassword = keychainJSON[backupPasswordKey] as String; final backupPassword = keychainJSON[backupPasswordKey] as String;
await _flutterSecureStorage.delete(key: backupPasswordKey);
await _flutterSecureStorage.write(key: backupPasswordKey, value: backupPassword); await _flutterSecureStorage.write(key: backupPasswordKey, value: backupPassword);
keychainWalletsInfo.forEach((dynamic rawInfo) async { keychainWalletsInfo.forEach((dynamic rawInfo) async {
@ -443,6 +444,7 @@ class BackupService {
await importWalletKeychainInfo(info); await importWalletKeychainInfo(info);
}); });
await _flutterSecureStorage.delete(key: pinCodeKey);
await _flutterSecureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); await _flutterSecureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
keychainDumpFile.deleteSync(); keychainDumpFile.deleteSync();
@ -462,6 +464,7 @@ class BackupService {
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
final backupPassword = keychainJSON[backupPasswordKey] as String; final backupPassword = keychainJSON[backupPasswordKey] as String;
await _flutterSecureStorage.delete(key: backupPasswordKey);
await _flutterSecureStorage.write(key: backupPasswordKey, value: backupPassword); await _flutterSecureStorage.write(key: backupPasswordKey, value: backupPassword);
keychainWalletsInfo.forEach((dynamic rawInfo) async { keychainWalletsInfo.forEach((dynamic rawInfo) async {
@ -469,6 +472,7 @@ class BackupService {
await importWalletKeychainInfo(info); await importWalletKeychainInfo(info);
}); });
await _flutterSecureStorage.delete(key: pinCodeKey);
await _flutterSecureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); await _flutterSecureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
keychainDumpFile.deleteSync(); keychainDumpFile.deleteSync();

View file

@ -19,6 +19,7 @@ class KeyService {
key: SecretStoreKey.moneroWalletPassword, walletName: walletName); key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = encodeWalletPassword(password: password); final encodedPassword = encodeWalletPassword(password: password);
await _secureStorage.delete(key: key);
await _secureStorage.write(key: key, value: encodedPassword); await _secureStorage.write(key: key, value: encodedPassword);
} }

View file

@ -27,7 +27,7 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sideba
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart'; import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart'; import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart'; import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart'; import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart';
@ -46,6 +46,7 @@ import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.
import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart'; import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart'; import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart';
import 'package:cake_wallet/src/screens/settings/tor_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
@ -64,6 +65,7 @@ import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart'; import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
@ -79,7 +81,7 @@ import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_cards_page.dar
import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_tip_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_tip_page.dart';
import 'package:cake_wallet/src/screens/ionia/ionia.dart'; import 'package:cake_wallet/src/screens/ionia/ionia.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/balance_page.dart';
import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart';
@ -211,7 +213,7 @@ import 'package:cake_wallet/store/templates/exchange_template_store.dart';
import 'package:cake_wallet/entities/template.dart'; import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/exchange/exchange_template.dart'; import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
import 'package:cake_wallet/anypay/anypay_api.dart'; import 'package:cake_wallet/anypay/anypay_api.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
@ -482,6 +484,7 @@ Future<void> setup({
}); });
getIt.registerFactory(() => BalancePage( getIt.registerFactory(() => BalancePage(
nftViewModel: getIt.get<NFTViewModel>(),
dashboardViewModel: getIt.get<DashboardViewModel>(), dashboardViewModel: getIt.get<DashboardViewModel>(),
settingsStore: getIt.get<SettingsStore>())); settingsStore: getIt.get<SettingsStore>()));
@ -1177,5 +1180,9 @@ Future<void> setup({
getIt.registerFactory( getIt.registerFactory(
() => WalletConnectConnectionsView(web3walletService: getIt.get<Web3WalletService>())); () => WalletConnectConnectionsView(web3walletService: getIt.get<Web3WalletService>()));
getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
_isSetupFinished = true; _isSetupFinished = true;
} }

View file

@ -496,6 +496,7 @@ Future<void> generateBackupPassword(FlutterSecureStorage secureStorage) async {
} }
final password = encrypt.Key.fromSecureRandom(32).base16; final password = encrypt.Key.fromSecureRandom(32).base16;
await secureStorage.delete(key: key);
await secureStorage.write(key: key, value: password); await secureStorage.write(key: key, value: password);
} }

View file

@ -147,6 +147,7 @@ Future<void> ios_migrate_pin() async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPassword = encodedPinCode(pin: pinPassword); final encodedPassword = encodedPinCode(pin: pinPassword);
await flutterSecureStorage.delete(key: key);
await flutterSecureStorage.write(key: key, value: encodedPassword); await flutterSecureStorage.write(key: key, value: encodedPassword);
await prefs.setBool('ios_migration_pin_completed', true); await prefs.setBool('ios_migration_pin_completed', true);
} }

View file

@ -9,7 +9,9 @@ Future<List<int>> getEncryptionKey(
if (stringifiedKey == null) { if (stringifiedKey == null) {
key = CakeHive.generateSecureKey(); key = CakeHive.generateSecureKey();
final keyStringified = key.join(','); final keyStringified = key.join(',');
await secureStorage.write(key: 'transactionDescriptionsBoxKey', value: keyStringified); String storageKey = 'transactionDescriptionsBoxKey';
await secureStorage.delete(key: storageKey);
await secureStorage.write(key: storageKey, value: keyStringified);
} else { } else {
key = stringifiedKey.split(',').map((i) => int.parse(i)).toList(); key = stringifiedKey.split(',').map((i) => int.parse(i)).toList();
} }

View file

@ -64,6 +64,7 @@ class PreferencesKey {
static const exchangeProvidersSelection = 'exchange-providers-selection'; static const exchangeProvidersSelection = 'exchange-providers-selection';
static const autoGenerateSubaddressStatusKey = 'auto_generate_subaddress_status'; static const autoGenerateSubaddressStatusKey = 'auto_generate_subaddress_status';
static const moneroSeedType = 'monero_seed_type';
static const clearnetDonationLink = 'clearnet_donation_link'; static const clearnetDonationLink = 'clearnet_donation_link';
static const onionDonationLink = 'onion_donation_link'; static const onionDonationLink = 'onion_donation_link';
static const lastSeenAppVersion = 'last_seen_app_version'; static const lastSeenAppVersion = 'last_seen_app_version';

View file

@ -0,0 +1,36 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/enumerable_item.dart';
class SeedType extends EnumerableItem<int> with Serializable<int> {
const SeedType({required String title, required int raw}) : super(title: title, raw: raw);
static const all = [SeedType.legacy, SeedType.polyseed];
static const defaultSeedType = legacy;
static const legacy = SeedType(raw: 0, title: 'Legacy (25 words)');
static const polyseed = SeedType(raw: 1, title: 'Polyseed (16 words)');
static SeedType deserialize({required int raw}) {
switch (raw) {
case 0:
return legacy;
case 1:
return polyseed;
default:
throw Exception('Unexpected token: $raw for SeedType deserialize');
}
}
@override
String toString() {
switch (this) {
case SeedType.legacy:
return S.current.seedtype_legacy;
case SeedType.polyseed:
return S.current.seedtype_polyseed;
default:
return '';
}
}
}

View file

@ -0,0 +1,95 @@
class WalletNFTsResponseModel {
final int? page;
final int? pageSize;
final List<NFTAssetModel>? result;
final String? status;
WalletNFTsResponseModel({this.page, this.pageSize, this.result, this.status});
factory WalletNFTsResponseModel.fromJson(Map<String, dynamic> json) {
return WalletNFTsResponseModel(
page: json['page'] as int?,
pageSize: json['page_size'] as int?,
result: (json['result'] as List?)
?.map((x) => NFTAssetModel.fromJson(x as Map<String, dynamic>))
.toList(),
status: json['status'] as String?,
);
}
}
class NFTAssetModel {
final String? tokenAddress;
final String? tokenId;
final String? contractType;
final String? name;
final String? symbol;
NormalizedMetadata? normalizedMetadata;
NFTAssetModel(
{this.tokenAddress,
this.tokenId,
this.contractType,
this.name,
this.symbol,
this.normalizedMetadata});
factory NFTAssetModel.fromJson(Map<String, dynamic> json) {
return NFTAssetModel(
tokenAddress: json['token_address'] as String?,
tokenId: json['token_id'] as String?,
contractType: json['contract_type'] as String?,
name: json['name'] as String?,
symbol: json['symbol'] as String?,
normalizedMetadata: json['normalized_metadata'] != null
? new NormalizedMetadata.fromJson(
json['normalized_metadata'] as Map<String, dynamic>)
: null,
);
}
}
class NormalizedMetadata {
final String? name;
final String? description;
final String? image;
NormalizedMetadata({
this.name,
this.description,
this.image,
});
factory NormalizedMetadata.fromJson(Map<String, dynamic> json) {
return NormalizedMetadata(
name: json['name'] as String?,
description: json['description'] as String?,
image: json['image'] as String?,
);
}
String? get imageUrl {
if (image == null) return image;
if (image!.contains('ipfs.io')) return image;
if (!image!.contains('ipfs')) return image;
// IPFS public gateway provided by Cloudflare is https://cloudflare-ipfs.com/ipfs/
//
// Here is an example of an ipfs image link:
//
// [ipfs://bafkreia2i2ctfexpovgzfff66wqhbmwwpvqjvozan7ioifzcnq76jharwu]
//https://ipfs.io/ipfs/QmTRcRXo6cXByjHYHTVxGpag6vpocrG3rxjPC9PxKAArR9/1620.png
const String ipfsPublicGateway = 'https://cloudflare-ipfs.com/ipfs/';
final ipfsPath = image?.split('//')[1];
final imageLink = '$ipfsPublicGateway$ipfsPath';
return imageLink;
}
}

View file

@ -166,6 +166,10 @@ class CWMonero extends Monero {
@override @override
List<String> getMoneroWordList(String language) { List<String> getMoneroWordList(String language) {
if (language.startsWith("POLYSEED_")) {
final lang = language.replaceAll("POLYSEED_", "");
return PolyseedLang.getByEnglishName(lang).words;
}
switch (language.toLowerCase()) { switch (language.toLowerCase()) {
case 'english': case 'english':
return EnglishMnemonics.words; return EnglishMnemonics.words;
@ -223,8 +227,10 @@ class CWMonero extends Monero {
WalletCredentials createMoneroNewWalletCredentials({ WalletCredentials createMoneroNewWalletCredentials({
required String name, required String name,
required String language, required String language,
required bool isPolyseed,
String? password}) => String? password}) =>
MoneroNewWalletCredentials(name: name, password: password, language: language); MoneroNewWalletCredentials(
name: name, password: password, language: language, isPolyseed: isPolyseed);
@override @override
Map<String, String> getKeys(Object wallet) { Map<String, String> getKeys(Object wallet) {

View file

@ -5,6 +5,7 @@ import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart';
import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/qr_view_data.dart'; import 'package:cake_wallet/entities/qr_view_data.dart';
import 'package:cake_wallet/entities/wallet_nft_response.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart'; import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/backup/backup_page.dart'; import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
@ -13,6 +14,7 @@ import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart'; import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart'; import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart'; import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart'; import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart';
@ -20,7 +22,7 @@ import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart'; import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart'; import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_choose_derivation.dart'; import 'package:cake_wallet/src/screens/restore/wallet_restore_choose_derivation.dart';
import 'package:cake_wallet/src/screens/settings/desktop_settings/desktop_settings_page.dart'; import 'package:cake_wallet/src/screens/settings/desktop_settings/desktop_settings_page.dart';
import 'package:cake_wallet/src/screens/settings/display_settings_page.dart'; import 'package:cake_wallet/src/screens/settings/display_settings_page.dart';
@ -43,6 +45,7 @@ import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart'; import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart'; import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart'; import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart';
import 'package:cake_wallet/src/screens/settings/tor_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
@ -53,8 +56,10 @@ import 'package:cake_wallet/src/screens/support_other_links/support_other_links_
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart'; import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart'; import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart'; import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart'; import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
@ -83,7 +88,6 @@ import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
import 'package:cake_wallet/src/screens/restore/restore_options_page.dart'; import 'package:cake_wallet/src/screens/restore/restore_options_page.dart';
import 'package:cake_wallet/src/screens/send/send_page.dart'; import 'package:cake_wallet/src/screens/send/send_page.dart';
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart'; import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
import 'package:cake_wallet/src/screens/seed_language/seed_language_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart'; import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
@ -101,7 +105,7 @@ import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dar
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:cake_wallet/wallet_types.g.dart'; import 'package:cake_wallet/wallet_types.g.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart'; import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
import 'package:cake_wallet/src/screens/ionia/ionia.dart'; import 'package:cake_wallet/src/screens/ionia/ionia.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
@ -110,6 +114,8 @@ import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'src/screens/dashboard/pages/nft_import_page.dart';
late RouteSettings currentRouteSettings; late RouteSettings currentRouteSettings;
Route<dynamic> createRoute(RouteSettings settings) { Route<dynamic> createRoute(RouteSettings settings) {
@ -141,8 +147,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.newWallet: case Routes.newWallet:
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;
final walletNewVM = getIt.get<WalletNewVM>(param1: type); final walletNewVM = getIt.get<WalletNewVM>(param1: type);
final settingsStore = getIt.get<SettingsStore>();
return CupertinoPageRoute<void>(builder: (_) => NewWalletPage(walletNewVM)); return CupertinoPageRoute<void>(builder: (_) => NewWalletPage(walletNewVM, settingsStore));
case Routes.setupPin: case Routes.setupPin:
Function(PinCodeState<PinCodeWidget>, String)? callback; Function(PinCodeState<PinCodeWidget>, String)? callback;
@ -258,17 +265,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.changeRep: case Routes.changeRep:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<NanoChangeRepPage>()); return CupertinoPageRoute<void>(builder: (_) => getIt.get<NanoChangeRepPage>());
case Routes.seedLanguage:
final args = settings.arguments as List<dynamic>;
final type = args.first as WalletType;
final redirectRoute = args[1] as String;
return CupertinoPageRoute<void>(builder: (_) {
return SeedLanguage(
onConfirm: (context, lang) =>
Navigator.of(context).popAndPushNamed(redirectRoute, arguments: [type, lang]));
});
case Routes.walletList: case Routes.walletList:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
fullscreenDialog: true, builder: (_) => getIt.get<WalletListPage>()); fullscreenDialog: true, builder: (_) => getIt.get<WalletListPage>());
@ -615,6 +611,25 @@ Route<dynamic> createRoute(RouteSettings settings) {
web3walletService: getIt.get<Web3WalletService>(), web3walletService: getIt.get<Web3WalletService>(),
launchUri: settings.arguments as Uri?, launchUri: settings.arguments as Uri?,
)); ));
case Routes.nftDetailsPage:
return MaterialPageRoute<void>(
builder: (_) => NFTDetailsPage(
nftAsset: settings.arguments as NFTAssetModel,
dashboardViewModel: getIt.get<DashboardViewModel>(),
),
);
case Routes.importNFTPage:
return MaterialPageRoute<void>(
builder: (_) => ImportNFTPage(
nftViewModel: settings.arguments as NFTViewModel,
),
);
case Routes.torPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>());
default: default:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => Scaffold( builder: (_) => Scaffold(

View file

@ -7,7 +7,8 @@ class Routes {
static const restoreOptions = '/restore_options'; static const restoreOptions = '/restore_options';
static const restoreWalletFromSeedKeys = '/restore_wallet_from_seeds_keys'; static const restoreWalletFromSeedKeys = '/restore_wallet_from_seeds_keys';
static const restoreWalletTypeFromQR = '/restore_wallet_from_qr_code'; static const restoreWalletTypeFromQR = '/restore_wallet_from_qr_code';
static const restoreWalletChooseDerivation = '/restore_wallet_choose_derivation'; static const restoreWalletChooseDerivation =
'/restore_wallet_choose_derivation';
static const dashboard = '/dashboard'; static const dashboard = '/dashboard';
static const send = '/send'; static const send = '/send';
static const transactionDetails = '/transaction_info'; static const transactionDetails = '/transaction_info';
@ -17,7 +18,6 @@ class Routes {
static const disclaimer = '/disclaimer'; static const disclaimer = '/disclaimer';
static const readDisclaimer = '/read_disclaimer'; static const readDisclaimer = '/read_disclaimer';
static const changeRep = '/change_representative'; static const changeRep = '/change_representative';
static const seedLanguage = '/seed_language';
static const walletList = '/view_model.wallet_list'; static const walletList = '/view_model.wallet_list';
static const auth = '/auth'; static const auth = '/auth';
static const newNode = '/new_node_list'; static const newNode = '/new_node_list';
@ -100,5 +100,9 @@ class Routes {
static const editToken = '/edit_token'; static const editToken = '/edit_token';
static const manageNodes = '/manage_nodes'; static const manageNodes = '/manage_nodes';
static const managePowNodes = '/manage_pow_nodes'; static const managePowNodes = '/manage_pow_nodes';
static const walletConnectConnectionsListing = '/wallet-connect-connections-listing'; static const walletConnectConnectionsListing =
'/wallet-connect-connections-listing';
static const nftDetailsPage = '/nft_details_page';
static const importNFTPage = '/import_nft_page';
static const torPage = '/tor_page';
} }

View file

@ -1,11 +1,10 @@
import 'dart:async'; import 'dart:async';
import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart'; import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart';
import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart';
import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/entities/main_actions.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/market_place_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.dart'; import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart'; import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart'; import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
@ -15,7 +14,6 @@ import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -23,8 +21,8 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/action_button.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/action_button.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/balance_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';

View file

@ -1,17 +1,14 @@
import 'dart:async'; import 'dart:async';
import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart'; import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/utils/version_comparator.dart'; import 'package:cake_wallet/utils/version_comparator.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/balance_page.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/router.dart' as Router; import 'package:cake_wallet/router.dart' as Router;
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';

View file

@ -1,7 +1,7 @@
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/entities/main_actions.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_action_button.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/market_place_page.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -6,10 +6,8 @@ import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/receive_page_option.dart'; import 'package:cake_wallet/entities/receive_page_option.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart'; import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart'; import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
@ -26,7 +24,6 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart'; import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin; import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
@ -192,8 +189,7 @@ class AddressPage extends BasePage {
? S.of(context).accounts_subaddresses ? S.of(context).accounts_subaddresses
: S.of(context).addresses; : S.of(context).addresses;
if (!addressListViewModel.hasSilentAddresses && if (dashboardViewModel.isAutoGenerateSubaddressesEnabled) {
dashboardViewModel.isAutoGenerateSubaddressesEnabled) {
label = addressListViewModel.hasAccounts label = addressListViewModel.hasAccounts
? S.of(context).accounts ? S.of(context).accounts
: S.of(context).account; : S.of(context).account;

View file

@ -1,6 +1,7 @@
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/nft_listing_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/home_screen_account_widget.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/home_screen_account_widget.dart';
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
import 'package:cake_wallet/src/widgets/introducing_card.dart'; import 'package:cake_wallet/src/widgets/introducing_card.dart';
@ -11,15 +12,80 @@ import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/utils/feature_flag.dart'; import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
class BalancePage extends StatelessWidget { class BalancePage extends StatelessWidget {
BalancePage({required this.dashboardViewModel, required this.settingsStore}); BalancePage({
required this.dashboardViewModel,
required this.settingsStore,
required this.nftViewModel,
});
final DashboardViewModel dashboardViewModel; final DashboardViewModel dashboardViewModel;
final NFTViewModel nftViewModel;
final SettingsStore settingsStore; final SettingsStore settingsStore;
@override
Widget build(BuildContext context) {
return Observer(
builder: (context) {
final isEthereumWallet = dashboardViewModel.type == WalletType.ethereum;
return DefaultTabController(
length: isEthereumWallet ? 2 : 1,
child: Column(
children: [
if (isEthereumWallet)
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(left: 8),
child: TabBar(
indicatorSize: TabBarIndicatorSize.label,
isScrollable: true,
physics: NeverScrollableScrollPhysics(),
labelStyle: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color:
Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
height: 1,
),
tabs: [
Tab(text: 'My Crypto'),
Tab(text: 'My NFTs'),
],
),
),
),
Expanded(
child: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: [
CryptoBalanceWidget(dashboardViewModel: dashboardViewModel),
if (isEthereumWallet) NFTListingPage(nftViewModel: nftViewModel)
],
),
),
],
),
);
},
);
}
}
class CryptoBalanceWidget extends StatelessWidget {
const CryptoBalanceWidget({
super.key,
required this.dashboardViewModel,
});
final DashboardViewModel dashboardViewModel;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
@ -38,7 +104,7 @@ class BalancePage extends StatelessWidget {
accountName: dashboardViewModel.subname) accountName: dashboardViewModel.subname)
: Column( : Column(
children: [ children: [
SizedBox(height: 56), SizedBox(height: 16),
Container( Container(
margin: const EdgeInsets.only(left: 24, bottom: 16), margin: const EdgeInsets.only(left: 24, bottom: 16),
child: Observer( child: Observer(
@ -105,8 +171,7 @@ class BalancePage extends StatelessWidget {
itemBuilder: (__, index) { itemBuilder: (__, index) {
final balance = final balance =
dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index); dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
return buildBalanceRow( return BalanceRowWidget(
context,
availableBalanceLabel: availableBalanceLabel:
'${dashboardViewModel.balanceViewModel.availableBalanceLabel}', '${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
availableBalance: balance.availableBalance, availableBalance: balance.availableBalance,
@ -130,20 +195,44 @@ class BalancePage extends StatelessWidget {
), ),
); );
} }
}
Widget buildBalanceRow( class BalanceRowWidget extends StatelessWidget {
BuildContext context, { const BalanceRowWidget({
required String availableBalanceLabel, required this.availableBalanceLabel,
required String availableBalance, required this.availableBalance,
required String availableFiatBalance, required this.availableFiatBalance,
required String additionalBalanceLabel, required this.additionalBalanceLabel,
required String additionalBalance, required this.additionalBalance,
required String additionalFiatBalance, required this.additionalFiatBalance,
required String frozenBalance, required this.frozenBalance,
required String frozenFiatBalance, required this.frozenFiatBalance,
required String currency, required this.currency,
required bool hasAdditionalBalance, required this.hasAdditionalBalance,
}) { super.key,
});
final String availableBalanceLabel;
final String availableBalance;
final String availableFiatBalance;
final String additionalBalanceLabel;
final String additionalBalance;
final String additionalFiatBalance;
final String frozenBalance;
final String frozenFiatBalance;
final String currency;
final bool hasAdditionalBalance;
// void _showBalanceDescription(BuildContext context) {
// showPopUp<void>(
// context: context,
// builder: (_) =>
// InformationPage(information: S.current.available_balance_description),
// );
// }
@override
Widget build(BuildContext context) {
return Container( return Container(
margin: const EdgeInsets.only(left: 16, right: 16), margin: const EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
@ -165,7 +254,8 @@ class BalancePage extends StatelessWidget {
children: [ children: [
GestureDetector( GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: hasAdditionalBalance ? () => onTap: hasAdditionalBalance
? () =>
_showBalanceDescription(context, S.current.available_balance_description) _showBalanceDescription(context, S.current.available_balance_description)
: null, : null,
child: Column( child: Column(
@ -229,8 +319,9 @@ class BalancePage extends StatelessWidget {
if (frozenBalance.isNotEmpty) if (frozenBalance.isNotEmpty)
GestureDetector( GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: hasAdditionalBalance ? onTap: hasAdditionalBalance
() => _showBalanceDescription(context, S.current.unavailable_balance_description) ? () =>
_showBalanceDescription(context, S.current.unavailable_balance_description)
: null, : null,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -253,9 +344,8 @@ class BalancePage extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(horizontal: 4),
child: Icon(Icons.help_outline, child: Icon(Icons.help_outline,
size: 16, size: 16,
color: Theme.of(context) color:
.extension<BalancePageTheme>()! Theme.of(context).extension<BalancePageTheme>()!.labelTextColor),
.labelTextColor),
), ),
], ],
), ),
@ -337,8 +427,6 @@ class BalancePage extends StatelessWidget {
} }
void _showBalanceDescription(BuildContext context, String content) { void _showBalanceDescription(BuildContext context, String content) {
showPopUp<void>( showPopUp<void>(context: context, builder: (_) => InformationPage(information: content));
context: context,
builder: (_) => InformationPage(information: content));
} }
} }

View file

@ -0,0 +1,178 @@
import 'package:cake_wallet/entities/wallet_nft_response.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/menu_widget.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/nft_image_tile_widget.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/material.dart';
class NFTDetailsPage extends BasePage {
NFTDetailsPage({required this.dashboardViewModel, required this.nftAsset});
final DashboardViewModel dashboardViewModel;
final NFTAssetModel nftAsset;
@override
bool get gradientBackground => true;
@override
Widget Function(BuildContext, Widget) get rootWrapper =>
(BuildContext context, Widget scaffold) =>
GradientBackground(scaffold: scaffold);
@override
bool get resizeToAvoidBottomInset => false;
@override
Widget get endDrawer => MenuWidget(dashboardViewModel);
@override
Widget trailing(BuildContext context) {
final menuButton = Image.asset(
'assets/images/menu.png',
color:
Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
);
return Container(
alignment: Alignment.centerRight,
width: 40,
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => onOpenEndDrawer(),
child: Semantics(label: S.of(context).wallet_menu, child: menuButton),
),
);
}
@override
Widget body(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.all(16),
padding: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
border: Border.all(
color: Theme.of(context)
.extension<BalancePageTheme>()!
.cardBorderColor,
width: 1,
),
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: MediaQuery.sizeOf(context).height / 2.5,
width: double.infinity,
clipBehavior: Clip.hardEdge,
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.0),
border: Border.all(
color: Theme.of(context)
.extension<BalancePageTheme>()!
.cardBorderColor,
width: 1,
),
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor,
),
child: NFTImageWidget(
imageUrl: nftAsset.normalizedMetadata?.imageUrl,
),
),
SizedBox(height: 16),
_NFTSingleInfoTile(
infoType: S.current.name,
infoValue: nftAsset.normalizedMetadata?.name ?? '',
),
if (nftAsset.normalizedMetadata?.description != null) ...[
SizedBox(height: 16),
_NFTSingleInfoTile(
infoType: 'Description',
infoValue: nftAsset.normalizedMetadata?.description ?? '',
),
],
SizedBox(height: 16),
_NFTSingleInfoTile(
infoType: 'Contract Name',
infoValue: nftAsset.name ?? '',
),
SizedBox(height: 8),
_NFTSingleInfoTile(
infoType: 'Contract Symbol',
infoValue: nftAsset.symbol ?? '',
),
],
),
),
],
),
);
}
}
class _NFTSingleInfoTile extends StatelessWidget {
const _NFTSingleInfoTile({
required this.infoType,
required this.infoValue,
});
final String infoType;
final String infoValue;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
infoType,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
height: 1,
),
),
SizedBox(height: 8),
Text(
infoValue,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.assetTitleColor,
height: 1,
),
),
],
),
);
}
}

View file

@ -0,0 +1,168 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/seed_widget_theme.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class ImportNFTPage extends StatefulWidget {
const ImportNFTPage({required this.nftViewModel, super.key});
final NFTViewModel nftViewModel;
@override
State<ImportNFTPage> createState() => _ImportNFTPageState();
}
class _ImportNFTPageState extends State<ImportNFTPage> {
late TextEditingController tokenAddressController;
late TextEditingController tokenIDController;
@override
void initState() {
super.initState();
tokenAddressController = TextEditingController();
tokenIDController = TextEditingController();
}
@override
void dispose() {
tokenAddressController.dispose();
tokenIDController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return _ImportNFTPage(
nftViewModel: widget.nftViewModel,
tokenAddressController: tokenAddressController,
tokenIDController: tokenIDController,
);
}
}
class _ImportNFTPage extends BasePage {
_ImportNFTPage({
required this.tokenIDController,
required this.tokenAddressController,
required this.nftViewModel,
});
final NFTViewModel nftViewModel;
final TextEditingController tokenIDController;
final TextEditingController tokenAddressController;
@override
String? get title => S.current.import;
@override
Widget body(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
S.current.address,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
color:
Theme.of(context).extension<SeedWidgetTheme>()!.hintTextColor,
height: 1,
),
),
AddressTextField(
controller: tokenAddressController,
options: [AddressTextFieldOption.paste],
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
final tokenAddress = clipboard?.text ?? '';
if (tokenAddress.isNotEmpty) {
tokenAddressController.text = tokenAddress;
}
},
borderColor: Theme.of(context)
.extension<CakeTextTheme>()!
.textfieldUnderlineColor,
iconColor: Theme.of(context).primaryColor,
placeholder: '0x...',
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: PaletteDark.darkCyanBlue,
),
hintStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: PaletteDark.darkCyanBlue,
),
),
SizedBox(height: 48),
Text(
S.current.tokenID,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
color: Theme.of(context).extension<SeedWidgetTheme>()!.hintTextColor,
height: 1,
),
),
AddressTextField(
controller: tokenIDController,
options: [AddressTextFieldOption.paste],
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
final tokenID = clipboard?.text ?? '';
if (tokenID.isNotEmpty) {
tokenIDController.text = tokenID;
}
},
borderColor: Theme.of(context)
.extension<CakeTextTheme>()!
.textfieldUnderlineColor,
iconColor: Theme.of(context).primaryColor,
placeholder: S.current.enterTokenID,
textStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: PaletteDark.darkCyanBlue,
),
hintStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: PaletteDark.darkCyanBlue,
),
),
Spacer(),
Observer(builder: (context) {
return LoadingPrimaryButton(
isLoading: nftViewModel.isImportNFTLoading,
text: S.current.import,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
onPressed: () async {
await nftViewModel.importNFT(tokenAddressController.text, tokenIDController.text);
Navigator.pop(context);
},
);
}),
],
),
);
}
}

View file

@ -0,0 +1,84 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/nft_tile_widget.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class NFTListingPage extends StatelessWidget {
final NFTViewModel nftViewModel;
const NFTListingPage({super.key, required this.nftViewModel});
@override
Widget build(BuildContext context) {
return Observer(
builder: (context) {
return Column(
children: [
SizedBox(height: 16),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: PrimaryButton(
text: S.current.import,
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor,
textColor: Colors.white,
onPressed: () => Navigator.pushNamed(
context,
Routes.importNFTPage,
arguments: nftViewModel,
),
),
),
if (nftViewModel.isLoading)
Expanded(
child: Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context)
.extension<ExchangePageTheme>()!
.firstGradientBottomPanelColor,
),
),
),
),
if (!nftViewModel.isLoading)
Expanded(
child: nftViewModel.nftAssetByWalletModels.isEmpty
? Center(
child: Text(
S.current.noNFTYet,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context)
.extension<DashboardPageTheme>()!
.pageTitleTextColor,
height: 1,
),
),
)
: ListView.separated(
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 16),
separatorBuilder: (context, index) => SizedBox(height: 8),
itemCount: nftViewModel.nftAssetByWalletModels.length,
itemBuilder: (context, index) {
final nftAsset = nftViewModel.nftAssetByWalletModels[index];
return NFTTileWidget(nftAsset: nftAsset);
},
),
)
],
);
},
);
}
}

View file

@ -46,9 +46,11 @@ class TransactionsPage extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 8), padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
child: DashBoardRoundedCardWidget( child: DashBoardRoundedCardWidget(
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [
Routes.webViewPage, '',
arguments: ['', Uri.parse('https://guides.cakewallet.com/docs/bugs-service-status/why_are_my_funds_not_appearing/')]), Uri.parse(
'https://guides.cakewallet.com/docs/bugs-service-status/why_are_my_funds_not_appearing/')
]),
title: S.of(context).syncing_wallet_alert_title, title: S.of(context).syncing_wallet_alert_title,
subTitle: S.of(context).syncing_wallet_alert_content, subTitle: S.of(context).syncing_wallet_alert_content,
), ),
@ -76,40 +78,34 @@ class TransactionsPage extends StatelessWidget {
return Observer( return Observer(
builder: (_) => TransactionRow( builder: (_) => TransactionRow(
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context)
Routes.transactionDetails, .pushNamed(Routes.transactionDetails, arguments: transaction),
arguments: transaction),
direction: transaction.direction, direction: transaction.direction,
formattedDate: DateFormat('HH:mm') formattedDate: DateFormat('HH:mm').format(transaction.date),
.format(transaction.date),
formattedAmount: item.formattedCryptoAmount, formattedAmount: item.formattedCryptoAmount,
formattedFiatAmount: dashboardViewModel formattedFiatAmount:
.balanceViewModel.isFiatDisabled dashboardViewModel.balanceViewModel.isFiatDisabled
? '' ? ''
: item.formattedFiatAmount, : item.formattedFiatAmount,
isPending: transaction.isPending, isPending: transaction.isPending,
title: item.formattedTitle + title: item.formattedTitle + item.formattedStatus));
item.formattedStatus));
} }
if (item is AnonpayTransactionListItem) { if (item is AnonpayTransactionListItem) {
final transactionInfo = item.transaction; final transactionInfo = item.transaction;
return AnonpayTransactionRow( return AnonpayTransactionRow(
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context)
Routes.anonPayDetailsPage, .pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
arguments: transactionInfo),
currency: transactionInfo.fiatAmount != null currency: transactionInfo.fiatAmount != null
? transactionInfo.fiatEquiv ?? '' ? transactionInfo.fiatEquiv ?? ''
: CryptoCurrency.fromFullName( : CryptoCurrency.fromFullName(transactionInfo.coinTo)
transactionInfo.coinTo)
.name .name
.toUpperCase(), .toUpperCase(),
provider: transactionInfo.provider, provider: transactionInfo.provider,
amount: transactionInfo.fiatAmount?.toString() ?? amount: transactionInfo.fiatAmount?.toString() ??
(transactionInfo.amountTo?.toString() ?? ''), (transactionInfo.amountTo?.toString() ?? ''),
createdAt: DateFormat('HH:mm') createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
.format(transactionInfo.createdAt),
); );
} }
@ -118,16 +114,13 @@ class TransactionsPage extends StatelessWidget {
return Observer( return Observer(
builder: (_) => TradeRow( builder: (_) => TradeRow(
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context)
Routes.tradeDetails, .pushNamed(Routes.tradeDetails, arguments: trade),
arguments: trade),
provider: trade.provider, provider: trade.provider,
from: trade.from, from: trade.from,
to: trade.to, to: trade.to,
createdAtFormattedDate: createdAtFormattedDate: trade.createdAt != null
trade.createdAt != null ? DateFormat('HH:mm').format(trade.createdAt!)
? DateFormat('HH:mm')
.format(trade.createdAt!)
: null, : null,
formattedAmount: item.tradeFormattedAmount)); formattedAmount: item.tradeFormattedAmount));
} }
@ -138,13 +131,12 @@ class TransactionsPage extends StatelessWidget {
return Observer( return Observer(
builder: (_) => OrderRow( builder: (_) => OrderRow(
onTap: () => Navigator.of(context) onTap: () => Navigator.of(context)
.pushNamed(Routes.orderDetails, .pushNamed(Routes.orderDetails, arguments: order),
arguments: order),
provider: order.provider, provider: order.provider,
from: order.from!, from: order.from!,
to: order.to!, to: order.to!,
createdAtFormattedDate: DateFormat('HH:mm') createdAtFormattedDate:
.format(order.createdAt), DateFormat('HH:mm').format(order.createdAt),
formattedAmount: item.orderFormattedAmount, formattedAmount: item.orderFormattedAmount,
)); ));
} }

View file

@ -0,0 +1,37 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class NFTImageWidget extends StatelessWidget {
const NFTImageWidget({
required this.imageUrl,
});
final String? imageUrl;
@override
Widget build(BuildContext context) {
try {
if (imageUrl == null) return Icon(Icons.error);
if (imageUrl!.contains('.svg')) {
return SvgPicture.network(imageUrl!);
}
return Image.network(
imageUrl!,
fit: BoxFit.cover,
loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return CupertinoActivityIndicator(animating: true);
}
},
errorBuilder: (_, __, ___) => Icon(Icons.error),
);
} catch (_) {
return Icon(Icons.error);
}
}
}

View file

@ -0,0 +1,95 @@
import 'package:cake_wallet/entities/wallet_nft_response.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/nft_image_tile_widget.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class NFTTileWidget extends StatelessWidget {
const NFTTileWidget({super.key, required this.nftAsset});
final NFTAssetModel nftAsset;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => Navigator.pushNamed(context, Routes.nftDetailsPage,
arguments: nftAsset),
child: Container(
width: double.infinity,
margin: const EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
border: Border.all(
color: Theme.of(context)
.extension<BalancePageTheme>()!
.cardBorderColor,
width: 1,
),
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor,
),
child: Row(
children: [
Container(
height: 100,
width: 100,
clipBehavior: Clip.hardEdge,
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.0),
border: Border.all(
color: Theme.of(context)
.extension<BalancePageTheme>()!
.cardBorderColor,
width: 1,
),
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor,
),
child: NFTImageWidget(
imageUrl: nftAsset.normalizedMetadata?.imageUrl,
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${nftAsset.name ?? ''} - ${nftAsset.symbol ?? ''}',
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
height: 1,
),
),
SizedBox(height: 8),
Text(
nftAsset.normalizedMetadata?.name ?? nftAsset.name ?? "",
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w900,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.assetTitleColor,
height: 1,
),
),
],
),
)
],
),
),
);
}
}

View file

@ -1,6 +1,7 @@
import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/seed_phrase_length.dart'; import 'package:cake_wallet/entities/seed_phrase_length.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart'; import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
@ -107,6 +108,17 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
}, },
); );
}), }),
if (widget.privacySettingsViewModel.hasSeedTypeOption)
Observer(builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<SeedType>(
title: S.current.seedtype,
items: SeedType.all,
selectedItem: widget.privacySettingsViewModel.seedType,
onItemSelected: widget.privacySettingsViewModel.setSeedType,
),
);
}),
], ],
), ),
bottomSectionPadding: EdgeInsets.all(24), bottomSectionPadding: EdgeInsets.all(24),

View file

@ -1,5 +1,7 @@
import 'package:cake_wallet/entities/generate_name.dart'; import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -15,17 +17,20 @@ import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart'; import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart'; import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart'; import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart'; import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/store/settings_store.dart';
class NewWalletPage extends BasePage { class NewWalletPage extends BasePage {
NewWalletPage(this._walletNewVM); NewWalletPage(this._walletNewVM, this._settingsStore);
final WalletNewVM _walletNewVM; final WalletNewVM _walletNewVM;
final SettingsStore _settingsStore;
final walletNameImage = Image.asset('assets/images/wallet_name.png'); final walletNameImage = Image.asset('assets/images/wallet_name.png');
@ -36,14 +41,15 @@ class NewWalletPage extends BasePage {
@override @override
Widget body(BuildContext context) => WalletNameForm( Widget body(BuildContext context) => WalletNameForm(
_walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage); _walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage, _settingsStore);
} }
class WalletNameForm extends StatefulWidget { class WalletNameForm extends StatefulWidget {
WalletNameForm(this._walletNewVM, this.walletImage); WalletNameForm(this._walletNewVM, this.walletImage, this._settingsStore);
final WalletNewVM _walletNewVM; final WalletNewVM _walletNewVM;
final Image walletImage; final Image walletImage;
final SettingsStore _settingsStore;
@override @override
_WalletNameFormState createState() => _WalletNameFormState(_walletNewVM); _WalletNameFormState createState() => _WalletNameFormState(_walletNewVM);
@ -85,6 +91,8 @@ class _WalletNameFormState extends State<WalletNameForm> {
}); });
} }
}); });
_setSeedType(SeedType.defaultSeedType);
super.initState(); super.initState();
} }
@ -180,22 +188,40 @@ class _WalletNameFormState extends State<WalletNameForm> {
), ),
), ),
), ),
if (_walletNewVM.hasLanguageSelector) ...[ if (_walletNewVM.hasLanguageSelector) ...[
Padding( if (_walletNewVM.hasSeedType) ...[
padding: EdgeInsets.only(top: 40), Observer(
child: Text( builder: (BuildContext build) => Padding(
S.of(context).seed_language_choose,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
),
Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: SelectButton(
text: widget._settingsStore.moneroSeedType.title,
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => Picker(
items: SeedType.all,
selectedAtIndex: isPolyseed ? 1 : 0,
onItemSelected: _setSeedType,
isSeparated: false,
),
);
},
),
),
),
],
Observer(
builder: (BuildContext build) => Padding(
padding: EdgeInsets.only(top: 10),
child: SeedLanguageSelector( child: SeedLanguageSelector(
key: _languageSelectorKey, initialSelected: defaultSeedLanguage), key: _languageSelectorKey,
initialSelected: defaultSeedLanguage,
seedType: _walletNewVM.hasSeedType
? widget._settingsStore.moneroSeedType
: SeedType.legacy,
),
),
) )
], ],
Observer(builder: (context) { Observer(builder: (context) {
@ -229,7 +255,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
Navigator.of(context) Navigator.of(context)
.pushNamed(Routes.advancedPrivacySettings, arguments: _walletNewVM.type); .pushNamed(Routes.advancedPrivacySettings, arguments: _walletNewVM.type);
}, },
child: Text(S.of(context).advanced_privacy_settings), child: Text(S.of(context).advanced_settings),
), ),
], ],
)), )),
@ -253,8 +279,15 @@ class _WalletNameFormState extends State<WalletNameForm> {
} else { } else {
_walletNewVM.create( _walletNewVM.create(
options: _walletNewVM.hasLanguageSelector options: _walletNewVM.hasLanguageSelector
? _languageSelectorKey.currentState!.selected ? [_languageSelectorKey.currentState!.selected, isPolyseed]
: null); : null);
} }
} }
bool get isPolyseed => widget._settingsStore.moneroSeedType == SeedType.polyseed;
void _setSeedType(SeedType item) {
widget._settingsStore.moneroSeedType = item;
_languageSelectorKey.currentState?.selected = defaultSeedLanguage; // Reset Seed language
}
} }

View file

@ -133,7 +133,7 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
widget.walletRestoreViewModel.type == WalletType.banano; widget.walletRestoreViewModel.type == WalletType.banano;
return AddressTextField( return AddressTextField(
controller: privateKeyController, controller: privateKeyController,
placeholder: nanoBased ? S.of(context).seed_key : S.of(context).private_key, placeholder: nanoBased ? S.of(context).seed_hex_form : S.of(context).private_key,
options: [AddressTextFieldOption.paste], options: [AddressTextFieldOption.paste],
buttonColor: Theme.of(context).hintColor, buttonColor: Theme.of(context).hintColor,
onPushPasteButton: (_) { onPushPasteButton: (_) {

View file

@ -1,16 +1,19 @@
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/entities/generate_name.dart'; import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/seed_widget.dart'; import 'package:cake_wallet/src/widgets/seed_widget.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart'; import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart'; import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:polyseed/polyseed.dart';
class WalletRestoreFromSeedForm extends StatefulWidget { class WalletRestoreFromSeedForm extends StatefulWidget {
WalletRestoreFromSeedForm({ WalletRestoreFromSeedForm({
@ -47,21 +50,35 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
blockchainHeightKey = GlobalKey<BlockchainHeightState>(), blockchainHeightKey = GlobalKey<BlockchainHeightState>(),
formKey = GlobalKey<FormState>(), formKey = GlobalKey<FormState>(),
languageController = TextEditingController(), languageController = TextEditingController(),
nameTextEditingController = TextEditingController(); nameTextEditingController = TextEditingController(),
seedTypeController = TextEditingController();
final GlobalKey<SeedWidgetState> seedWidgetStateKey; final GlobalKey<SeedWidgetState> seedWidgetStateKey;
final GlobalKey<BlockchainHeightState> blockchainHeightKey; final GlobalKey<BlockchainHeightState> blockchainHeightKey;
final TextEditingController languageController; final TextEditingController languageController;
final TextEditingController nameTextEditingController; final TextEditingController nameTextEditingController;
final TextEditingController seedTypeController;
final GlobalKey<FormState> formKey; final GlobalKey<FormState> formKey;
String language; String language;
bool isPolyseed = false;
@override @override
void initState() { void initState() {
_setLanguageLabel(language); _setLanguageLabel(language);
_setSeedType(SeedType.defaultSeedType);
super.initState(); super.initState();
} }
void onSeedChange(String seed) {
if (widget.type == WalletType.monero && Polyseed.isValidSeed(seed)) {
final lang = PolyseedLang.getByPhrase(seed);
_changeSeedType(SeedType.polyseed);
_changeLanguage(lang.nameEnglish);
}
widget.onSeedChange?.call(seed);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -111,14 +128,43 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
key: seedWidgetStateKey, key: seedWidgetStateKey,
language: language, language: language,
type: widget.type, type: widget.type,
onSeedChange: widget.onSeedChange), onSeedChange: onSeedChange),
if (widget.type == WalletType.monero)
GestureDetector(
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => Picker(
items: SeedType.all,
selectedAtIndex: isPolyseed ? 1 : 0,
mainAxisAlignment: MainAxisAlignment.start,
onItemSelected: _changeSeedType,
isSeparated: false,
));
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.only(top: 20.0),
child: IgnorePointer(
child: BaseTextFormField(
controller: seedTypeController,
enableInteractiveSelection: false,
readOnly: true,
suffixIcon: expandIcon,
),
),
),
),
if (widget.displayLanguageSelector) if (widget.displayLanguageSelector)
GestureDetector( GestureDetector(
onTap: () async { onTap: () async {
await showPopUp<void>( await showPopUp<void>(
context: context, context: context,
builder: (_) => builder: (_) => SeedLanguagePicker(
SeedLanguagePicker(selected: language, onItemSelected: _changeLanguage)); selected: language,
onItemSelected: _changeLanguage,
seedType: isPolyseed ? SeedType.polyseed : SeedType.legacy,
));
}, },
child: Container( child: Container(
color: Colors.transparent, color: Colors.transparent,
@ -127,8 +173,13 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
child: BaseTextFormField( child: BaseTextFormField(
controller: languageController, controller: languageController,
enableInteractiveSelection: false, enableInteractiveSelection: false,
readOnly: true)))), readOnly: true,
if (widget.displayBlockHeightSelector) suffixIcon: expandIcon,
),
),
),
),
if (!isPolyseed && widget.displayBlockHeightSelector)
BlockchainHeightWidget( BlockchainHeightWidget(
focusNode: widget.blockHeightFocusNode, focusNode: widget.blockHeightFocusNode,
key: blockchainHeightKey, key: blockchainHeightKey,
@ -143,14 +194,37 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
])); ]));
} }
Widget get expandIcon => Container(
padding: EdgeInsets.all(18),
width: 24,
height: 24,
child: Image.asset(
'assets/images/arrow_bottom_purple_icon.png',
height: 8,
color: Theme.of(context).hintColor,
),
);
void _changeLanguage(String language) { void _changeLanguage(String language) {
final setLang = isPolyseed ? "POLYSEED_$language" : language;
setState(() { setState(() {
this.language = language; this.language = setLang;
seedWidgetStateKey.currentState!.changeSeedLanguage(language); seedWidgetStateKey.currentState!.changeSeedLanguage(setLang);
_setLanguageLabel(language); _setLanguageLabel(setLang);
widget.onLanguageChange?.call(language); widget.onLanguageChange?.call(setLang);
}); });
} }
void _setLanguageLabel(String language) => languageController.text = '$language (Seed language)'; void _setLanguageLabel(String language) =>
languageController.text = '${language.replaceAll("POLYSEED_", "")} (Seed language)';
void _changeSeedType(SeedType item) {
_setSeedType(item);
_changeLanguage('English');
}
void _setSeedType(SeedType item) {
setState(() => isPolyseed = item == SeedType.polyseed);
seedTypeController.text = item.toString();
}
} }

View file

@ -1,29 +1,30 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/nano/nano.dart'; import 'package:cake_wallet/nano/nano.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart'; import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cw_core/nano_account_info_response.dart'; import 'package:cw_core/nano_account_info_response.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:polyseed/polyseed.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
class WalletRestorePage extends BasePage { class WalletRestorePage extends BasePage {
WalletRestorePage(this.walletRestoreViewModel) WalletRestorePage(this.walletRestoreViewModel)
@ -50,27 +51,13 @@ class WalletRestorePage extends BasePage {
} }
}, },
onSeedChange: (String seed) { onSeedChange: (String seed) {
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) { final isPolyseed =
final hasHeight = walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey walletRestoreViewModel.type == WalletType.monero && Polyseed.isValidSeed(seed);
.currentState!.restoreHeightController.text.isNotEmpty; _validateOnChange(isPolyseed: isPolyseed);
if (hasHeight) {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
} else {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
}, },
onLanguageChange: (_) { onLanguageChange: (String language) {
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) { final isPolyseed = language.startsWith("POLYSEED_");
final hasHeight = walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey _validateOnChange(isPolyseed: isPolyseed);
.currentState!.restoreHeightController.text.isNotEmpty;
if (hasHeight) {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
} else {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
})); }));
break; break;
case WalletRestoreMode.keys: case WalletRestoreMode.keys:
@ -225,7 +212,7 @@ class WalletRestorePage extends BasePage {
Navigator.of(context).pushNamed(Routes.advancedPrivacySettings, Navigator.of(context).pushNamed(Routes.advancedPrivacySettings,
arguments: walletRestoreViewModel.type); arguments: walletRestoreViewModel.type);
}, },
child: Text(S.of(context).advanced_privacy_settings), child: Text(S.of(context).advanced_settings),
), ),
], ],
), ),
@ -238,9 +225,26 @@ class WalletRestorePage extends BasePage {
); );
} }
void _validateOnChange({bool isPolyseed = false}) {
if (!isPolyseed && walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
final hasHeight = walletRestoreFromSeedFormKey
.currentState?.blockchainHeightKey.currentState?.restoreHeightController.text.isNotEmpty;
if (hasHeight == true) {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
} else {
walletRestoreViewModel.isButtonEnabled = _isValidSeed();
}
}
bool _isValidSeed() { bool _isValidSeed() {
final seedWords = final seedPhrase =
walletRestoreFromSeedFormKey.currentState!.seedWidgetStateKey.currentState!.text.split(' '); walletRestoreFromSeedFormKey.currentState!.seedWidgetStateKey.currentState!.text;
if (walletRestoreViewModel.type == WalletType.monero && Polyseed.isValidSeed(seedPhrase))
return true;
final seedWords = seedPhrase.split(' ');
if ((walletRestoreViewModel.type == WalletType.monero || if ((walletRestoreViewModel.type == WalletType.monero ||
walletRestoreViewModel.type == WalletType.haven) && walletRestoreViewModel.type == WalletType.haven) &&
@ -285,7 +289,8 @@ class WalletRestorePage extends BasePage {
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) { if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
credentials['height'] = credentials['height'] =
walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey.currentState!.height; walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey.currentState?.height ??
-1;
} }
credentials['name'] = credentials['name'] =

View file

@ -1,95 +0,0 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart';
class SeedLanguage extends BasePage {
SeedLanguage({required this.onConfirm});
final Function(BuildContext, String) onConfirm;
final walletNameImage = Image.asset('assets/images/wallet_name.png');
final walletNameLightImage =
Image.asset('assets/images/wallet_name_light.png');
@override
String get title => S.current.wallet_list_restore_wallet;
@override
Widget body(BuildContext context) =>
SeedLanguageForm(
onConfirm: onConfirm,
walletImage: currentTheme.type == ThemeType.dark
? walletNameImage : walletNameLightImage);
}
class SeedLanguageForm extends StatefulWidget {
SeedLanguageForm({required this.onConfirm, required this.walletImage});
final Function(BuildContext, String) onConfirm;
final Image walletImage;
@override
SeedLanguageFormState createState() => SeedLanguageFormState();
}
class SeedLanguageFormState extends State<SeedLanguageForm> {
static const aspectRatioImage = 1.22;
final _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>();
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 24),
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
content:
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
Padding(
padding: EdgeInsets.only(left: 12, right: 12),
child: AspectRatio(
aspectRatio: aspectRatioImage,
child: FittedBox(child: widget.walletImage,
fit: BoxFit.fill)),
),
Padding(
padding: EdgeInsets.only(top: 40),
child: Text(
S.of(context).seed_language_choose,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
),
Padding(
padding: EdgeInsets.only(top: 24),
child: SeedLanguageSelector(
key: _languageSelectorKey,
initialSelected: defaultSeedLanguage),
)
]),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Observer(
builder: (context) {
return PrimaryButton(
onPressed: () => widget.onConfirm(
context, _languageSelectorKey.currentState!.selected),
text: S.of(context).seed_language_next,
color: Colors.green,
textColor: Colors.white);
},
)),
);
}
}

View file

@ -1,82 +0,0 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
List<Image> flagImages = [
Image.asset('assets/images/flags/usa.png'),
Image.asset('assets/images/flags/chn.png'),
Image.asset('assets/images/flags/nld.png'),
Image.asset('assets/images/flags/deu.png'),
Image.asset('assets/images/flags/jpn.png'),
Image.asset('assets/images/flags/prt.png'),
Image.asset('assets/images/flags/rus.png'),
Image.asset('assets/images/flags/esp.png'),
Image.asset('assets/images/flags/fra.png'),
Image.asset('assets/images/flags/ita.png'),
];
const List<String> languageCodes = [
'Eng',
'Chi',
'Ned',
'Ger',
'Jap',
'Por',
'Rus',
'Esp',
'Fre',
'Ita',
];
const defaultSeedLanguage = 'English';
const List<String> seedLanguages = [
defaultSeedLanguage,
'Chinese (simplified)',
'Dutch',
'German',
'Japanese',
'Portuguese',
'Russian',
'Spanish',
'French',
'Italian',
];
enum Places { topLeft, topRight, bottomLeft, bottomRight, inside }
class SeedLanguagePicker extends StatefulWidget {
SeedLanguagePicker({Key? key, this.selected = defaultSeedLanguage, required this.onItemSelected})
: super(key: key);
final String selected;
final Function(String) onItemSelected;
@override
SeedLanguagePickerState createState() =>
SeedLanguagePickerState(selected: selected, onItemSelected: onItemSelected);
}
class SeedLanguagePickerState extends State<SeedLanguagePicker> {
SeedLanguagePickerState({required this.selected, required this.onItemSelected});
final String selected;
final Function(String) onItemSelected;
@override
Widget build(BuildContext context) {
return Picker(
selectedAtIndex: seedLanguages.indexOf(selected),
items: seedLanguages,
images: flagImages,
isGridView: true,
title: S.of(context).seed_choose,
hintText: S.of(context).seed_choose,
matchingCriteria: (String language, String searchText) {
return language.toLowerCase().contains(searchText);
},
onItemSelected: onItemSelected,
);
}
}

View file

@ -3,8 +3,8 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arro
import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/wallet_connect_button.dart'; import 'package:cake_wallet/src/screens/settings/widgets/wallet_connect_button.dart';
import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/settings/sync_mode.dart'; import 'package:cake_wallet/view_model/settings/sync_mode.dart';
@ -90,7 +90,12 @@ class ConnectionSyncPage extends BasePage {
onTap: () => Navigator.of(context).pushNamed(Routes.walletConnectConnectionsListing), onTap: () => Navigator.of(context).pushNamed(Routes.walletConnectConnectionsListing),
), ),
const StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)), const StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)),
] ],
if (FeatureFlag.isInAppTorEnabled)
SettingsCellWithArrow(
title: S.current.tor_connection,
handler: (context) => Navigator.of(context).pushNamed(Routes.torPage),
),
], ],
), ),
); );

View file

@ -22,7 +22,8 @@ class PrivacyPage extends BasePage {
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
return Container( return SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(top: 10), padding: EdgeInsets.only(top: 10),
child: Observer(builder: (_) { child: Observer(builder: (_) {
return Column( return Column(
@ -97,6 +98,7 @@ class PrivacyPage extends BasePage {
], ],
); );
}), }),
),
); );
} }
} }

View file

@ -0,0 +1,267 @@
import 'dart:async';
import 'dart:io';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:flutter/material.dart';
import 'package:tor/tor.dart';
class TorPage extends BasePage {
final AppStore appStore;
TorPage(this.appStore);
@override
Widget body(BuildContext context) {
return TorPageBody(appStore);
}
}
class TorPageBody extends StatefulWidget {
final AppStore appStore;
const TorPageBody(this.appStore, {Key? key}) : super(key: key);
@override
State<TorPageBody> createState() => _TorPageBodyState();
}
class _TorPageBodyState extends State<TorPageBody> {
bool torEnabled = false;
bool connecting = false;
// Set the default text for the host input field.
final hostController = TextEditingController(text: 'https://icanhazip.com/');
// https://check.torproject.org is another good option.
Future<void> startTor() async {
setState(() {
connecting = true; // Update flag
});
await Tor.init();
// Start the proxy
await Tor.instance.start();
// Toggle started flag.
setState(() {
torEnabled = Tor.instance.enabled; // Update flag
connecting = false;
});
final node = widget.appStore.settingsStore.getCurrentNode(widget.appStore.wallet!.type);
if (node.socksProxyAddress?.isEmpty ?? true) {
node.socksProxyAddress = "${InternetAddress.loopbackIPv4.address}:${Tor.instance.port}";
}
widget.appStore.wallet!.connectToNode(node: node);
print('Done awaiting; tor should be running');
}
Future<void> endTor() async {
// Start the proxy
Tor.instance.disable();
// Toggle started flag.
setState(() {
torEnabled = Tor.instance.enabled; // Update flag
});
print('Done awaiting; tor should be stopped');
}
@override
void initState() {
super.initState();
torEnabled = Tor.instance.enabled;
}
@override
void dispose() {
// Clean up the controller when the widget is disposed.
hostController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(10),
child: connecting
? ConnectingScreen()
: torEnabled
? DisconnectScreen(disconnect: endTor)
: ConnectScreen(connect: startTor),
),
);
}
}
class ConnectScreen extends StatelessWidget {
final Function() connect;
const ConnectScreen({super.key, required this.connect});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue,
),
child: Icon(
Icons.lock,
color: Colors.white,
size: 100,
),
),
SizedBox(height: 20),
Text(
'Connect to Tor',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10),
Text(
'Your connection to the Tor network ensures privacy and security.',
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
textAlign: TextAlign.center,
),
SizedBox(height: 30),
ElevatedButton(
onPressed: connect,
style: ElevatedButton.styleFrom(
primary: Colors.blue,
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
child: Text(
'Connect',
style: TextStyle(
fontSize: 18,
color: Colors.white,
),
),
),
],
),
);
}
}
class DisconnectScreen extends StatelessWidget {
final Function() disconnect;
const DisconnectScreen({super.key, required this.disconnect});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.green,
),
child: Icon(
Icons.check,
color: Colors.white,
size: 100,
),
),
SizedBox(height: 20),
Text(
'Connected to Tor',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10),
Text(
'You are currently connected to the Tor network.',
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
textAlign: TextAlign.center,
),
SizedBox(height: 30),
ElevatedButton(
onPressed: disconnect,
style: ElevatedButton.styleFrom(
primary: Colors.red,
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
child: Text(
'Disconnect',
style: TextStyle(
fontSize: 18,
color: Colors.white,
),
),
),
],
),
);
}
}
class ConnectingScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.yellow,
),
child: Icon(
Icons.hourglass_bottom,
color: Colors.white,
size: 100,
),
),
SizedBox(height: 20),
Text(
'Connecting...',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10),
],
),
);
}
}

View file

@ -57,6 +57,8 @@ class ChatwootWidgetState extends State<ChatwootWidget> {
return true; return true;
} }
Future<void> storeCookie(String value) async => Future<void> storeCookie(String value) async {
await widget.secureStorage.delete(key: COOKIE_KEY);
await widget.secureStorage.write(key: COOKIE_KEY, value: value); await widget.secureStorage.write(key: COOKIE_KEY, value: value);
}
} }

View file

@ -31,6 +31,8 @@ class WalletConnectConnectionsView extends StatelessWidget {
final actualLinkList = launchUri.query.split("uri="); final actualLinkList = launchUri.query.split("uri=");
if (actualLinkList.length <= 1) return;
final query = actualLinkList[1]; final query = actualLinkList[1];
final uri = Uri.decodeComponent(query); final uri = Uri.decodeComponent(query);

View file

@ -68,13 +68,16 @@ class AddressTextField extends StatelessWidget {
enabled: isActive, enabled: isActive,
controller: controller, controller: controller,
focusNode: focusNode, focusNode: focusNode,
style: textStyle ?? style: textStyle ??
TextStyle( TextStyle(
fontSize: 16, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor), fontSize: 16, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
decoration: InputDecoration( decoration: InputDecoration(
suffixIcon: SizedBox( suffixIcon: SizedBox(
width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length), width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length),
), ),
hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Theme.of(context).hintColor), hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Theme.of(context).hintColor),
hintText: placeholder ?? S.current.widgets_address, hintText: placeholder ?? S.current.widgets_address,
focusedBorder: isBorderExist focusedBorder: isBorderExist

View file

@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/entities/seed_type.dart';
class SeedLanguagePickerOption {
SeedLanguagePickerOption(this.name, this.nameLocalized, this.image, this.supportedSeedTypes);
final String name;
final String nameLocalized;
final Image image;
final List<SeedType> supportedSeedTypes;
}
final List<SeedLanguagePickerOption> seedLanguages = [
SeedLanguagePickerOption('English', S.current.seed_language_english,
Image.asset('assets/images/flags/usa.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('Chinese (simplified)', S.current.seed_language_chinese,
Image.asset('assets/images/flags/chn.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('Chinese (Traditional)', S.current.seed_language_chinese_traditional,
Image.asset('assets/images/flags/chn.png'), [SeedType.polyseed]),
SeedLanguagePickerOption('Dutch', S.current.seed_language_dutch,
Image.asset('assets/images/flags/nld.png'), [SeedType.legacy]),
SeedLanguagePickerOption('German', S.current.seed_language_german,
Image.asset('assets/images/flags/deu.png'), [SeedType.legacy]),
SeedLanguagePickerOption('Japanese', S.current.seed_language_japanese,
Image.asset('assets/images/flags/jpn.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('Korean', S.current.seed_language_korean,
Image.asset('assets/images/flags/kor.png'), [SeedType.polyseed]),
SeedLanguagePickerOption('Portuguese', S.current.seed_language_portuguese,
Image.asset('assets/images/flags/prt.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('Russian', S.current.seed_language_russian,
Image.asset('assets/images/flags/rus.png'), [SeedType.legacy]),
SeedLanguagePickerOption('Czech', S.current.seed_language_czech,
Image.asset('assets/images/flags/czk.png'), [SeedType.polyseed]),
SeedLanguagePickerOption('Spanish', S.current.seed_language_spanish,
Image.asset('assets/images/flags/esp.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('French', S.current.seed_language_french,
Image.asset('assets/images/flags/fra.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('Italian', S.current.seed_language_italian,
Image.asset('assets/images/flags/ita.png'), [SeedType.legacy, SeedType.polyseed]),
];
const defaultSeedLanguage = 'English';
enum Places { topLeft, topRight, bottomLeft, bottomRight, inside }
class SeedLanguagePicker extends StatefulWidget {
SeedLanguagePicker(
{Key? key,
this.selected = defaultSeedLanguage,
this.seedType = SeedType.defaultSeedType,
required this.onItemSelected})
: super(key: key);
final SeedType seedType;
final String selected;
final Function(String) onItemSelected;
@override
SeedLanguagePickerState createState() => SeedLanguagePickerState(
selected: selected, onItemSelected: onItemSelected, seedType: seedType);
}
class SeedLanguagePickerState extends State<SeedLanguagePicker> {
SeedLanguagePickerState(
{required this.selected, required this.onItemSelected, required this.seedType});
final SeedType seedType;
final String selected;
final Function(String) onItemSelected;
@override
Widget build(BuildContext context) {
final availableSeedLanguages = seedLanguages
.where((SeedLanguagePickerOption e) => e.supportedSeedTypes.contains(seedType));
return Picker(
selectedAtIndex: availableSeedLanguages.map((e) => e.name).toList().indexOf(selected),
items: availableSeedLanguages.map((e) => e.name).toList(),
images: availableSeedLanguages.map((e) => e.image).toList(),
isGridView: true,
title: S.of(context).seed_choose,
hintText: S.of(context).seed_choose,
matchingCriteria: (String language, String searchText) {
return language.toLowerCase().contains(searchText);
},
onItemSelected: onItemSelected,
);
}
}

View file

@ -1,49 +1,42 @@
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/entities/seed_type.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart'; import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart'; import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart';
class SeedLanguageSelector extends StatefulWidget { class SeedLanguageSelector extends StatefulWidget {
SeedLanguageSelector({Key? key, required this.initialSelected}) SeedLanguageSelector(
{Key? key, required this.initialSelected, this.seedType = SeedType.defaultSeedType})
: super(key: key); : super(key: key);
final String initialSelected; final String initialSelected;
final SeedType seedType;
@override @override
SeedLanguageSelectorState createState() => SeedLanguageSelectorState createState() => SeedLanguageSelectorState(selected: initialSelected);
SeedLanguageSelectorState(selected: initialSelected);
} }
class SeedLanguageSelectorState extends State<SeedLanguageSelector> { class SeedLanguageSelectorState extends State<SeedLanguageSelector> {
SeedLanguageSelectorState({required this.selected}); SeedLanguageSelectorState({required this.selected});
final seedLocales = [
S.current.seed_language_english,
S.current.seed_language_chinese,
S.current.seed_language_dutch,
S.current.seed_language_german,
S.current.seed_language_japanese,
S.current.seed_language_portuguese,
S.current.seed_language_russian,
S.current.seed_language_spanish,
S.current.seed_language_french,
S.current.seed_language_italian,
];
String selected; String selected;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SelectButton( return SelectButton(
image: null, image: null,
text: seedLocales[seedLanguages.indexOf(selected)], text:
"${seedLanguages.firstWhere((e) => e.name == selected).nameLocalized} (${S.of(context).seed_language})",
onTap: () async { onTap: () async {
await showPopUp<String>( await showPopUp<String>(
context: context, context: context,
builder: (_) => SeedLanguagePicker( builder: (_) => SeedLanguagePicker(
selected: this.selected, selected: this.selected,
onItemSelected: (String selected) => seedType: widget.seedType,
setState(() => this.selected = selected))); onItemSelected: (String selected) => setState(() => this.selected = selected),
),
);
}, },
); );
} }

View file

@ -10,6 +10,7 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/pin_code_required_duration.dart'; import 'package:cake_wallet/entities/pin_code_required_duration.dart';
import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/seed_phrase_length.dart'; import 'package:cake_wallet/entities/seed_phrase_length.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/entities/sort_balance_types.dart'; import 'package:cake_wallet/entities/sort_balance_types.dart';
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart'; import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
import 'package:cake_wallet/view_model/settings/sync_mode.dart'; import 'package:cake_wallet/view_model/settings/sync_mode.dart';
@ -48,6 +49,7 @@ abstract class SettingsStoreBase with Store {
required BalanceDisplayMode initialBalanceDisplayMode, required BalanceDisplayMode initialBalanceDisplayMode,
required bool initialSaveRecipientAddress, required bool initialSaveRecipientAddress,
required AutoGenerateSubaddressStatus initialAutoGenerateSubaddressStatus, required AutoGenerateSubaddressStatus initialAutoGenerateSubaddressStatus,
required SeedType initialMoneroSeedType,
required bool initialAppSecure, required bool initialAppSecure,
required bool initialDisableBuy, required bool initialDisableBuy,
required bool initialDisableSell, required bool initialDisableSell,
@ -108,6 +110,7 @@ abstract class SettingsStoreBase with Store {
balanceDisplayMode = initialBalanceDisplayMode, balanceDisplayMode = initialBalanceDisplayMode,
shouldSaveRecipientAddress = initialSaveRecipientAddress, shouldSaveRecipientAddress = initialSaveRecipientAddress,
autoGenerateSubaddressStatus = initialAutoGenerateSubaddressStatus, autoGenerateSubaddressStatus = initialAutoGenerateSubaddressStatus,
moneroSeedType = initialMoneroSeedType,
fiatApiMode = initialFiatMode, fiatApiMode = initialFiatMode,
allowBiometricalAuthentication = initialAllowBiometricalAuthentication, allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
selectedCake2FAPreset = initialCake2FAPresetOptions, selectedCake2FAPreset = initialCake2FAPresetOptions,
@ -240,6 +243,11 @@ abstract class SettingsStoreBase with Store {
(AutoGenerateSubaddressStatus autoGenerateSubaddressStatus) => sharedPreferences.setInt( (AutoGenerateSubaddressStatus autoGenerateSubaddressStatus) => sharedPreferences.setInt(
PreferencesKey.autoGenerateSubaddressStatusKey, autoGenerateSubaddressStatus.value)); PreferencesKey.autoGenerateSubaddressStatusKey, autoGenerateSubaddressStatus.value));
reaction(
(_) => moneroSeedType,
(SeedType moneroSeedType) => sharedPreferences.setInt(
PreferencesKey.moneroSeedType, moneroSeedType.raw));
reaction( reaction(
(_) => fiatApiMode, (_) => fiatApiMode,
(FiatApiMode mode) => (FiatApiMode mode) =>
@ -435,6 +443,7 @@ abstract class SettingsStoreBase with Store {
static const defaultPinCodeTimeOutDuration = PinCodeRequiredDuration.tenminutes; static const defaultPinCodeTimeOutDuration = PinCodeRequiredDuration.tenminutes;
static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized; static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords; static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords;
static const defaultMoneroSeedType = SeedType.defaultSeedType;
@observable @observable
FiatCurrency fiatCurrency; FiatCurrency fiatCurrency;
@ -460,6 +469,9 @@ abstract class SettingsStoreBase with Store {
@observable @observable
AutoGenerateSubaddressStatus autoGenerateSubaddressStatus; AutoGenerateSubaddressStatus autoGenerateSubaddressStatus;
@observable
SeedType moneroSeedType;
@observable @observable
bool isAppSecure; bool isAppSecure;
@ -775,12 +787,20 @@ abstract class SettingsStoreBase with Store {
final packageInfo = await PackageInfo.fromPlatform(); final packageInfo = await PackageInfo.fromPlatform();
final deviceName = await _getDeviceName() ?? ''; final deviceName = await _getDeviceName() ?? '';
final shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true; final shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
final generateSubaddresses = final generateSubaddresses =
sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey); sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
final autoGenerateSubaddressStatus = generateSubaddresses != null final autoGenerateSubaddressStatus = generateSubaddresses != null
? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses) ? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
: defaultAutoGenerateSubaddressStatus; : defaultAutoGenerateSubaddressStatus;
final _moneroSeedType = sharedPreferences.getInt(PreferencesKey.moneroSeedType);
final moneroSeedType = _moneroSeedType != null
? SeedType.deserialize(raw: _moneroSeedType)
: defaultMoneroSeedType;
final nodes = <WalletType, Node>{}; final nodes = <WalletType, Node>{};
final powNodes = <WalletType, Node>{}; final powNodes = <WalletType, Node>{};
@ -833,6 +853,7 @@ abstract class SettingsStoreBase with Store {
initialBalanceDisplayMode: currentBalanceDisplayMode, initialBalanceDisplayMode: currentBalanceDisplayMode,
initialSaveRecipientAddress: shouldSaveRecipientAddress, initialSaveRecipientAddress: shouldSaveRecipientAddress,
initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus, initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus,
initialMoneroSeedType: moneroSeedType,
initialAppSecure: isAppSecure, initialAppSecure: isAppSecure,
initialDisableBuy: disableBuy, initialDisableBuy: disableBuy,
initialDisableSell: disableSell, initialDisableSell: disableSell,
@ -848,8 +869,7 @@ abstract class SettingsStoreBase with Store {
actionlistDisplayMode: actionListDisplayMode, actionlistDisplayMode: actionListDisplayMode,
initialPinLength: pinLength, initialPinLength: pinLength,
pinTimeOutDuration: pinCodeTimeOutDuration, pinTimeOutDuration: pinCodeTimeOutDuration,
seedPhraseLength: seedPhraseWordCount, seedPhraseLength: seedPhraseWordCount,initialLanguageCode: savedLanguageCode,
initialLanguageCode: savedLanguageCode,
sortBalanceBy: sortBalanceBy, sortBalanceBy: sortBalanceBy,
pinNativeTokenAtTop: pinNativeTokenAtTop, pinNativeTokenAtTop: pinNativeTokenAtTop,
useEtherscan: useEtherscan, useEtherscan: useEtherscan,
@ -927,6 +947,12 @@ abstract class SettingsStoreBase with Store {
? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses) ? AutoGenerateSubaddressStatus.deserialize(raw: generateSubaddresses)
: defaultAutoGenerateSubaddressStatus; : defaultAutoGenerateSubaddressStatus;
final _moneroSeedType = sharedPreferences.getInt(PreferencesKey.moneroSeedType);
moneroSeedType = _moneroSeedType != null
? SeedType.deserialize(raw: _moneroSeedType)
: defaultMoneroSeedType;
balanceDisplayMode = BalanceDisplayMode.deserialize( balanceDisplayMode = BalanceDisplayMode.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!); raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
shouldSaveRecipientAddress = shouldSaveRecipientAddress =

View file

@ -162,6 +162,7 @@ class ExceptionHandler {
"Error while launching http", "Error while launching http",
"OS Error: Network is unreachable", "OS Error: Network is unreachable",
"ClientException: Write failed, uri=http", "ClientException: Write failed, uri=http",
"Connection terminated during handshake",
]; ];
static Future<void> _addDeviceInfo(File file) async { static Future<void> _addDeviceInfo(File file) async {

View file

@ -1,4 +1,5 @@
class FeatureFlag { class FeatureFlag {
static const bool isCakePayEnabled = false; static const bool isCakePayEnabled = false;
static const bool isExolixEnabled = false; static const bool isExolixEnabled = false;
static const bool isInAppTorEnabled = false;
} }

View file

@ -1,6 +1,7 @@
import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/seed_phrase_length.dart'; import 'package:cake_wallet/entities/seed_phrase_length.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
@ -19,6 +20,9 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
@computed @computed
FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode; FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode;
@computed
SeedType get seedType => _settingsStore.moneroSeedType;
@observable @observable
bool _addCustomNode = false; bool _addCustomNode = false;
@ -29,6 +33,8 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
bool get hasSeedPhraseLengthOption => bool get hasSeedPhraseLengthOption =>
type == WalletType.bitcoinCash || type == WalletType.ethereum; type == WalletType.bitcoinCash || type == WalletType.ethereum;
bool get hasSeedTypeOption => type == WalletType.monero;
@computed @computed
bool get addCustomNode => _addCustomNode; bool get addCustomNode => _addCustomNode;
@ -38,6 +44,9 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
@action @action
void setFiatApiMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode; void setFiatApiMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode;
@action
void setSeedType(SeedType seedType) => _settingsStore.moneroSeedType = seedType;
@action @action
void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value; void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value;

View file

@ -0,0 +1,142 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
import 'dart:developer';
import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart';
import 'package:cake_wallet/src/screens/wallet_connect/widgets/message_display_widget.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:http/http.dart' as http;
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/entities/wallet_nft_response.dart';
import 'package:cake_wallet/store/app_store.dart';
part 'nft_view_model.g.dart';
class NFTViewModel = NFTViewModelBase with _$NFTViewModel;
abstract class NFTViewModelBase with Store {
NFTViewModelBase(this.appStore, this.bottomSheetService)
: isLoading = false,
isImportNFTLoading = false,
nftAssetByWalletModels = ObservableList() {
getNFTAssetByWallet();
reaction((_) => appStore.wallet, (_) => getNFTAssetByWallet());
}
final AppStore appStore;
final BottomSheetService bottomSheetService;
@observable
bool isLoading;
@observable
bool isImportNFTLoading;
ObservableList<NFTAssetModel> nftAssetByWalletModels;
@action
Future<void> getNFTAssetByWallet() async {
if (appStore.wallet!.type != WalletType.ethereum) return;
final walletAddress = appStore.wallet!.walletInfo.address;
log('Fetching wallet NFTs for $walletAddress');
// the [chain] refers to the chain network that the nft is on
// the [format] refers to the number format type of the responses
// the [normalizedMetadata] field is a boolean that determines if
// the response would include a json string of the NFT Metadata that can be decoded
// and used within the wallet
final uri = Uri.https(
'deep-index.moralis.io',
'/api/v2.2/$walletAddress/nft',
{
"chain": "eth",
"format": "decimal",
"media_items": "false",
"normalizeMetadata": "true",
},
);
try {
isLoading = true;
final response = await http.get(
uri,
headers: {
"Accept": "application/json",
"X-API-Key": secrets.moralisApiKey,
},
);
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
final result = WalletNFTsResponseModel.fromJson(decodedResponse).result ?? [];
nftAssetByWalletModels.clear();
nftAssetByWalletModels.addAll(result);
isLoading = false;
} catch (e) {
isLoading = false;
log(e.toString());
bottomSheetService.queueBottomSheet(
isModalDismissible: true,
widget: BottomSheetMessageDisplayWidget(
message: e.toString(),
),
);
}
}
@action
Future<void> importNFT(String tokenAddress, String tokenId) async {
// the [chain] refers to the chain network that the nft is on
// the [format] refers to the number format type of the responses
// the [normalizedMetadata] field is a boolean that determines if
// the response would include a json string of the NFT Metadata that can be decoded
// and used within the wallet
final uri = Uri.https(
'deep-index.moralis.io',
'/api/v2.2/nft/$tokenAddress/$tokenId',
{
"chain": "eth",
"format": "decimal",
"media_items": "false",
"normalizeMetadata": "true",
},
);
try {
isImportNFTLoading = true;
final response = await http.get(
uri,
headers: {
"Accept": "application/json",
"X-API-Key": secrets.moralisApiKey,
},
);
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
final nftAsset = NFTAssetModel.fromJson(decodedResponse);
nftAssetByWalletModels.add(nftAsset);
isImportNFTLoading = false;
} catch (e) {
isImportNFTLoading = false;
bottomSheetService.queueBottomSheet(
isModalDismissible: true,
widget: BottomSheetMessageDisplayWidget(
message: e.toString(),
),
);
}
}
}

View file

@ -37,6 +37,7 @@ abstract class EditBackupPasswordViewModelBase with Store {
@action @action
Future<void> save() async { Future<void> save() async {
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
await secureStorage.delete(key: key);
await secureStorage.write(key: key, value: backupPassword); await secureStorage.write(key: key, value: backupPassword);
secretStore.write(key: key, value: backupPassword); secretStore.write(key: key, value: backupPassword);
} }

View file

@ -45,7 +45,7 @@ class RestoredWallet {
factory RestoredWallet.fromSeed(Map<String, dynamic> json) { factory RestoredWallet.fromSeed(Map<String, dynamic> json) {
final height = json['height'] as String?; final height = json['height'] as String?;
final mnemonic_seed = json['mnemonic_seed'] as String?; final mnemonic_seed = json['mnemonic_seed'] as String?;
final seed = json['seed'] as String?; final seed = json['seed'] as String? ?? json['hexSeed'] as String?;
return RestoredWallet( return RestoredWallet(
restoreMode: json['mode'] as WalletRestoreMode, restoreMode: json['mode'] as WalletRestoreMode,
type: json['type'] as WalletType, type: json['type'] as WalletType,

View file

@ -10,6 +10,7 @@ import 'package:cw_core/wallet_type.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:polyseed/polyseed.dart';
class WalletRestoreFromQRCode { class WalletRestoreFromQRCode {
WalletRestoreFromQRCode(); WalletRestoreFromQRCode();
@ -51,7 +52,7 @@ class WalletRestoreFromQRCode {
RegExp _getPattern(int wordCount) => RegExp _getPattern(int wordCount) =>
RegExp(r'(?<=\W|^)((?:\w+\s+){' + (wordCount - 1).toString() + r'}\w+)(?=\W|$)'); RegExp(r'(?<=\W|^)((?:\w+\s+){' + (wordCount - 1).toString() + r'}\w+)(?=\W|$)');
List<int> patternCounts = walletType == WalletType.monero ? [25, 14, 13] : [24, 18, 12]; List<int> patternCounts = walletType == WalletType.monero ? [25, 16, 14, 13] : [24, 18, 12];
for (final count in patternCounts) { for (final count in patternCounts) {
final pattern = _getPattern(count); final pattern = _getPattern(count);
@ -123,12 +124,17 @@ class WalletRestoreFromQRCode {
} }
if (credentials['seed'] != null) { if (credentials['seed'] != null) {
final seedValue = credentials['seed']; final seedValue = credentials['seed'] as String;
final words = SeedValidator.getWordList(type: type, language: 'english'); final words = SeedValidator.getWordList(type: type, language: 'english');
if (type == WalletType.monero && Polyseed.isValidSeed(seedValue)) {
return WalletRestoreMode.seed;
}
seedValue.split(' ').forEach((element) { seedValue.split(' ').forEach((element) {
if (!words.contains(element)) { if (!words.contains(element)) {
throw Exception( throw Exception(
'Unexpected restore mode: mnemonic_seed is invalid or does\'t match wallet type'); "Unexpected restore mode: mnemonic_seed is invalid or doesn't match wallet type");
} }
}); });
return WalletRestoreMode.seed; return WalletRestoreMode.seed;
@ -151,6 +157,14 @@ class WalletRestoreFromQRCode {
return WalletRestoreMode.keys; return WalletRestoreMode.keys;
} }
if ((type == WalletType.nano || type == WalletType.banano) && credentials.containsKey('hexSeed')) {
final hexSeed = credentials['hexSeed'] as String;
if (hexSeed.isEmpty) {
throw Exception('Unexpected restore mode: hexSeed');
}
return WalletRestoreMode.seed;
}
throw Exception('Unexpected restore mode: restore params are invalid'); throw Exception('Unexpected restore mode: restore params are invalid');
} }
} }

View file

@ -107,19 +107,18 @@ abstract class WalletKeysViewModelBase with Store {
]); ]);
} }
if (_appStore.wallet!.type == WalletType.nano || _appStore.wallet!.type == WalletType.banano) { bool nanoBased =
_appStore.wallet!.type == WalletType.nano || _appStore.wallet!.type == WalletType.banano;
// we don't necessarily have the seed phrase for nano / banano: if (nanoBased) {
if (_appStore.wallet!.seed != null) { // we always have the hex version of the seed and private key:
items.addAll([ items.addAll([
if (_appStore.wallet!.seed != null)
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!), StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
]); if (_appStore.wallet!.hexSeed != null)
} StandartListItem(title: S.current.seed_hex_form, value: _appStore.wallet!.hexSeed!),
// we always have the hex version of the seed:
items.addAll([
if (_appStore.wallet!.privateKey != null) if (_appStore.wallet!.privateKey != null)
StandartListItem(title: S.current.spend_key_private, value: _appStore.wallet!.privateKey!), StandartListItem(title: S.current.private_key, value: _appStore.wallet!.privateKey!),
]); ]);
} }
} }
@ -172,7 +171,10 @@ abstract class WalletKeysViewModelBase with Store {
final restoreHeightResult = await restoreHeight; final restoreHeightResult = await restoreHeight;
return { return {
if (_appStore.wallet!.seed != null) 'seed': _appStore.wallet!.seed!, if (_appStore.wallet!.seed != null) 'seed': _appStore.wallet!.seed!,
if (_appStore.wallet!.privateKey != null) 'private_key': _appStore.wallet!.privateKey!, if (_appStore.wallet!.seed == null && _appStore.wallet!.hexSeed != null)
'hexSeed': _appStore.wallet!.hexSeed!,
if (_appStore.wallet!.seed == null && _appStore.wallet!.privateKey != null)
'private_key': _appStore.wallet!.privateKey!,
if (restoreHeightResult != null) ...{'height': restoreHeightResult} if (restoreHeightResult != null) ...{'height': restoreHeightResult}
}; };
} }

View file

@ -1,6 +1,4 @@
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart'; import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
@ -32,17 +30,22 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
bool get hasLanguageSelector => type == WalletType.monero || type == WalletType.haven; bool get hasLanguageSelector => type == WalletType.monero || type == WalletType.haven;
bool get hasSeedType => type == WalletType.monero;
@override @override
WalletCredentials getCredentials(dynamic options) { WalletCredentials getCredentials(dynamic _options) {
final options = _options as List<dynamic>?;
switch (type) { switch (type) {
case WalletType.monero: case WalletType.monero:
return monero!.createMoneroNewWalletCredentials(name: name, language: options as String); return monero!.createMoneroNewWalletCredentials(
name: name, language: options!.first as String, isPolyseed: options.last as bool);
case WalletType.bitcoin: case WalletType.bitcoin:
return bitcoin!.createBitcoinNewWalletCredentials(name: name); return bitcoin!.createBitcoinNewWalletCredentials(name: name);
case WalletType.litecoin: case WalletType.litecoin:
return bitcoin!.createBitcoinNewWalletCredentials(name: name); return bitcoin!.createBitcoinNewWalletCredentials(name: name);
case WalletType.haven: case WalletType.haven:
return haven!.createHavenNewWalletCredentials(name: name, language: options as String); return haven!
.createHavenNewWalletCredentials(name: name, language: options!.first as String);
case WalletType.ethereum: case WalletType.ethereum:
return ethereum!.createEthereumNewWalletCredentials(name: name); return ethereum!.createEthereumNewWalletCredentials(name: name);
case WalletType.bitcoinCash: case WalletType.bitcoinCash:

View file

@ -30,13 +30,11 @@ PODS:
- FlutterMacOS - FlutterMacOS
- package_info (0.0.1): - package_info (0.0.1):
- FlutterMacOS - FlutterMacOS
- package_info_plus (0.0.1):
- FlutterMacOS
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- platform_device_id (0.0.1):
- FlutterMacOS
- platform_device_id_macos (0.0.1):
- FlutterMacOS
- ReachabilitySwift (5.0.0) - ReachabilitySwift (5.0.0)
- share_plus_macos (0.0.1): - share_plus_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
@ -45,7 +43,7 @@ PODS:
- FlutterMacOS - FlutterMacOS
- url_launcher_macos (0.0.1): - url_launcher_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- wakelock_macos (0.0.1): - wakelock_plus (0.0.1):
- FlutterMacOS - FlutterMacOS
DEPENDENCIES: DEPENDENCIES:
@ -57,13 +55,12 @@ DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`) - FlutterMacOS (from `Flutter/ephemeral`)
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`) - in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
- package_info (from `Flutter/ephemeral/.symlinks/plugins/package_info/macos`) - package_info (from `Flutter/ephemeral/.symlinks/plugins/package_info/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - 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`) - share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`) - wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
SPEC REPOS: SPEC REPOS:
trunk: trunk:
@ -86,20 +83,18 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos :path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos
package_info: package_info:
:path: Flutter/ephemeral/.symlinks/plugins/package_info/macos :path: Flutter/ephemeral/.symlinks/plugins/package_info/macos
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation: path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin :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:
:path: Flutter/ephemeral/.symlinks/plugins/platform_device_id_macos/macos
share_plus_macos: share_plus_macos:
:path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos
shared_preferences_foundation: shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
url_launcher_macos: url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
wakelock_macos: wakelock_plus:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
SPEC CHECKSUMS: SPEC CHECKSUMS:
connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308 connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308
@ -110,14 +105,13 @@ SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0 in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0
package_info: 6eba2fd8d3371dda2d85c8db6fe97488f24b74b2 package_info: 6eba2fd8d3371dda2d85c8db6fe97488f24b74b2
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
platform_device_id: 3e414428f45df149bbbfb623e2c0ca27c545b763
platform_device_id_macos: f763bb55f088be804d61b96eb4710b8ab6598e94
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4 share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
PODFILE CHECKSUM: 5107934592df7813b33d744aebc8ddc6b5a5445f PODFILE CHECKSUM: 5107934592df7813b33d744aebc8ddc6b5a5445f

View file

@ -83,7 +83,7 @@ dependencies:
ref: main ref: main
version: 1.0.0 version: 1.0.0
flutter_plugin_android_lifecycle: 2.0.9 flutter_plugin_android_lifecycle: 2.0.9
path_provider_android: 2.0.24 path_provider_android: ^2.2.1
shared_preferences_android: 2.0.17 shared_preferences_android: 2.0.17
url_launcher_android: 6.0.24 url_launcher_android: 6.0.24
sensitive_clipboard: ^1.0.0 sensitive_clipboard: ^1.0.0
@ -98,6 +98,15 @@ dependencies:
url: https://github.com/cake-tech/bitcoin_flutter.git url: https://github.com/cake-tech/bitcoin_flutter.git
ref: silent-payments ref: silent-payments
fluttertoast: 8.1.4 fluttertoast: 8.1.4
tor:
git:
url: https://github.com/cake-tech/tor.git
ref: main
socks5_proxy: ^1.0.4
flutter_svg: ^2.0.9
polyseed:
git:
url: https://github.com/cake-tech/polyseed_dart.git
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -160,7 +160,7 @@
"seed_title": "سييد", "seed_title": "سييد",
"seed_share": "شارك السييد", "seed_share": "شارك السييد",
"copy": "نسخ", "copy": "نسخ",
"seed_language_choose": "الرجاء اختيار لغة السييد:", "seed_language": "لغة البذور",
"seed_choose": "اختر لغة السييد", "seed_choose": "اختر لغة السييد",
"seed_language_next": "التالي", "seed_language_next": "التالي",
"seed_language_english": "إنجليزي", "seed_language_english": "إنجليزي",
@ -383,7 +383,7 @@
"change_backup_password_alert": "لن تكون ملفات النسخ الاحتياطي السابقة متاحة للاستيراد بكلمة مرور نسخ احتياطي جديدة. سيتم استخدام كلمة مرور النسخ الاحتياطي الجديدة لملفات النسخ الاحتياطي الجديدة فقط. هل أنت متأكد أنك تريد تغيير كلمة المرور الاحتياطية؟", "change_backup_password_alert": "لن تكون ملفات النسخ الاحتياطي السابقة متاحة للاستيراد بكلمة مرور نسخ احتياطي جديدة. سيتم استخدام كلمة مرور النسخ الاحتياطي الجديدة لملفات النسخ الاحتياطي الجديدة فقط. هل أنت متأكد أنك تريد تغيير كلمة المرور الاحتياطية؟",
"enter_backup_password": "أدخل كلمة المرور الاحتياطية هنا", "enter_backup_password": "أدخل كلمة المرور الاحتياطية هنا",
"select_backup_file": "حدد ملف النسخ الاحتياطي", "select_backup_file": "حدد ملف النسخ الاحتياطي",
"import": "اختيار ملف", "import": "ﺩﺭﻮﺘﺴﻳ",
"please_select_backup_file": "الرجاء تحديد ملف النسخ الاحتياطي وإدخال كلمة مرور النسخ الاحتياطي.", "please_select_backup_file": "الرجاء تحديد ملف النسخ الاحتياطي وإدخال كلمة مرور النسخ الاحتياطي.",
"fixed_rate": "السعر الثابت", "fixed_rate": "السعر الثابت",
"fixed_rate_alert": "ستتمكن من إدخال مبلغ الاستلام عند تشغيل وضع السعر الثابت. هل تريد التبديل إلى وضع السعر الثابت؟", "fixed_rate_alert": "ستتمكن من إدخال مبلغ الاستلام عند تشغيل وضع السعر الثابت. هل تريد التبديل إلى وضع السعر الثابت؟",
@ -569,7 +569,7 @@
"always": "دائماً", "always": "دائماً",
"minutes_to_pin_code": "${minutes} دقيقة", "minutes_to_pin_code": "${minutes} دقيقة",
"disable_exchange": "تعطيل التبادل", "disable_exchange": "تعطيل التبادل",
"advanced_privacy_settings": "إعدادات الخصوصية المتقدمة", "advanced_settings": "إعدادات متقدمة",
"settings_can_be_changed_later": "يمكن تغيير هذه الإعدادات لاحقًا في إعدادات التطبيق", "settings_can_be_changed_later": "يمكن تغيير هذه الإعدادات لاحقًا في إعدادات التطبيق",
"add_custom_node": "إضافة عقدة مخصصة جديدة", "add_custom_node": "إضافة عقدة مخصصة جديدة",
"disable_fiat": "تعطيل fiat", "disable_fiat": "تعطيل fiat",
@ -727,11 +727,26 @@
"require_for_exchanges_to_external_wallets": "ﺔﻴﺟﺭﺎﺧ ﻆﻓﺎﺤﻣ ﻰﻟﺇ ﺕﻻﺩﺎﺒﺘﻟﺍ ﺐﻠﻄﺘﺗ", "require_for_exchanges_to_external_wallets": "ﺔﻴﺟﺭﺎﺧ ﻆﻓﺎﺤﻣ ﻰﻟﺇ ﺕﻻﺩﺎﺒﺘﻟﺍ ﺐﻠﻄﺘﺗ",
"camera_permission_is_required": ".ﺍﺮﻴﻣﺎﻜﻟﺍ ﻥﺫﺇ ﺏﻮﻠﻄﻣ", "camera_permission_is_required": ".ﺍﺮﻴﻣﺎﻜﻟﺍ ﻥﺫﺇ ﺏﻮﻠﻄﻣ",
"switchToETHWallet": "ﻯﺮﺧﺃ ﺓﺮﻣ ﺔﻟﻭﺎﺤﻤﻟﺍﻭ Ethereum ﺔﻈﻔﺤﻣ ﻰﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻰﺟﺮﻳ", "switchToETHWallet": "ﻯﺮﺧﺃ ﺓﺮﻣ ﺔﻟﻭﺎﺤﻤﻟﺍﻭ Ethereum ﺔﻈﻔﺤﻣ ﻰﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻰﺟﺮﻳ",
"seed_phrase_length": " ﺭﻭﺬﺒﻟﺍ ﺓﺭﺎﺒﻌﻟﺍ ﻝﻮﻃ", "importNFTs": "NFTs ﺩﺍﺮﻴﺘﺳﺍ",
"unavailable_balance": " ﺮﻓﻮﺘﻣ ﺮﻴﻏ ﺪﻴﺻﺭ", "noNFTYet": "ﻥﻵﺍ ﻰﺘﺣ NFTs ﺪﺟﻮﻳ ﻻ",
"address": " ﻥﺍﻮﻨﻋ",
"enterTokenID": "ﺰﻴﻤﻤﻟﺍ ﺰﻣﺮﻟﺍ ﻑﺮﻌﻣ ﻞﺧﺩﺃ",
"tokenID": "ﻒﻳﺮﻌﺗ ﺔﻗﺎﻄﺑ",
"name": "ﻢﺳﺍ",
"symbol": "ﺰﻣﺭ",
"seed_phrase_length": "ﺭﻭﺬﺒﻟﺍ ﺓﺭﺎﺒﻌﻟﺍ ﻝﻮﻃ",
"unavailable_balance": "ﺮﻓﻮﺘﻣ ﺮﻴﻏ ﺪﻴﺻﺭ",
"unavailable_balance_description": ".ﺎﻫﺪﻴﻤﺠﺗ ءﺎﻐﻟﺇ ﺭﺮﻘﺗ ﻰﺘﺣ ﺕﻼﻣﺎﻌﻤﻠﻟ ﻝﻮﺻﻮﻠﻟ ﺔﻠﺑﺎﻗ ﺮﻴﻏ ﺓﺪﻤﺠﻤﻟﺍ ﺓﺪﺻﺭﻷﺍ ﻞﻈﺗ ﺎﻤﻨﻴﺑ ،ﺎﻬﺑ ﺔﺻﺎﺨﻟﺍ ﺕﻼﻣﺎﻌﻤﻟﺍ ﻝﺎﻤﺘﻛﺍ ﺩﺮﺠﻤﺑ ﺔﺣﺎﺘﻣ ﺔﻠﻔﻘﻤﻟﺍ ﺓﺪﺻﺭﻷﺍ ﺢﺒﺼﺘﺳ .ﻚﺑ ﺔﺻﺎﺨﻟﺍ ﺕﻼﻤﻌﻟﺍ ﻲﻓ ﻢﻜﺤﺘﻟﺍ ﺕﺍﺩﺍﺪﻋﺇ ﻲﻓ ﻂﺸﻧ ﻞﻜﺸﺑ ﺎﻫﺪﻴﻤﺠﺘﺑ ﺖﻤﻗ", "unavailable_balance_description": ".ﺎﻫﺪﻴﻤﺠﺗ ءﺎﻐﻟﺇ ﺭﺮﻘﺗ ﻰﺘﺣ ﺕﻼﻣﺎﻌﻤﻠﻟ ﻝﻮﺻﻮﻠﻟ ﺔﻠﺑﺎﻗ ﺮﻴﻏ ﺓﺪﻤﺠﻤﻟﺍ ﺓﺪﺻﺭﻷﺍ ﻞﻈﺗ ﺎﻤﻨﻴﺑ ،ﺎﻬﺑ ﺔﺻﺎﺨﻟﺍ ﺕﻼﻣﺎﻌﻤﻟﺍ ﻝﺎﻤﺘﻛﺍ ﺩﺮﺠﻤﺑ ﺔﺣﺎﺘﻣ ﺔﻠﻔﻘﻤﻟﺍ ﺓﺪﺻﺭﻷﺍ ﺢﺒﺼﺘﺳ .ﻚﺑ ﺔﺻﺎﺨﻟﺍ ﺕﻼﻤﻌﻟﺍ ﻲﻓ ﻢﻜﺤﺘﻟﺍ ﺕﺍﺩﺍﺪﻋﺇ ﻲﻓ ﻂﺸﻧ ﻞﻜﺸﺑ ﺎﻫﺪﻴﻤﺠﺘﺑ ﺖﻤﻗ",
"unspent_change": "يتغير", "unspent_change": "يتغير",
"Block_remaining": "${status} كتلة متبقية", "Block_remaining": "${status} كتلة متبقية",
"labeled_silent_addresses": "العناوين الصامتة المسمى", "labeled_silent_addresses": "العناوين الصامتة المسمى",
"use_testnet": "استخدم testnet" "use_testnet": "استخدم testnet",
"seed_hex_form": "بذور المحفظة (شكل عرافة)",
"tor_connection": "ﺭﻮﺗ ﻝﺎﺼﺗﺍ",
"seedtype": "البذور",
"seedtype_legacy": "إرث (25 كلمة)",
"seedtype_polyseed": "بوليسيد (16 كلمة)",
"seed_language_czech": "التشيكية",
"seed_language_korean": "الكورية",
"seed_language_chinese_traditional": "تقاليد صينية)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Seed", "seed_title": "Seed",
"seed_share": "Споделяне на seed", "seed_share": "Споделяне на seed",
"copy": "Копиране", "copy": "Копиране",
"seed_language_choose": "Моля, изберете език на seed-а:", "seed_language": "Език на семената",
"seed_choose": "Изберете език на seed-а", "seed_choose": "Изберете език на seed-а",
"seed_language_next": "Следващ", "seed_language_next": "Следващ",
"seed_language_english": "Английски", "seed_language_english": "Английски",
@ -569,7 +569,7 @@
"always": "Винаги", "always": "Винаги",
"minutes_to_pin_code": "${minute} минути", "minutes_to_pin_code": "${minute} минути",
"disable_exchange": "Деактивиране на борса", "disable_exchange": "Деактивиране на борса",
"advanced_privacy_settings": "Допълнителни настройки за поверителност", "advanced_settings": "Разширени настройки",
"settings_can_be_changed_later": "Тези настройки могат да бъдат променени по-късно от приложението", "settings_can_be_changed_later": "Тези настройки могат да бъдат променени по-късно от приложението",
"add_custom_node": "Добавяне на нов персонализиран Node", "add_custom_node": "Добавяне на нов персонализиран Node",
"disable_fiat": "Деактивиране на fiat", "disable_fiat": "Деактивиране на fiat",
@ -723,11 +723,26 @@
"require_for_exchanges_to_external_wallets": "Изискване за обмен към външни портфейли", "require_for_exchanges_to_external_wallets": "Изискване за обмен към външни портфейли",
"camera_permission_is_required": "Изисква се разрешение за камерата.\nМоля, активирайте го от настройките на приложението.", "camera_permission_is_required": "Изисква се разрешение за камерата.\nМоля, активирайте го от настройките на приложението.",
"switchToETHWallet": "Моля, преминете към портфейл Ethereum и опитайте отново", "switchToETHWallet": "Моля, преминете към портфейл Ethereum и опитайте отново",
"importNFTs": "Импортирайте NFT",
"noNFTYet": "Все още няма NFT",
"address": "Адрес",
"enterTokenID": "Въведете идентификатора на токена",
"tokenID": "документ за самоличност",
"name": "Име",
"symbol": "Символ",
"seed_phrase_length": "Дължина на началната фраза", "seed_phrase_length": "Дължина на началната фраза",
"unavailable_balance": "Неналично салдо", "unavailable_balance": "Неналично салдо",
"unavailable_balance_description": "Неналично салдо: Тази обща сума включва средства, които са заключени в чакащи транзакции и тези, които сте замразили активно в настройките за контрол на монетите. Заключените баланси ще станат достъпни, след като съответните им транзакции бъдат завършени, докато замразените баланси остават недостъпни за транзакции, докато не решите да ги размразите.", "unavailable_balance_description": "Неналично салдо: Тази обща сума включва средства, които са заключени в чакащи транзакции и тези, които сте замразили активно в настройките за контрол на монетите. Заключените баланси ще станат достъпни, след като съответните им транзакции бъдат завършени, докато замразените баланси остават недостъпни за транзакции, докато не решите да ги размразите.",
"unspent_change": "Промяна", "unspent_change": "Промяна",
"Block_remaining": "${status} останал блок", "Block_remaining": "${status} останал блок",
"labeled_silent_addresses": "Етикетирани безшумни адреси", "labeled_silent_addresses": "Етикетирани безшумни адреси",
"use_testnet": "Използвайте TestNet" "use_testnet": "Използвайте TestNet",
"tor_connection": "Tor връзка",
"seed_hex_form": "Семена от портфейл (шестнадесетична форма)",
"seedtype": "Семенна тип",
"seedtype_legacy": "Наследство (25 думи)",
"seedtype_polyseed": "Поли семе (16 думи)",
"seed_language_czech": "Чех",
"seed_language_korean": "Корейски",
"seed_language_chinese_traditional": "Традиционен китайски)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Seed", "seed_title": "Seed",
"seed_share": "Sdílet seed", "seed_share": "Sdílet seed",
"copy": "Kopírovat", "copy": "Kopírovat",
"seed_language_choose": "Prosím zvolte si jazyk seedu:", "seed_language": "Jazyk semen",
"seed_choose": "Zvolte si jazyk seedu", "seed_choose": "Zvolte si jazyk seedu",
"seed_language_next": "Další", "seed_language_next": "Další",
"seed_language_english": "Angličtina", "seed_language_english": "Angličtina",
@ -383,7 +383,7 @@
"change_backup_password_alert": "Vaše předchozí soubory se zálohami nebude možné naimportovat s novým heslem. Nové heslo bude použito pouze pro nové zálohy. Opravdu chcete změnit heslo pro zálohy?", "change_backup_password_alert": "Vaše předchozí soubory se zálohami nebude možné naimportovat s novým heslem. Nové heslo bude použito pouze pro nové zálohy. Opravdu chcete změnit heslo pro zálohy?",
"enter_backup_password": "Zde zadejte své heslo pro zálohy", "enter_backup_password": "Zde zadejte své heslo pro zálohy",
"select_backup_file": "Vybrat soubor se zálohou", "select_backup_file": "Vybrat soubor se zálohou",
"import": "Importovat", "import": "Import",
"please_select_backup_file": "Prosím vyberte soubor se zálohou a zadejte heslo pro zálohy.", "please_select_backup_file": "Prosím vyberte soubor se zálohou a zadejte heslo pro zálohy.",
"fixed_rate": "Pevný kurz", "fixed_rate": "Pevný kurz",
"fixed_rate_alert": "Když je zvolený pevný kurz, můžete zadat konkrétní částku, kterou chcete dostat. Chcete se přepnout do režimu s pevným kurzem?", "fixed_rate_alert": "Když je zvolený pevný kurz, můžete zadat konkrétní částku, kterou chcete dostat. Chcete se přepnout do režimu s pevným kurzem?",
@ -569,7 +569,7 @@
"always": "Vždy", "always": "Vždy",
"minutes_to_pin_code": "${minute} minutách", "minutes_to_pin_code": "${minute} minutách",
"disable_exchange": "Zakázat směnárny", "disable_exchange": "Zakázat směnárny",
"advanced_privacy_settings": "Pokročilá nastavení soukromí", "advanced_settings": "Pokročilé nastavení",
"settings_can_be_changed_later": "Tato nastavení mohou být změněna později v nastavení v této aplikaci", "settings_can_be_changed_later": "Tato nastavení mohou být změněna později v nastavení v této aplikaci",
"add_custom_node": "Přidat vlastní uzel", "add_custom_node": "Přidat vlastní uzel",
"disable_fiat": "Zakázat fiat", "disable_fiat": "Zakázat fiat",
@ -723,11 +723,26 @@
"require_for_exchanges_to_external_wallets": "Vyžadovat pro výměny do externích peněženek", "require_for_exchanges_to_external_wallets": "Vyžadovat pro výměny do externích peněženek",
"camera_permission_is_required": "Vyžaduje se povolení fotoaparátu.\nPovolte jej v nastavení aplikace.", "camera_permission_is_required": "Vyžaduje se povolení fotoaparátu.\nPovolte jej v nastavení aplikace.",
"switchToETHWallet": "Přejděte na peněženku Ethereum a zkuste to znovu", "switchToETHWallet": "Přejděte na peněženku Ethereum a zkuste to znovu",
"importNFTs": "Importujte NFT",
"noNFTYet": "Zatím žádné NFT",
"address": "Adresa",
"enterTokenID": "Zadejte ID tokenu",
"tokenID": "ID",
"name": "název",
"symbol": "Symbol",
"seed_phrase_length": "Délka fráze semene", "seed_phrase_length": "Délka fráze semene",
"unavailable_balance": "Nedostupný zůstatek", "unavailable_balance": "Nedostupný zůstatek",
"unavailable_balance_description": "Nedostupný zůstatek: Tento součet zahrnuje prostředky, které jsou uzamčeny v nevyřízených transakcích a ty, které jste aktivně zmrazili v nastavení kontroly mincí. Uzamčené zůstatky budou k dispozici po dokončení příslušných transakcí, zatímco zmrazené zůstatky zůstanou pro transakce nepřístupné, dokud se nerozhodnete je uvolnit.", "unavailable_balance_description": "Nedostupný zůstatek: Tento součet zahrnuje prostředky, které jsou uzamčeny v nevyřízených transakcích a ty, které jste aktivně zmrazili v nastavení kontroly mincí. Uzamčené zůstatky budou k dispozici po dokončení příslušných transakcí, zatímco zmrazené zůstatky zůstanou pro transakce nepřístupné, dokud se nerozhodnete je uvolnit.",
"unspent_change": "Změna", "unspent_change": "Změna",
"Block_remaining": "${status} Blok zbývající", "Block_remaining": "${status} Blok zbývající",
"labeled_silent_addresses": "Označené tiché adresy", "labeled_silent_addresses": "Označené tiché adresy",
"use_testnet": "Použijte testNet" "use_testnet": "Použijte testNet",
"tor_connection": "Připojení Tor",
"seed_hex_form": "Semeno peněženky (hex formulář)",
"seedtype": "SeedType",
"seedtype_legacy": "Legacy (25 slov)",
"seedtype_polyseed": "Polyseed (16 slov)",
"seed_language_czech": "čeština",
"seed_language_korean": "korejština",
"seed_language_chinese_traditional": "Číňan (tradiční)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Seed", "seed_title": "Seed",
"seed_share": "Seed teilen", "seed_share": "Seed teilen",
"copy": "Kopieren", "copy": "Kopieren",
"seed_language_choose": "Bitte wählen Sie die Sprache des Seeds:", "seed_language": "Seed-Sprache",
"seed_choose": "Seed-Sprache auswählen", "seed_choose": "Seed-Sprache auswählen",
"seed_language_next": "Weiter", "seed_language_next": "Weiter",
"seed_language_english": "Englisch", "seed_language_english": "Englisch",
@ -571,7 +571,7 @@
"always": "immer", "always": "immer",
"minutes_to_pin_code": "${minute} Minuten", "minutes_to_pin_code": "${minute} Minuten",
"disable_exchange": "Exchange deaktivieren", "disable_exchange": "Exchange deaktivieren",
"advanced_privacy_settings": "Erweiterte Datenschutzeinstellungen", "advanced_settings": "Erweiterte Einstellungen",
"settings_can_be_changed_later": "Diese Einstellungen können später in den App-Einstellungen geändert werden", "settings_can_be_changed_later": "Diese Einstellungen können später in den App-Einstellungen geändert werden",
"add_custom_node": "Neuen benutzerdefinierten Knoten hinzufügen", "add_custom_node": "Neuen benutzerdefinierten Knoten hinzufügen",
"disable_fiat": "Fiat deaktivieren", "disable_fiat": "Fiat deaktivieren",
@ -722,20 +722,35 @@
"awaitDAppProcessing": "Bitte warten Sie, bis die dApp die Verarbeitung abgeschlossen hat.", "awaitDAppProcessing": "Bitte warten Sie, bis die dApp die Verarbeitung abgeschlossen hat.",
"copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein", "copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein",
"enterWalletConnectURI": "Geben Sie den WalletConnect-URI ein", "enterWalletConnectURI": "Geben Sie den WalletConnect-URI ein",
"seed_key": "Samenschlüssel", "seed_key": "Seed-Schlüssel",
"enter_seed_phrase": "Geben Sie Ihre Samenphrase ein", "enter_seed_phrase": "Geben Sie Ihre Seed-Phrase ein",
"change_rep_successful": "Erfolgreich veränderte Vertreter", "change_rep_successful": "Vertreter erfolgreich gerändert",
"add_contact": "Kontakt hinzufügen", "add_contact": "Kontakt hinzufügen",
"exchange_provider_unsupported": "${providerName} wird nicht mehr unterstützt!", "exchange_provider_unsupported": "${providerName} wird nicht mehr unterstützt!",
"domain_looks_up": "Domain-Suchen", "domain_looks_up": "Domain-Suchen",
"require_for_exchanges_to_external_wallets": "Erforderlich für den Umtausch in externe Wallets", "require_for_exchanges_to_external_wallets": "Erforderlich für den Umtausch in externe Wallets",
"camera_permission_is_required": "Eine Kameraerlaubnis ist erforderlich.\nBitte aktivieren Sie es in den App-Einstellungen.", "camera_permission_is_required": "Eine Kameraerlaubnis ist erforderlich.\nBitte aktivieren Sie es in den App-Einstellungen.",
"switchToETHWallet": "Bitte wechseln Sie zu einem Ethereum-Wallet und versuchen Sie es erneut", "switchToETHWallet": "Bitte wechseln Sie zu einem Ethereum-Wallet und versuchen Sie es erneut",
"importNFTs": "NFTs importieren",
"noNFTYet": "Noch keine NFTs",
"address": "Adresse",
"enterTokenID": "Geben Sie die Token-ID ein",
"tokenID": "AUSWEIS",
"name": "Name",
"symbol": "Symbol",
"seed_phrase_length": "Länge der Seed-Phrase", "seed_phrase_length": "Länge der Seed-Phrase",
"unavailable_balance": "Nicht verfügbares Guthaben", "unavailable_balance": "Nicht verfügbares Guthaben",
"unavailable_balance_description": "Nicht verfügbares Guthaben: Diese Summe umfasst Gelder, die in ausstehenden Transaktionen gesperrt sind, und solche, die Sie in Ihren Münzkontrolleinstellungen aktiv eingefroren haben. Gesperrte Guthaben werden verfügbar, sobald die entsprechenden Transaktionen abgeschlossen sind, während eingefrorene Guthaben für Transaktionen nicht zugänglich bleiben, bis Sie sich dazu entschließen, sie wieder freizugeben.", "unavailable_balance_description": "Nicht verfügbares Guthaben: Diese Summe umfasst Gelder, die in ausstehenden Transaktionen gesperrt sind, und solche, die Sie in Ihren Münzkontrolleinstellungen aktiv eingefroren haben. Gesperrte Guthaben werden verfügbar, sobald die entsprechenden Transaktionen abgeschlossen sind, während eingefrorene Guthaben für Transaktionen nicht zugänglich bleiben, bis Sie sich dazu entschließen, sie wieder freizugeben.",
"unspent_change": "Wechselgeld", "unspent_change": "Wechselgeld",
"Block_remaining": "${status} Block verbleibend", "Block_remaining": "${status} Block verbleibend",
"labeled_silent_addresses": "Bezeichnete stille Adressen", "labeled_silent_addresses": "Bezeichnete stille Adressen",
"use_testnet": "TESTNET verwenden" "use_testnet": "TESTNET verwenden",
"tor_connection": "Tor-Verbindung",
"seed_hex_form": "Brieftaschensamen (Sechskantform)",
"seedtype": "Seedtyp",
"seedtype_legacy": "Veraltet (25 Wörter)",
"seedtype_polyseed": "Polyseed (16 Wörter)",
"seed_language_czech": "Tschechisch",
"seed_language_korean": "Koreanisch",
"seed_language_chinese_traditional": "Chinesisch (Traditionell)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Seed", "seed_title": "Seed",
"seed_share": "Share seed", "seed_share": "Share seed",
"copy": "Copy", "copy": "Copy",
"seed_language_choose": "Please choose seed language:", "seed_language": "Seed language",
"seed_choose": "Choose seed language", "seed_choose": "Choose seed language",
"seed_language_next": "Next", "seed_language_next": "Next",
"seed_language_english": "English", "seed_language_english": "English",
@ -572,7 +572,7 @@
"always": "Always", "always": "Always",
"minutes_to_pin_code": "${minute} minutes", "minutes_to_pin_code": "${minute} minutes",
"disable_exchange": "Disable exchange", "disable_exchange": "Disable exchange",
"advanced_privacy_settings": "Advanced Privacy Settings", "advanced_settings": "Advanced Settings",
"settings_can_be_changed_later": "These settings can be changed later in the app settings", "settings_can_be_changed_later": "These settings can be changed later in the app settings",
"add_custom_node": "Add New Custom Node", "add_custom_node": "Add New Custom Node",
"disable_fiat": "Disable fiat", "disable_fiat": "Disable fiat",
@ -732,11 +732,26 @@
"require_for_exchanges_to_external_wallets": "Require for exchanges to external wallets", "require_for_exchanges_to_external_wallets": "Require for exchanges to external wallets",
"camera_permission_is_required": "Camera permission is required. \nPlease enable it from app settings.", "camera_permission_is_required": "Camera permission is required. \nPlease enable it from app settings.",
"switchToETHWallet": "Please switch to an Ethereum wallet and try again", "switchToETHWallet": "Please switch to an Ethereum wallet and try again",
"importNFTs": "Import NFTs",
"noNFTYet": "No NFTs yet",
"address": "Address",
"enterTokenID": "Enter the token ID",
"tokenID": "ID",
"name": "Name",
"symbol": "Symbol",
"seed_phrase_length": "Seed phrase length", "seed_phrase_length": "Seed phrase length",
"unavailable_balance": "Unavailable balance", "unavailable_balance": "Unavailable balance",
"unavailable_balance_description": "Unavailable Balance: This total includes funds that are locked in pending transactions and those you have actively frozen in your coin control settings. Locked balances will become available once their respective transactions are completed, while frozen balances remain inaccessible for transactions until you decide to unfreeze them.", "unavailable_balance_description": "Unavailable Balance: This total includes funds that are locked in pending transactions and those you have actively frozen in your coin control settings. Locked balances will become available once their respective transactions are completed, while frozen balances remain inaccessible for transactions until you decide to unfreeze them.",
"unspent_change": "Change", "unspent_change": "Change",
"Block_remaining": "${status} Block Remaining", "Block_remaining": "${status} Block Remaining",
"labeled_silent_addresses": "Labeled Silent Addresses", "labeled_silent_addresses": "Labeled Silent Addresses",
"use_testnet": "Use testnet" "use_testnet": "Use testnet",
"tor_connection": "Tor connection",
"seed_hex_form": "Wallet seed (hex form)",
"seedtype": "Seedtype",
"seedtype_legacy": "Legacy (25 words)",
"seedtype_polyseed": "Polyseed (16 words)",
"seed_language_czech": "Czech",
"seed_language_korean": "Korean",
"seed_language_chinese_traditional": "Chinese (Traditional)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Semilla", "seed_title": "Semilla",
"seed_share": "Compartir semillas", "seed_share": "Compartir semillas",
"copy": "Dupdo", "copy": "Dupdo",
"seed_language_choose": "Por favor elija el idioma semilla:", "seed_language": "Lenguaje de semillas",
"seed_choose": "Elige el idioma semilla", "seed_choose": "Elige el idioma semilla",
"seed_language_next": "Próximo", "seed_language_next": "Próximo",
"seed_language_english": "Inglés", "seed_language_english": "Inglés",
@ -571,7 +571,7 @@
"always": "siempre", "always": "siempre",
"minutes_to_pin_code": "${minute} minutos", "minutes_to_pin_code": "${minute} minutos",
"disable_exchange": "Deshabilitar intercambio", "disable_exchange": "Deshabilitar intercambio",
"advanced_privacy_settings": "Configuración avanzada de privacidad", "advanced_settings": "Ajustes avanzados",
"settings_can_be_changed_later": "Estas configuraciones se pueden cambiar más tarde en la configuración de la aplicación", "settings_can_be_changed_later": "Estas configuraciones se pueden cambiar más tarde en la configuración de la aplicación",
"add_custom_node": "Agregar nuevo nodo personalizado", "add_custom_node": "Agregar nuevo nodo personalizado",
"disable_fiat": "Deshabilitar fiat", "disable_fiat": "Deshabilitar fiat",
@ -731,11 +731,26 @@
"require_for_exchanges_to_external_wallets": "Requerido para intercambios a billeteras externas", "require_for_exchanges_to_external_wallets": "Requerido para intercambios a billeteras externas",
"camera_permission_is_required": "Se requiere permiso de la cámara.\nHabilítelo desde la configuración de la aplicación.", "camera_permission_is_required": "Se requiere permiso de la cámara.\nHabilítelo desde la configuración de la aplicación.",
"switchToETHWallet": "Cambie a una billetera Ethereum e inténtelo nuevamente.", "switchToETHWallet": "Cambie a una billetera Ethereum e inténtelo nuevamente.",
"importNFTs": "Importar NFT",
"noNFTYet": "Aún no hay NFT",
"address": "DIRECCIÓN",
"enterTokenID": "Ingrese el ID del token",
"tokenID": "IDENTIFICACIÓN",
"name": "Nombre",
"symbol": "Símbolo",
"seed_phrase_length": "Longitud de la frase inicial", "seed_phrase_length": "Longitud de la frase inicial",
"unavailable_balance": "Saldo no disponible", "unavailable_balance": "Saldo no disponible",
"unavailable_balance_description": "Saldo no disponible: este total incluye fondos que están bloqueados en transacciones pendientes y aquellos que usted ha congelado activamente en su configuración de control de monedas. Los saldos bloqueados estarán disponibles una vez que se completen sus respectivas transacciones, mientras que los saldos congelados permanecerán inaccesibles para las transacciones hasta que usted decida descongelarlos.", "unavailable_balance_description": "Saldo no disponible: este total incluye fondos que están bloqueados en transacciones pendientes y aquellos que usted ha congelado activamente en su configuración de control de monedas. Los saldos bloqueados estarán disponibles una vez que se completen sus respectivas transacciones, mientras que los saldos congelados permanecerán inaccesibles para las transacciones hasta que usted decida descongelarlos.",
"unspent_change": "Cambiar", "unspent_change": "Cambiar",
"Block_remaining": "${status} bloque restante", "Block_remaining": "${status} bloque restante",
"labeled_silent_addresses": "Direcciones silenciosas etiquetadas", "labeled_silent_addresses": "Direcciones silenciosas etiquetadas",
"use_testnet": "Use TestNet" "use_testnet": "Use TestNet",
"tor_connection": "conexión tor",
"seed_hex_form": "Semilla de billetera (forma hexadecimal)",
"seedtype": "Type de semillas",
"seedtype_legacy": "Legado (25 palabras)",
"seedtype_polyseed": "Polieta (16 palabras)",
"seed_language_czech": "checo",
"seed_language_korean": "coreano",
"seed_language_chinese_traditional": "Chino (tradicional)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Phrase secrète (seed)", "seed_title": "Phrase secrète (seed)",
"seed_share": "Partager la phrase secrète (seed)", "seed_share": "Partager la phrase secrète (seed)",
"copy": "Copier", "copy": "Copier",
"seed_language_choose": "Merci de choisir la langue de la phrase secrète (seed) :", "seed_language": "Langage de la phrase secrète",
"seed_choose": "Choisissez la langue de la phrase secrète (seed)", "seed_choose": "Choisissez la langue de la phrase secrète (seed)",
"seed_language_next": "Suivant", "seed_language_next": "Suivant",
"seed_language_english": "Anglais", "seed_language_english": "Anglais",
@ -571,7 +571,7 @@
"always": "toujours", "always": "toujours",
"minutes_to_pin_code": "${minute} minutes", "minutes_to_pin_code": "${minute} minutes",
"disable_exchange": "Désactiver l'échange", "disable_exchange": "Désactiver l'échange",
"advanced_privacy_settings": "Paramètres de confidentialité avancés", "advanced_settings": "Réglages avancés",
"settings_can_be_changed_later": "Ces paramètres peuvent être modifiés ultérieurement dans les paramètres de l'application", "settings_can_be_changed_later": "Ces paramètres peuvent être modifiés ultérieurement dans les paramètres de l'application",
"add_custom_node": "Ajouter un nouveau nœud personnalisé", "add_custom_node": "Ajouter un nouveau nœud personnalisé",
"disable_fiat": "Désactiver les montants en fiat", "disable_fiat": "Désactiver les montants en fiat",
@ -729,6 +729,15 @@
"exchange_provider_unsupported": "${providerName} n'est plus pris en charge !", "exchange_provider_unsupported": "${providerName} n'est plus pris en charge !",
"domain_looks_up": "Résolution de nom", "domain_looks_up": "Résolution de nom",
"require_for_exchanges_to_external_wallets": "Exiger pour les échanges vers des portefeuilles externes", "require_for_exchanges_to_external_wallets": "Exiger pour les échanges vers des portefeuilles externes",
"camera_permission_is_required": "L'autorisation de la caméra est requise.\nVeuillez l'activer à partir des paramètres de l'application.",
"switchToETHWallet": "Veuillez passer à un portefeuille (wallet) Ethereum et réessayer",
"importNFTs": "Importer des NFT",
"noNFTYet": "Pas encore de NFT",
"address": "Adresse",
"enterTokenID": "Entrez l'ID du jeton",
"tokenID": "IDENTIFIANT",
"name": "Nom",
"symbol": "Symbole",
"seed_phrase_length": "Longueur de la phrase de départ", "seed_phrase_length": "Longueur de la phrase de départ",
"unavailable_balance": "Solde indisponible", "unavailable_balance": "Solde indisponible",
"unavailable_balance_description": "Solde indisponible : ce total comprend les fonds bloqués dans les transactions en attente et ceux que vous avez activement gelés dans vos paramètres de contrôle des pièces. Les soldes bloqués deviendront disponibles une fois leurs transactions respectives terminées, tandis que les soldes gelés resteront inaccessibles aux transactions jusqu'à ce que vous décidiez de les débloquer.", "unavailable_balance_description": "Solde indisponible : ce total comprend les fonds bloqués dans les transactions en attente et ceux que vous avez activement gelés dans vos paramètres de contrôle des pièces. Les soldes bloqués deviendront disponibles une fois leurs transactions respectives terminées, tandis que les soldes gelés resteront inaccessibles aux transactions jusqu'à ce que vous décidiez de les débloquer.",
@ -737,5 +746,14 @@
"unspent_change": "Changement", "unspent_change": "Changement",
"Block_remaining": "${status} bloc restant", "Block_remaining": "${status} bloc restant",
"labeled_silent_addresses": "Adresses silencieuses étiquetées", "labeled_silent_addresses": "Adresses silencieuses étiquetées",
"use_testnet": "Utiliser TestNet" "use_testnet": "Utiliser TestNet",
"unspent_change": "Changement",
"tor_connection": "Connexion Tor",
"seed_hex_form": "Graine du portefeuille (forme hexagonale)",
"seedtype": "Type de type graine",
"seedtype_legacy": "Héritage (25 mots)",
"seedtype_polyseed": "Polyseed (16 mots)",
"seed_language_czech": "tchèque",
"seed_language_korean": "coréen",
"seed_language_chinese_traditional": "Chinois (Traditionnel)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "iri", "seed_title": "iri",
"seed_share": "Raba iri", "seed_share": "Raba iri",
"copy": "Kwafi", "copy": "Kwafi",
"seed_language_choose": "Don Allah zaɓi harshen seed:", "seed_language": "Harshen Magani",
"seed_choose": "Zaɓi harshen seed", "seed_choose": "Zaɓi harshen seed",
"seed_language_next": "Na gaba", "seed_language_next": "Na gaba",
"seed_language_english": "Ingilishi", "seed_language_english": "Ingilishi",
@ -570,7 +570,7 @@
"always": "Koyaushe", "always": "Koyaushe",
"minutes_to_pin_code": "${minute} minti", "minutes_to_pin_code": "${minute} minti",
"disable_exchange": "Kashe musanya", "disable_exchange": "Kashe musanya",
"advanced_privacy_settings": "Babban Saitunan Sirri", "advanced_settings": "Saitunan ci gaba",
"settings_can_be_changed_later": "Ana iya canza waɗannan saitunan daga baya a cikin saitunan app", "settings_can_be_changed_later": "Ana iya canza waɗannan saitunan daga baya a cikin saitunan app",
"add_custom_node": "Ƙara Sabon Kulli na Custom", "add_custom_node": "Ƙara Sabon Kulli na Custom",
"disable_fiat": "Dakatar da fiat", "disable_fiat": "Dakatar da fiat",
@ -709,11 +709,26 @@
"require_for_exchanges_to_external_wallets": "Bukatar musanya zuwa wallet na waje", "require_for_exchanges_to_external_wallets": "Bukatar musanya zuwa wallet na waje",
"camera_permission_is_required": "Ana buƙatar izinin kyamara.\nDa fatan za a kunna shi daga saitunan app.", "camera_permission_is_required": "Ana buƙatar izinin kyamara.\nDa fatan za a kunna shi daga saitunan app.",
"switchToETHWallet": "Da fatan za a canza zuwa walat ɗin Ethereum kuma a sake gwadawa", "switchToETHWallet": "Da fatan za a canza zuwa walat ɗin Ethereum kuma a sake gwadawa",
"importNFTs": "Shigo da NFTs",
"noNFTYet": "Babu NFTs tukuna",
"address": "Adireshi",
"enterTokenID": "Shigar da alamar alama",
"tokenID": "ID",
"name": "Suna",
"symbol": "Alama",
"seed_phrase_length": "Tsawon jimlar iri", "seed_phrase_length": "Tsawon jimlar iri",
"unavailable_balance": "Ma'aunin da ba ya samuwa", "unavailable_balance": "Ma'aunin da ba ya samuwa",
"unavailable_balance_description": "Ma'auni Babu: Wannan jimlar ya haɗa da kuɗi waɗanda ke kulle a cikin ma'amaloli da ke jiran aiki da waɗanda kuka daskare sosai a cikin saitunan sarrafa kuɗin ku. Ma'auni da aka kulle za su kasance da zarar an kammala ma'amalolinsu, yayin da daskararrun ma'auni ba za su iya samun damar yin ciniki ba har sai kun yanke shawarar cire su.", "unavailable_balance_description": "Ma'auni Babu: Wannan jimlar ya haɗa da kuɗi waɗanda ke kulle a cikin ma'amaloli da ke jiran aiki da waɗanda kuka daskare sosai a cikin saitunan sarrafa kuɗin ku. Ma'auni da aka kulle za su kasance da zarar an kammala ma'amalolinsu, yayin da daskararrun ma'auni ba za su iya samun damar yin ciniki ba har sai kun yanke shawarar cire su.",
"unspent_change": "Canza", "unspent_change": "Canza",
"Block_remaining": "${status} toshe ragowar", "Block_remaining": "${status} toshe ragowar",
"labeled_silent_addresses": "Mai labarar adireshin shiru", "labeled_silent_addresses": "Mai labarar adireshin shiru",
"use_testnet": "Amfani da gwaji" "use_testnet": "Amfani da gwaji",
"tor_connection": "Tor haɗin gwiwa",
"seed_hex_form": "Gany Sero (form form)",
"seedtype": "Seedtype",
"seedtype_legacy": "Legacy (25 kalmomi)",
"seedtype_polyseed": "Polyseed (16 kalmomi)",
"seed_language_czech": "Czech",
"seed_language_korean": "Yaren Koriya",
"seed_language_chinese_traditional": "Sinanci (na gargajiya)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "बीज", "seed_title": "बीज",
"seed_share": "बीज साझा करें", "seed_share": "बीज साझा करें",
"copy": "प्रतिलिपि", "copy": "प्रतिलिपि",
"seed_language_choose": "कृपया बीज भाषा चुनें:", "seed_language": "बीज",
"seed_choose": "बीज भाषा चुनें", "seed_choose": "बीज भाषा चुनें",
"seed_language_next": "आगामी", "seed_language_next": "आगामी",
"seed_language_english": "अंग्रेज़ी", "seed_language_english": "अंग्रेज़ी",
@ -571,7 +571,7 @@
"always": "हमेशा", "always": "हमेशा",
"minutes_to_pin_code": "${minute} मिनट", "minutes_to_pin_code": "${minute} मिनट",
"disable_exchange": "एक्सचेंज अक्षम करें", "disable_exchange": "एक्सचेंज अक्षम करें",
"advanced_privacy_settings": "उन्नत गोपनीयता सेटिंग्स", "advanced_settings": "एडवांस सेटिंग",
"settings_can_be_changed_later": "इन सेटिंग्स को बाद में ऐप सेटिंग में बदला जा सकता है", "settings_can_be_changed_later": "इन सेटिंग्स को बाद में ऐप सेटिंग में बदला जा सकता है",
"add_custom_node": "नया कस्टम नोड जोड़ें", "add_custom_node": "नया कस्टम नोड जोड़ें",
"disable_fiat": "िएट को अक्षम करें", "disable_fiat": "िएट को अक्षम करें",
@ -731,11 +731,26 @@
"require_for_exchanges_to_external_wallets": "बाहरी वॉलेट में एक्सचेंज की आवश्यकता है", "require_for_exchanges_to_external_wallets": "बाहरी वॉलेट में एक्सचेंज की आवश्यकता है",
"camera_permission_is_required": "कैमरे की अनुमति आवश्यक है.\nकृपया इसे ऐप सेटिंग से सक्षम करें।", "camera_permission_is_required": "कैमरे की अनुमति आवश्यक है.\nकृपया इसे ऐप सेटिंग से सक्षम करें।",
"switchToETHWallet": "कृपया एथेरियम वॉलेट पर स्विच करें और पुनः प्रयास करें", "switchToETHWallet": "कृपया एथेरियम वॉलेट पर स्विच करें और पुनः प्रयास करें",
"importNFTs": "एनएफटी आयात करें",
"noNFTYet": "अभी तक कोई एनएफटी नहीं",
"address": "पता",
"enterTokenID": "टोकन आईडी दर्ज करें",
"tokenID": "पहचान",
"name": "नाम",
"symbol": "प्रतीक",
"seed_phrase_length": "बीज वाक्यांश की लंबाई", "seed_phrase_length": "बीज वाक्यांश की लंबाई",
"unavailable_balance": "अनुपलब्ध शेष", "unavailable_balance": "अनुपलब्ध शेष",
"unavailable_balance_description": "अनुपलब्ध शेष राशि: इस कुल में वे धनराशि शामिल हैं जो लंबित लेनदेन में बंद हैं और जिन्हें आपने अपनी सिक्का नियंत्रण सेटिंग्स में सक्रिय रूप से जमा कर रखा है। लॉक किए गए शेष उनके संबंधित लेन-देन पूरे होने के बाद उपलब्ध हो जाएंगे, जबकि जमे हुए शेष लेन-देन के लिए अप्राप्य रहेंगे जब तक कि आप उन्हें अनफ्रीज करने का निर्णय नहीं लेते।", "unavailable_balance_description": "अनुपलब्ध शेष राशि: इस कुल में वे धनराशि शामिल हैं जो लंबित लेनदेन में बंद हैं और जिन्हें आपने अपनी सिक्का नियंत्रण सेटिंग्स में सक्रिय रूप से जमा कर रखा है। लॉक किए गए शेष उनके संबंधित लेन-देन पूरे होने के बाद उपलब्ध हो जाएंगे, जबकि जमे हुए शेष लेन-देन के लिए अप्राप्य रहेंगे जब तक कि आप उन्हें अनफ्रीज करने का निर्णय नहीं लेते।",
"unspent_change": "परिवर्तन", "unspent_change": "परिवर्तन",
"Block_remaining": "${status} शेष ब्लॉक", "Block_remaining": "${status} शेष ब्लॉक",
"labeled_silent_addresses": "मूक पते लेबल", "labeled_silent_addresses": "मूक पते लेबल",
"use_testnet": "टेस्टनेट का उपयोग करें" "use_testnet": "टेस्टनेट का उपयोग करें",
"tor_connection": "टोर कनेक्शन",
"seed_hex_form": "वॉलेट सीड (हेक्स फॉर्म)",
"seedtype": "बीज",
"seedtype_legacy": "विरासत (25 शब्द)",
"seedtype_polyseed": "पॉलीसीड (16 शब्द)",
"seed_language_czech": "चेक",
"seed_language_korean": "कोरियाई",
"seed_language_chinese_traditional": "चीनी पारंपरिक)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Prisupni izraz", "seed_title": "Prisupni izraz",
"seed_share": "Podijeli pristupni izraz", "seed_share": "Podijeli pristupni izraz",
"copy": "Kopiraj", "copy": "Kopiraj",
"seed_language_choose": "Molimo odaberite jezik pristupnog izraza:", "seed_language": "Sjemeni jezik",
"seed_choose": "Odaberi jezik pristupnog izraza", "seed_choose": "Odaberi jezik pristupnog izraza",
"seed_language_next": "Dalje", "seed_language_next": "Dalje",
"seed_language_english": "Engleski", "seed_language_english": "Engleski",
@ -383,7 +383,7 @@
"change_backup_password_alert": "Nećemo moći uvesti Vaše prethodne datoteke sigurnosne kopije s novom lozinkom za sigurnosnu kopiju. Novu lozinku za sigurnosnu kopiju moći ćete koristiti samo za nove datoteke sigurnosne kopije. Jeste li sigurni da želite promijeniti lozinku za sigurnosnu kopiju?", "change_backup_password_alert": "Nećemo moći uvesti Vaše prethodne datoteke sigurnosne kopije s novom lozinkom za sigurnosnu kopiju. Novu lozinku za sigurnosnu kopiju moći ćete koristiti samo za nove datoteke sigurnosne kopije. Jeste li sigurni da želite promijeniti lozinku za sigurnosnu kopiju?",
"enter_backup_password": "Unesite svoju lozinku za sigurnosnu kopiju ovdje", "enter_backup_password": "Unesite svoju lozinku za sigurnosnu kopiju ovdje",
"select_backup_file": "Odaberite datoteku sigurnosne kopije", "select_backup_file": "Odaberite datoteku sigurnosne kopije",
"import": "Uvezi", "import": "Uvoz",
"please_select_backup_file": "Molimo odaberite datoteku sigurnosne kopije i unesite lozinku za sigurnosnu kopiju.", "please_select_backup_file": "Molimo odaberite datoteku sigurnosne kopije i unesite lozinku za sigurnosnu kopiju.",
"fixed_rate": "Fiksna stopa", "fixed_rate": "Fiksna stopa",
"fixed_rate_alert": "Moći ćete unijeti iznos koji želite primiti nakon što označite način rada fiksne stope. Želite li se prebaciti na način rada fiksne stope?", "fixed_rate_alert": "Moći ćete unijeti iznos koji želite primiti nakon što označite način rada fiksne stope. Želite li se prebaciti na način rada fiksne stope?",
@ -571,7 +571,7 @@
"always": "Uvijek", "always": "Uvijek",
"minutes_to_pin_code": "${minute} minuta", "minutes_to_pin_code": "${minute} minuta",
"disable_exchange": "Onemogući exchange", "disable_exchange": "Onemogući exchange",
"advanced_privacy_settings": "Napredne postavke privatnosti", "advanced_settings": "Napredne postavke",
"settings_can_be_changed_later": "Te se postavke mogu promijeniti kasnije u postavkama aplikacije", "settings_can_be_changed_later": "Te se postavke mogu promijeniti kasnije u postavkama aplikacije",
"add_custom_node": "Dodaj novi prilagođeni čvor", "add_custom_node": "Dodaj novi prilagođeni čvor",
"disable_fiat": "Isključi, fiat", "disable_fiat": "Isključi, fiat",
@ -729,11 +729,26 @@
"require_for_exchanges_to_external_wallets": "Zahtijeva razmjene na vanjske novčanike", "require_for_exchanges_to_external_wallets": "Zahtijeva razmjene na vanjske novčanike",
"camera_permission_is_required": "Potrebno je dopuštenje kamere.\nOmogućite ga u postavkama aplikacije.", "camera_permission_is_required": "Potrebno je dopuštenje kamere.\nOmogućite ga u postavkama aplikacije.",
"switchToETHWallet": "Prijeđite na Ethereum novčanik i pokušajte ponovno", "switchToETHWallet": "Prijeđite na Ethereum novčanik i pokušajte ponovno",
"importNFTs": "Uvoz NFT-ova",
"noNFTYet": "Još nema NFT-ova",
"address": "Adresa",
"enterTokenID": "Unesite ID tokena",
"tokenID": "iskaznica",
"name": "Ime",
"symbol": "Simbol",
"seed_phrase_length": "Duljina početne fraze", "seed_phrase_length": "Duljina početne fraze",
"unavailable_balance": "Nedostupno stanje", "unavailable_balance": "Nedostupno stanje",
"unavailable_balance_description": "Nedostupno stanje: Ovaj ukupni iznos uključuje sredstva koja su zaključana u transakcijama na čekanju i ona koja ste aktivno zamrznuli u postavkama kontrole novčića. Zaključani saldi postat će dostupni kada se dovrše njihove transakcije, dok zamrznuti saldi ostaju nedostupni za transakcije sve dok ih ne odlučite odmrznuti.", "unavailable_balance_description": "Nedostupno stanje: Ovaj ukupni iznos uključuje sredstva koja su zaključana u transakcijama na čekanju i ona koja ste aktivno zamrznuli u postavkama kontrole novčića. Zaključani saldi postat će dostupni kada se dovrše njihove transakcije, dok zamrznuti saldi ostaju nedostupni za transakcije sve dok ih ne odlučite odmrznuti.",
"unspent_change": "Promijeniti", "unspent_change": "Promijeniti",
"Block_remaining": "${status} ostao blok", "Block_remaining": "${status} ostao blok",
"labeled_silent_addresses": "Označene tihe adrese", "labeled_silent_addresses": "Označene tihe adrese",
"use_testnet": "Koristite TestNet" "use_testnet": "Koristite TestNet",
"tor_connection": "Tor veza",
"seed_hex_form": "Sjeme novčanika (šesterokutni oblik)",
"seedtype": "Sjemenska vrsta",
"seedtype_legacy": "Nasljeđe (25 riječi)",
"seedtype_polyseed": "Poliseed (16 riječi)",
"seed_language_czech": "češki",
"seed_language_korean": "korejski",
"seed_language_chinese_traditional": "Kinesko (tradicionalno)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Bibit", "seed_title": "Bibit",
"seed_share": "Bagikan bibit", "seed_share": "Bagikan bibit",
"copy": "Salin", "copy": "Salin",
"seed_language_choose": "Silakan pilih bahasa bibit:", "seed_language": "Bahasa benih",
"seed_choose": "Pilih bahasa bibit", "seed_choose": "Pilih bahasa bibit",
"seed_language_next": "Selanjutnya", "seed_language_next": "Selanjutnya",
"seed_language_english": "Inggris", "seed_language_english": "Inggris",
@ -570,7 +570,7 @@
"always": "Selalu", "always": "Selalu",
"minutes_to_pin_code": "${minute} menit", "minutes_to_pin_code": "${minute} menit",
"disable_exchange": "Nonaktifkan pertukaran", "disable_exchange": "Nonaktifkan pertukaran",
"advanced_privacy_settings": "Pengaturan Privasi Lanjutan", "advanced_settings": "Pengaturan lanjutan",
"settings_can_be_changed_later": "Pengaturan ini dapat diubah nanti di pengaturan aplikasi", "settings_can_be_changed_later": "Pengaturan ini dapat diubah nanti di pengaturan aplikasi",
"add_custom_node": "Tambahkan Node Kustom Baru", "add_custom_node": "Tambahkan Node Kustom Baru",
"disable_fiat": "Nonaktifkan fiat", "disable_fiat": "Nonaktifkan fiat",
@ -719,11 +719,26 @@
"require_for_exchanges_to_external_wallets": "Memerlukan pertukaran ke dompet eksternal", "require_for_exchanges_to_external_wallets": "Memerlukan pertukaran ke dompet eksternal",
"camera_permission_is_required": "Izin kamera diperlukan.\nSilakan aktifkan dari pengaturan aplikasi.", "camera_permission_is_required": "Izin kamera diperlukan.\nSilakan aktifkan dari pengaturan aplikasi.",
"switchToETHWallet": "Silakan beralih ke dompet Ethereum dan coba lagi", "switchToETHWallet": "Silakan beralih ke dompet Ethereum dan coba lagi",
"importNFTs": "Impor NFT",
"noNFTYet": "Belum ada NFT",
"address": "Alamat",
"enterTokenID": "Masukkan ID tokennya",
"tokenID": "PENGENAL",
"name": "Nama",
"symbol": "Simbol",
"seed_phrase_length": "Panjang frase benih", "seed_phrase_length": "Panjang frase benih",
"unavailable_balance": "Saldo tidak tersedia", "unavailable_balance": "Saldo tidak tersedia",
"unavailable_balance_description": "Saldo Tidak Tersedia: Total ini termasuk dana yang terkunci dalam transaksi yang tertunda dan dana yang telah Anda bekukan secara aktif di pengaturan kontrol koin Anda. Saldo yang terkunci akan tersedia setelah transaksi masing-masing selesai, sedangkan saldo yang dibekukan tetap tidak dapat diakses untuk transaksi sampai Anda memutuskan untuk mencairkannya.", "unavailable_balance_description": "Saldo Tidak Tersedia: Total ini termasuk dana yang terkunci dalam transaksi yang tertunda dan dana yang telah Anda bekukan secara aktif di pengaturan kontrol koin Anda. Saldo yang terkunci akan tersedia setelah transaksi masing-masing selesai, sedangkan saldo yang dibekukan tetap tidak dapat diakses untuk transaksi sampai Anda memutuskan untuk mencairkannya.",
"unspent_change": "Mengubah", "unspent_change": "Mengubah",
"Block_remaining": "${status} blok tersisa", "Block_remaining": "${status} blok tersisa",
"labeled_silent_addresses": "Label alamat diam", "labeled_silent_addresses": "Label alamat diam",
"use_testnet": "Gunakan TestNet" "use_testnet": "Gunakan TestNet",
"tor_connection": "koneksi Tor",
"seed_hex_form": "Biji dompet (bentuk hex)",
"seedtype": "Seedtype",
"seedtype_legacy": "Legacy (25 kata)",
"seedtype_polyseed": "Polyseed (16 kata)",
"seed_language_czech": "Ceko",
"seed_language_korean": "Korea",
"seed_language_chinese_traditional": "Cina (tradisional)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "Seme", "seed_title": "Seme",
"seed_share": "Condividi seme", "seed_share": "Condividi seme",
"copy": "Copia", "copy": "Copia",
"seed_language_choose": "Gentilmente scegli la lingua del seme:", "seed_language": "Linguaggio di semi",
"seed_choose": "Scegli la lingua del seme", "seed_choose": "Scegli la lingua del seme",
"seed_language_next": "Prossimo", "seed_language_next": "Prossimo",
"seed_language_english": "Inglese", "seed_language_english": "Inglese",
@ -383,7 +383,7 @@
"change_backup_password_alert": "I precedenti file di backup non potranno essere importati con la nuova password di backup. La nuova password di backup verrà usata soltanto per i nuovi file di backup. Sei sicuro di voler cambiare la tua password di backup?", "change_backup_password_alert": "I precedenti file di backup non potranno essere importati con la nuova password di backup. La nuova password di backup verrà usata soltanto per i nuovi file di backup. Sei sicuro di voler cambiare la tua password di backup?",
"enter_backup_password": "Inserisci la password di backup qui", "enter_backup_password": "Inserisci la password di backup qui",
"select_backup_file": "Seleziona file di backup", "select_backup_file": "Seleziona file di backup",
"import": "Importa", "import": "Importare",
"please_select_backup_file": "Gentilmente seleziona il file di backup e inserisci la password di backup.", "please_select_backup_file": "Gentilmente seleziona il file di backup e inserisci la password di backup.",
"fixed_rate": "Tasso fisso", "fixed_rate": "Tasso fisso",
"fixed_rate_alert": "Potrai inserire l'ammontare da ricevere quando il tasso è fisso. Vuoi cambiare alla modalità tasso fisso?", "fixed_rate_alert": "Potrai inserire l'ammontare da ricevere quando il tasso è fisso. Vuoi cambiare alla modalità tasso fisso?",
@ -571,7 +571,7 @@
"always": "sempre", "always": "sempre",
"minutes_to_pin_code": "${minute} minuti", "minutes_to_pin_code": "${minute} minuti",
"disable_exchange": "Disabilita scambio", "disable_exchange": "Disabilita scambio",
"advanced_privacy_settings": "Impostazioni avanzate sulla privacy", "advanced_settings": "Impostazioni avanzate",
"settings_can_be_changed_later": "Queste impostazioni possono essere modificate in seguito nelle impostazioni dell'app", "settings_can_be_changed_later": "Queste impostazioni possono essere modificate in seguito nelle impostazioni dell'app",
"add_custom_node": "Aggiungi nuovo nodo personalizzato", "add_custom_node": "Aggiungi nuovo nodo personalizzato",
"disable_fiat": "Disabilita fiat", "disable_fiat": "Disabilita fiat",
@ -731,11 +731,26 @@
"require_for_exchanges_to_external_wallets": "Richiede scambi con portafogli esterni", "require_for_exchanges_to_external_wallets": "Richiede scambi con portafogli esterni",
"camera_permission_is_required": "È richiesta l'autorizzazione della fotocamera.\nAbilitalo dalle impostazioni dell'app.", "camera_permission_is_required": "È richiesta l'autorizzazione della fotocamera.\nAbilitalo dalle impostazioni dell'app.",
"switchToETHWallet": "Passa a un portafoglio Ethereum e riprova", "switchToETHWallet": "Passa a un portafoglio Ethereum e riprova",
"importNFTs": "Importa NFT",
"noNFTYet": "Nessun NFT ancora",
"address": "Indirizzo",
"enterTokenID": "Inserisci l'ID del token",
"tokenID": "ID",
"name": "Nome",
"symbol": "Simbolo",
"seed_phrase_length": "Lunghezza della frase seed", "seed_phrase_length": "Lunghezza della frase seed",
"unavailable_balance": "Saldo non disponibile", "unavailable_balance": "Saldo non disponibile",
"unavailable_balance_description": "Saldo non disponibile: questo totale include i fondi bloccati nelle transazioni in sospeso e quelli che hai congelato attivamente nelle impostazioni di controllo delle monete. I saldi bloccati diventeranno disponibili una volta completate le rispettive transazioni, mentre i saldi congelati rimarranno inaccessibili per le transazioni finché non deciderai di sbloccarli.", "unavailable_balance_description": "Saldo non disponibile: questo totale include i fondi bloccati nelle transazioni in sospeso e quelli che hai congelato attivamente nelle impostazioni di controllo delle monete. I saldi bloccati diventeranno disponibili una volta completate le rispettive transazioni, mentre i saldi congelati rimarranno inaccessibili per le transazioni finché non deciderai di sbloccarli.",
"unspent_change": "Modifica", "unspent_change": "Modifica",
"Block_remaining": "${status} blocco rimanente", "Block_remaining": "${status} blocco rimanente",
"labeled_silent_addresses": "Indirizzi silenziosi etichettati", "labeled_silent_addresses": "Indirizzi silenziosi etichettati",
"use_testnet": "Usa TestNet" "use_testnet": "Usa TestNet",
"tor_connection": "Connessione Tor",
"seed_hex_form": "Seme di portafoglio (forma esadecimale)",
"seedtype": "Seedtype",
"seedtype_legacy": "Legacy (25 parole)",
"seedtype_polyseed": "Polyseed (16 parole)",
"seed_language_czech": "ceco",
"seed_language_korean": "coreano",
"seed_language_chinese_traditional": "Cinese tradizionale)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "シード", "seed_title": "シード",
"seed_share": "シードを共有する", "seed_share": "シードを共有する",
"copy": "コピー", "copy": "コピー",
"seed_language_choose": "シード言語を選択してください:", "seed_language": "シード言語",
"seed_choose": "シード言語を選択してください", "seed_choose": "シード言語を選択してください",
"seed_language_next": "次", "seed_language_next": "次",
"seed_language_english": "英語", "seed_language_english": "英語",
@ -383,7 +383,7 @@
"change_backup_password_alert": "以前のバックアップファイルは、新しいバックアップパスワードでインポートできなくなります。 新しいバックアップパスワードは、新しいバックアップファイルにのみ使用されます。 バックアップパスワードを変更してもよろしいですか?", "change_backup_password_alert": "以前のバックアップファイルは、新しいバックアップパスワードでインポートできなくなります。 新しいバックアップパスワードは、新しいバックアップファイルにのみ使用されます。 バックアップパスワードを変更してもよろしいですか?",
"enter_backup_password": "ここにバックアップパスワードを入力してください", "enter_backup_password": "ここにバックアップパスワードを入力してください",
"select_backup_file": "バックアップファイルを選択", "select_backup_file": "バックアップファイルを選択",
"import": "インポート", "import": "輸入",
"please_select_backup_file": "バックアップファイルを選択し、バックアップパスワードを入力してください。", "please_select_backup_file": "バックアップファイルを選択し、バックアップパスワードを入力してください。",
"fixed_rate": "固定金利", "fixed_rate": "固定金利",
"fixed_rate_alert": "固定金利モードにチェックを入れると、受取額を入力できるようになります。 固定金利モードに切り替えますか?", "fixed_rate_alert": "固定金利モードにチェックを入れると、受取額を入力できるようになります。 固定金利モードに切り替えますか?",
@ -571,7 +571,7 @@
"always": "いつも", "always": "いつも",
"minutes_to_pin_code": "${minute} 分", "minutes_to_pin_code": "${minute} 分",
"disable_exchange": "交換を無効にする", "disable_exchange": "交換を無効にする",
"advanced_privacy_settings": "高度なプライバシー設定", "advanced_settings": "高度な設定",
"settings_can_be_changed_later": "これらの設定は、後でアプリの設定で変更できます", "settings_can_be_changed_later": "これらの設定は、後でアプリの設定で変更できます",
"add_custom_node": "新しいカスタム ノードを追加", "add_custom_node": "新しいカスタム ノードを追加",
"disable_fiat": "フィアットを無効にする", "disable_fiat": "フィアットを無効にする",
@ -731,11 +731,26 @@
"require_for_exchanges_to_external_wallets": "外部ウォレットへの交換に必要", "require_for_exchanges_to_external_wallets": "外部ウォレットへの交換に必要",
"camera_permission_is_required": "カメラの許可が必要です。\nアプリの設定から有効にしてください。", "camera_permission_is_required": "カメラの許可が必要です。\nアプリの設定から有効にしてください。",
"switchToETHWallet": "イーサリアムウォレットに切り替えてもう一度お試しください", "switchToETHWallet": "イーサリアムウォレットに切り替えてもう一度お試しください",
"importNFTs": "NFTのインポート",
"noNFTYet": "NFTはまだありません",
"address": "住所",
"enterTokenID": "トークンIDを入力してください",
"tokenID": "ID",
"name": "名前",
"symbol": "シンボル",
"seed_phrase_length": "シードフレーズの長さ", "seed_phrase_length": "シードフレーズの長さ",
"unavailable_balance": "利用できない残高", "unavailable_balance": "利用できない残高",
"unavailable_balance_description": "利用不可能な残高: この合計には、保留中のトランザクションにロックされている資金と、コイン管理設定でアクティブに凍結した資金が含まれます。ロックされた残高は、それぞれの取引が完了すると利用可能になりますが、凍結された残高は、凍結を解除するまで取引にアクセスできません。", "unavailable_balance_description": "利用不可能な残高: この合計には、保留中のトランザクションにロックされている資金と、コイン管理設定でアクティブに凍結した資金が含まれます。ロックされた残高は、それぞれの取引が完了すると利用可能になりますが、凍結された残高は、凍結を解除するまで取引にアクセスできません。",
"unspent_change": "変化", "unspent_change": "変化",
"Block_remaining": "${status}ブロックの残り", "Block_remaining": "${status}ブロックの残り",
"labeled_silent_addresses": "サイレントアドレスとラベル付けされています", "labeled_silent_addresses": "サイレントアドレスとラベル付けされています",
"use_testnet": "TestNetを使用します" "use_testnet": "TestNetを使用します",
"tor_connection": "Tor接続",
"seed_hex_form": "ウォレットシード(ヘックスフォーム)",
"seedtype": "SeedType",
"seedtype_legacy": "レガシー25語",
"seedtype_polyseed": "ポリシード16語",
"seed_language_czech": "チェコ",
"seed_language_korean": "韓国語",
"seed_language_chinese_traditional": "中国の伝統的な)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "씨", "seed_title": "씨",
"seed_share": "시드 공유", "seed_share": "시드 공유",
"copy": "부", "copy": "부",
"seed_language_choose": "종자 언어를 선택하십시오:", "seed_language": "종자 언어",
"seed_choose": "시드 언어를 선택하십시오", "seed_choose": "시드 언어를 선택하십시오",
"seed_language_next": "다음 것", "seed_language_next": "다음 것",
"seed_language_english": "영어", "seed_language_english": "영어",
@ -571,7 +571,7 @@
"always": "언제나", "always": "언제나",
"minutes_to_pin_code": "${minute}분", "minutes_to_pin_code": "${minute}분",
"disable_exchange": "교환 비활성화", "disable_exchange": "교환 비활성화",
"advanced_privacy_settings": "고급 개인 정보 설정", "advanced_settings": "고급 설정",
"settings_can_be_changed_later": "이 설정은 나중에 앱 설정에서 변경할 수 있습니다.", "settings_can_be_changed_later": "이 설정은 나중에 앱 설정에서 변경할 수 있습니다.",
"add_custom_node": "새 사용자 정의 노드 추가", "add_custom_node": "새 사용자 정의 노드 추가",
"disable_fiat": "법정화폐 비활성화", "disable_fiat": "법정화폐 비활성화",
@ -729,11 +729,26 @@
"require_for_exchanges_to_external_wallets": "외부 지갑으로의 교환을 위해 필요", "require_for_exchanges_to_external_wallets": "외부 지갑으로의 교환을 위해 필요",
"camera_permission_is_required": "카메라 권한이 필요합니다.\n앱 설정에서 활성화해 주세요.", "camera_permission_is_required": "카메라 권한이 필요합니다.\n앱 설정에서 활성화해 주세요.",
"switchToETHWallet": "이더리움 지갑으로 전환한 후 다시 시도해 주세요.", "switchToETHWallet": "이더리움 지갑으로 전환한 후 다시 시도해 주세요.",
"importNFTs": "NFT 가져오기",
"noNFTYet": "아직 NFT가 없습니다",
"address": "주소",
"enterTokenID": "토큰 ID를 입력하세요",
"tokenID": "ID",
"name": "이름",
"symbol": "상징",
"seed_phrase_length": "시드 문구 길이", "seed_phrase_length": "시드 문구 길이",
"unavailable_balance": "사용할 수 없는 잔액", "unavailable_balance": "사용할 수 없는 잔액",
"unavailable_balance_description": "사용할 수 없는 잔액: 이 총계에는 보류 중인 거래에 잠겨 있는 자금과 코인 관리 설정에서 적극적으로 동결된 자금이 포함됩니다. 잠긴 잔액은 해당 거래가 완료되면 사용할 수 있게 되며, 동결된 잔액은 동결을 해제하기 전까지 거래에 액세스할 수 없습니다.", "unavailable_balance_description": "사용할 수 없는 잔액: 이 총계에는 보류 중인 거래에 잠겨 있는 자금과 코인 관리 설정에서 적극적으로 동결된 자금이 포함됩니다. 잠긴 잔액은 해당 거래가 완료되면 사용할 수 있게 되며, 동결된 잔액은 동결을 해제하기 전까지 거래에 액세스할 수 없습니다.",
"unspent_change": "변화", "unspent_change": "변화",
"Block_remaining": "${status} 나머지 블록", "Block_remaining": "${status} 나머지 블록",
"labeled_silent_addresses": "라벨링 된 무음 주소", "labeled_silent_addresses": "라벨링 된 무음 주소",
"use_testnet": "TestNet을 사용하십시오" "use_testnet": "TestNet을 사용하십시오",
"tor_connection": "토르 연결",
"seed_hex_form": "지갑 씨앗 (16 진 양식)",
"seedtype": "시드 타입",
"seedtype_legacy": "레거시 (25 단어)",
"seedtype_polyseed": "다문 (16 단어)",
"seed_language_czech": "체코 사람",
"seed_language_korean": "한국인",
"seed_language_chinese_traditional": "중국 전통)"
} }

View file

@ -160,7 +160,7 @@
"seed_title": "မျိုးစေ့", "seed_title": "မျိုးစေ့",
"seed_share": "မျိုးစေ့မျှဝေပါ။", "seed_share": "မျိုးစေ့မျှဝေပါ။",
"copy": "ကော်ပီ", "copy": "ကော်ပီ",
"seed_language_choose": "ကျေးဇူးပြု၍ မျိုးစေ့ဘာသာစကားကို ရွေးပါ-", "seed_language": "မျိုးစေ့ဘာသာ",
"seed_choose": "မျိုးစေ့ဘာသာစကားကို ရွေးချယ်ပါ။", "seed_choose": "မျိုးစေ့ဘာသာစကားကို ရွေးချယ်ပါ။",
"seed_language_next": "နောက်တစ်ခု", "seed_language_next": "နောက်တစ်ခု",
"seed_language_english": "အင်္ဂလိပ်စာ", "seed_language_english": "အင်္ဂလိပ်စာ",
@ -569,7 +569,7 @@
"always": "အမြဲတမ်း", "always": "အမြဲတမ်း",
"minutes_to_pin_code": "${minute} မိနစ်", "minutes_to_pin_code": "${minute} မိနစ်",
"disable_exchange": "လဲလှယ်မှုကို ပိတ်ပါ။", "disable_exchange": "လဲလှယ်မှုကို ပိတ်ပါ။",
"advanced_privacy_settings": "အဆင့်မြင့် ကိုယ်ရေးကိုယ်တာ ဆက်တင်များ", "advanced_settings": "အဆင့်မြင့်ချိန်ညှိချက်များ",
"settings_can_be_changed_later": "အက်ပ်ဆက်တင်များတွင် ဤဆက်တင်များကို နောက်ပိုင်းတွင် ပြောင်းလဲနိုင်သည်။", "settings_can_be_changed_later": "အက်ပ်ဆက်တင်များတွင် ဤဆက်တင်များကို နောက်ပိုင်းတွင် ပြောင်းလဲနိုင်သည်။",
"add_custom_node": "စိတ်ကြိုက် Node အသစ်ကို ထည့်ပါ။", "add_custom_node": "စိတ်ကြိုက် Node အသစ်ကို ထည့်ပါ။",
"disable_fiat": "Fiat ကိုပိတ်ပါ။", "disable_fiat": "Fiat ကိုပိတ်ပါ။",
@ -729,11 +729,26 @@
"require_for_exchanges_to_external_wallets": "ပြင်ပပိုက်ဆံအိတ်များသို့ လဲလှယ်ရန် လိုအပ်သည်။", "require_for_exchanges_to_external_wallets": "ပြင်ပပိုက်ဆံအိတ်များသို့ လဲလှယ်ရန် လိုအပ်သည်။",
"camera_permission_is_required": "ကင်မရာခွင့်ပြုချက် လိုအပ်ပါသည်။\nအက်ပ်ဆက်တင်များမှ ၎င်းကိုဖွင့်ပါ။", "camera_permission_is_required": "ကင်မရာခွင့်ပြုချက် လိုအပ်ပါသည်။\nအက်ပ်ဆက်တင်များမှ ၎င်းကိုဖွင့်ပါ။",
"switchToETHWallet": "ကျေးဇူးပြု၍ Ethereum ပိုက်ဆံအိတ်သို့ ပြောင်းပြီး ထပ်စမ်းကြည့်ပါ။", "switchToETHWallet": "ကျေးဇူးပြု၍ Ethereum ပိုက်ဆံအိတ်သို့ ပြောင်းပြီး ထပ်စမ်းကြည့်ပါ။",
"importNFTs": "NFTs များကို တင်သွင်းပါ။",
"noNFTYet": "NFTs မရှိသေးပါ။",
"address": "လိပ်စာ",
"enterTokenID": "တိုကင် ID ကိုထည့်ပါ။",
"tokenID": "အမှတ်သညာ",
"name": "နာမည်",
"symbol": "သင်္ကေတ",
"seed_phrase_length": "မျိုးစေ့စာပိုဒ်တိုအရှည်", "seed_phrase_length": "မျိုးစေ့စာပိုဒ်တိုအရှည်",
"unavailable_balance": "လက်ကျန်ငွေ မရရှိနိုင်ပါ။", "unavailable_balance": "လက်ကျန်ငွေ မရရှိနိုင်ပါ။",
"unavailable_balance_description": "မရရှိနိုင်သော လက်ကျန်ငွေ- ဤစုစုပေါင်းတွင် ဆိုင်းငံ့ထားသော ငွေပေးငွေယူများတွင် သော့ခတ်ထားသော ငွေကြေးများနှင့် သင်၏ coin ထိန်းချုပ်မှုဆက်တင်များတွင် သင် တက်ကြွစွာ အေးခဲထားသော ငွေများ ပါဝင်သည်။ သော့ခတ်ထားသော လက်ကျန်ငွေများကို ၎င်းတို့၏ သက်ဆိုင်ရာ ငွေပေးငွေယူများ ပြီးမြောက်သည်နှင့် တပြိုင်နက် ရရှိနိုင်မည်ဖြစ်ပြီး၊ အေးခဲထားသော လက်ကျန်များကို ၎င်းတို့အား ပြန်ဖြုတ်ရန် သင်ဆုံးဖြတ်သည်အထိ ငွေပေးငွေယူများအတွက် ဆက်လက်၍မရနိုင်ပါ။", "unavailable_balance_description": "မရရှိနိုင်သော လက်ကျန်ငွေ- ဤစုစုပေါင်းတွင် ဆိုင်းငံ့ထားသော ငွေပေးငွေယူများတွင် သော့ခတ်ထားသော ငွေကြေးများနှင့် သင်၏ coin ထိန်းချုပ်မှုဆက်တင်များတွင် သင် တက်ကြွစွာ အေးခဲထားသော ငွေများ ပါဝင်သည်။ သော့ခတ်ထားသော လက်ကျန်ငွေများကို ၎င်းတို့၏ သက်ဆိုင်ရာ ငွေပေးငွေယူများ ပြီးမြောက်သည်နှင့် တပြိုင်နက် ရရှိနိုင်မည်ဖြစ်ပြီး၊ အေးခဲထားသော လက်ကျန်များကို ၎င်းတို့အား ပြန်ဖြုတ်ရန် သင်ဆုံးဖြတ်သည်အထိ ငွေပေးငွေယူများအတွက် ဆက်လက်၍မရနိုင်ပါ။",
"unspent_change": "ပေြာင်းလဲခြင်း", "unspent_change": "ပေြာင်းလဲခြင်း",
"Block_remaining": "ကျန်ရှိသော ${status}", "Block_remaining": "ကျန်ရှိသော ${status}",
"labeled_silent_addresses": "အသံတိတ်အသံတိတ်လိပ်စာများတံဆိပ်ကပ်", "labeled_silent_addresses": "အသံတိတ်အသံတိတ်လိပ်စာများတံဆိပ်ကပ်",
"use_testnet": "testnet ကိုသုံးပါ" "use_testnet": "testnet ကိုသုံးပါ",
"tor_connection": "Tor ချိတ်ဆက်မှု",
"seed_hex_form": "ပိုက်ဆံအိတ်မျိုးစေ့ (Hex Form)",
"seedtype": "မျိုးပွားခြင်း",
"seedtype_legacy": "အမွေအနှစ် (စကားလုံး 25 လုံး)",
"seedtype_polyseed": "polyseed (စကားလုံး 16 လုံး)",
"seed_language_czech": "ချက်",
"seed_language_korean": "ကိုးရီးယား",
"seed_language_chinese_traditional": "တရုတ်ရိုးရာ)"
} }

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