Merge branch 'main' into CAKE-330-unspent-coins-details-UI

# Conflicts:
#	lib/router.dart
#	lib/routes.dart
wownero
OleksandrSobol 3 years ago
commit 3f81f708e5

5
.gitignore vendored

@ -97,4 +97,7 @@ android/app/.cxx/**
ios/Flutter/.last_build_id
/lib/generated/**
#**#
/**/#**#
/**/#**#
**/google-services.json
**/GoogleService-Info.plist

@ -24,6 +24,10 @@ if (flutterVersionName == null) {
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
if (file("./google-services.json").exists()) {
apply plugin: 'com.google.gms.google-services'
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
@ -83,4 +87,6 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.google.firebase:firebase-core:19.0.0'
implementation 'com.google.firebase:firebase-messaging:19.0.0'
}

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<application
android:name=".Application"
android:label="Cake Wallet"
android:allowBackup="false"
android:fullBackupContent="false"
@ -29,7 +30,6 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />

@ -0,0 +1,21 @@
package com.cakewallet.cake_wallet;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
}

@ -6,6 +6,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.5.4'
classpath 'com.google.gms:google-services:4.3.8'
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -134,6 +134,7 @@ extern "C"
uint32_t subaddrAccount;
int8_t direction;
int8_t isPending;
uint32_t subaddrIndex;
char *hash;
char *paymentId;
@ -146,6 +147,8 @@ extern "C"
fee = transaction->fee();
blockHeight = transaction->blockHeight();
subaddrAccount = transaction->subaddrAccount();
std::set<uint32_t>::iterator it = transaction->subaddrIndex().begin();
subaddrIndex = *it;
confirmations = transaction->confirmations();
datetime = static_cast<int64_t>(transaction->timestamp());
direction = transaction->direction();

@ -23,6 +23,9 @@ class TransactionInfoRow extends Struct {
@Int8()
int isPending;
@Uint32()
int subaddrIndex;
Pointer<Utf8> hash;
Pointer<Utf8> paymentId;

@ -36,6 +36,7 @@ target 'Runner' do
# Cake Wallet (Legacy)
pod 'CryptoSwift'
pod 'Firebase/Messaging', '6.33.0'
end
post_install do |installer|

@ -62,18 +62,84 @@ PODS:
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/CoreOnly (6.33.0):
- FirebaseCore (= 6.10.3)
- Firebase/Messaging (6.33.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 4.7.0)
- firebase_core (0.5.3):
- Firebase/CoreOnly (~> 6.33.0)
- Flutter
- firebase_messaging (7.0.3):
- Firebase/CoreOnly (~> 6.33.0)
- Firebase/Messaging (~> 6.33.0)
- firebase_core
- Flutter
- FirebaseCore (6.10.3):
- FirebaseCoreDiagnostics (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- FirebaseCoreDiagnostics (1.7.0):
- GoogleDataTransport (~> 7.4)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- nanopb (~> 1.30906.0)
- FirebaseInstallations (1.7.0):
- FirebaseCore (~> 6.10)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- PromisesObjC (~> 1.2)
- FirebaseInstanceID (4.8.0):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- FirebaseMessaging (4.7.1):
- FirebaseCore (~> 6.10)
- FirebaseInstanceID (~> 4.7)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Reachability (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- Protobuf (>= 3.9.2, ~> 3.9)
- Flutter (1.0.0)
- flutter_secure_storage (3.3.1):
- Flutter
- GoogleDataTransport (7.5.1):
- nanopb (~> 1.30906.0)
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (6.7.2):
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Network (6.7.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (6.7.2)"
- GoogleUtilities/Reachability (6.7.2):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (6.7.2):
- GoogleUtilities/Logger
- local_auth (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- nanopb (1.30906.0):
- nanopb/decode (= 1.30906.0)
- nanopb/encode (= 1.30906.0)
- nanopb/decode (1.30906.0)
- nanopb/encode (1.30906.0)
- package_info (0.0.1):
- Flutter
- path_provider (0.0.1):
- Flutter
- "permission_handler (5.1.0+2)":
- Flutter
- PromisesObjC (1.2.12)
- Protobuf (3.17.0)
- Reachability (3.2)
- SDWebImage (5.9.1):
- SDWebImage/Core (= 5.9.1)
@ -97,6 +163,9 @@ DEPENDENCIES:
- devicelocale (from `.symlinks/plugins/devicelocale/ios`)
- esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- Firebase/Messaging (= 6.33.0)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- local_auth (from `.symlinks/plugins/local_auth/ios`)
@ -113,7 +182,18 @@ SPEC REPOS:
- CryptoSwift
- DKImagePickerController
- DKPhotoGallery
- Firebase
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseInstallations
- FirebaseInstanceID
- FirebaseMessaging
- GoogleDataTransport
- GoogleUtilities
- MTBBarcodeScanner
- nanopb
- PromisesObjC
- Protobuf
- Reachability
- SDWebImage
- SwiftProtobuf
@ -132,6 +212,10 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/esys_flutter_share/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_messaging:
:path: ".symlinks/plugins/firebase_messaging/ios"
Flutter:
:path: Flutter
flutter_secure_storage:
@ -163,13 +247,26 @@ SPEC CHECKSUMS:
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659
firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2
FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1
FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
Protobuf: 7327d4444215b5f18e560a97f879ff5503c4581c
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SDWebImage: a990c053fff71e388a10f3357edb0be17929c9c5
share: 0b2c3e82132f5888bccca3351c504d0003b3b410
@ -179,6 +276,6 @@ SPEC CHECKSUMS:
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b
PODFILE CHECKSUM: 5b5f101b119a1b6eb857c967d462832a9062dec4
PODFILE CHECKSUM: f316539722a6f9dbb0d0f1065a27fa7ea38c6f88
COCOAPODS: 1.9.3

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
0C37B8B926678E9100C6E5A9 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0C37B8B826678E9100C6E5A9 /* GoogleService-Info.plist */; };
0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44A7192518EF8000B570ED /* decrypt.swift */; };
0C9D68C9264854B60011B691 /* secRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9D68C8264854B60011B691 /* secRandom.swift */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
@ -19,6 +20,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0C37B8B826678E9100C6E5A9 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
0C400E0F25B21ABB0025E469 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = "<group>"; };
0C9986A3251A932F00D566FD /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -96,6 +98,7 @@
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
0C37B8B826678E9100C6E5A9 /* GoogleService-Info.plist */,
0C44A7182518EF4A00B570ED /* CakeWallet */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
@ -191,6 +194,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0C37B8B926678E9100C6E5A9 /* GoogleService-Info.plist in Resources */,
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
@ -362,9 +366,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 40;
CURRENT_PROJECT_VERSION = 49;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
EXCLUDED_SOURCE_FILE_NAMES = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
@ -379,7 +384,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.2.0;
MARKETING_VERSION = 4.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -505,9 +510,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 40;
CURRENT_PROJECT_VERSION = 49;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
EXCLUDED_SOURCE_FILE_NAMES = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
@ -522,7 +528,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.2.0;
MARKETING_VERSION = 4.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -540,9 +546,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 40;
CURRENT_PROJECT_VERSION = 49;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
EXCLUDED_SOURCE_FILE_NAMES = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
@ -557,7 +564,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.2.0;
MARKETING_VERSION = 4.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

@ -7,6 +7,10 @@ import Flutter
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let legacyMigrationChannel = FlutterMethodChannel(
name: "com.cakewallet.cakewallet/legacy_wallet_migration",

@ -37,6 +37,11 @@
<string>Enable Face ID for fast and secure access to wallets and private keys</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to documents folder for get acces to open/save backup file</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>

@ -1,5 +1,5 @@
class BitcoinMnemonicIsIncorrectException implements Exception {
@override
String toString() =>
'Bitcoin mnemonic has incorrect format. Mnemonic should contain 24 words separated by space.';
'Bitcoin mnemonic has incorrect format. Mnemonic should contain 12 or 24 words separated by space.';
}

@ -35,7 +35,7 @@ abstract class ElectrumTransactionHistoryBase
@override
void addMany(Map<String, ElectrumTransactionInfo> transactions) =>
this.transactions.addAll(transactions);
transactions.forEach((_, tx) => _updateOrInsert(tx));
@override
Future<void> save() async {

@ -0,0 +1,12 @@
import 'package:flutter/foundation.dart';
class BuyAmount {
BuyAmount({
@required this.sourceAmount,
@required this.destAmount,
this.minAmount = 0});
final double sourceAmount;
final double destAmount;
final int minAmount;
}

@ -0,0 +1,12 @@
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
class BuyException implements Exception {
BuyException({@required this.description, @required this.text});
final BuyProviderDescription description;
final String text;
@override
String toString() => '${description.title}: $text';
}

@ -0,0 +1,27 @@
import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
abstract class BuyProvider {
BuyProvider({this.wallet, this.isTestEnvironment});
final WalletBase wallet;
final bool isTestEnvironment;
String get title;
BuyProviderDescription get description;
String get trackUrl;
WalletType get walletType => wallet.type;
String get walletAddress => wallet.address;
String get walletId => wallet.id;
@override
String toString() => title;
Future<String> requestUrl(String amount, String sourceCurrency);
Future<Order> findOrderById(String id);
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency);
}

@ -0,0 +1,21 @@
import 'package:cake_wallet/entities/enumerable_item.dart';
class BuyProviderDescription extends EnumerableItem<int>
with Serializable<int> {
const BuyProviderDescription({String title, int raw})
: super(title: title, raw: raw);
static const wyre = BuyProviderDescription(title: 'Wyre', raw: 0);
static const moonPay = BuyProviderDescription(title: 'MoonPay', raw: 1);
static BuyProviderDescription deserialize({int raw}) {
switch (raw) {
case 0:
return wyre;
case 1:
return moonPay;
default:
return null;
}
}
}

@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
Image getBuyProviderIcon(BuyProviderDescription providerDescription,
{bool isWhiteIconColor = false}) {
final _wyreIcon =
Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
final _moonPayWhiteIcon =
Image.asset('assets/images/moonpay-icon.png', color: Colors.white,
width: 36, height: 34);
final _moonPayBlackIcon =
Image.asset('assets/images/moonpay-icon.png', color: Colors.black,
width: 36, height: 34);
if (providerDescription != null) {
switch (providerDescription) {
case BuyProviderDescription.wyre:
return _wyreIcon;
case BuyProviderDescription.moonPay:
return isWhiteIconColor ? _moonPayWhiteIcon : _moonPayBlackIcon;
default:
return null;
}
} else {
return null;
}
}

@ -0,0 +1,144 @@
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:cake_wallet/buy/buy_exception.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
class MoonPayBuyProvider extends BuyProvider {
MoonPayBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
: super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl;
}
static const _baseTestUrl = 'https://buy-staging.moonpay.com';
static const _baseProductUrl = 'https://buy.moonpay.com';
static const _apiUrl = 'https://api.moonpay.com';
static const _currenciesSuffix = '/v3/currencies';
static const _quoteSuffix = '/buy_quote';
static const _transactionsSuffix = '/v1/transactions';
static const _ipAddressSuffix = '/v4/ip_address';
static const _apiKey = secrets.moonPayApiKey;
static const _secretKey = secrets.moonPaySecretKey;
@override
String get title => 'MoonPay';
@override
BuyProviderDescription get description => BuyProviderDescription.moonPay;
String get currencyCode =>
walletTypeToCryptoCurrency(walletType).title.toLowerCase();
@override
String get trackUrl => baseUrl + '/transaction_receipt?transactionId=';
String baseUrl;
@override
Future<String> requestUrl(String amount, String sourceCurrency) async {
final enabledPaymentMethods =
'credit_debit_card%2Capple_pay%2Cgoogle_pay%2Csamsung_pay'
'%2Csepa_bank_transfer%2Cgbp_bank_transfer%2Cgbp_open_banking_payment';
final suffix = '?apiKey=' + _apiKey + '&currencyCode=' +
currencyCode + '&enabledPaymentMethods=' + enabledPaymentMethods +
'&walletAddress=' + walletAddress +
'&baseCurrencyCode=' + sourceCurrency.toLowerCase() +
'&baseCurrencyAmount=' + amount + '&lockAmount=true' +
'&showAllCurrencies=false' + '&showWalletAddressForm=false';
final originalUrl = baseUrl + suffix;
final messageBytes = utf8.encode(suffix);
final key = utf8.encode(_secretKey);
final hmac = Hmac(sha256, key);
final digest = hmac.convert(messageBytes);
final signature = base64.encode(digest.bytes);
final urlWithSignature = originalUrl +
'&signature=${Uri.encodeComponent(signature)}';
return isTestEnvironment ? originalUrl : urlWithSignature;
}
@override
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
final url = _apiUrl + _currenciesSuffix + '/$currencyCode' +
_quoteSuffix + '/?apiKey=' + _apiKey +
'&baseCurrencyAmount=' + amount +
'&baseCurrencyCode=' + sourceCurrency.toLowerCase();
final response = await get(url);
if (response.statusCode != 200) {
throw BuyException(
description: description,
text: 'Quote is not found!');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final sourceAmount = responseJSON['totalAmount'] as double;
final destAmount = responseJSON['quoteCurrencyAmount'] as double;
final minSourceAmount = responseJSON['baseCurrency']['minAmount'] as int;
return BuyAmount(
sourceAmount: sourceAmount,
destAmount: destAmount,
minAmount: minSourceAmount);
}
@override
Future<Order> findOrderById(String id) async {
final url = _apiUrl + _transactionsSuffix + '/$id' +
'?apiKey=' + _apiKey;
final response = await get(url);
if (response.statusCode != 200) {
throw BuyException(
description: description,
text: 'Transaction $id is not found!');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final status = responseJSON['status'] as String;
final state = TradeState.deserialize(raw: status);
final createdAtRaw = responseJSON['createdAt'] as String;
final createdAt = DateTime.parse(createdAtRaw).toLocal();
final amount = responseJSON['quoteCurrencyAmount'] as double;
return Order(
id: id,
provider: description,
transferId: id,
state: state,
createdAt: createdAt,
amount: amount.toString(),
receiveAddress: walletAddress,
walletId: walletId
);
}
static Future<bool> onEnabled() async {
final url = _apiUrl + _ipAddressSuffix + '?apiKey=' + _apiKey;
var isBuyEnable = false;
final response = await get(url);
try {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
isBuyEnable = responseJSON['isBuyAllowed'] as bool;
} catch (e) {
isBuyEnable = false;
print(e.toString());
}
return isBuyEnable;
}
}

@ -1,3 +1,4 @@
import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:hive/hive.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/entities/format_amount.dart';
@ -8,6 +9,7 @@ part 'order.g.dart';
class Order extends HiveObject {
Order(
{this.id,
BuyProviderDescription provider,
this.transferId,
this.from,
this.to,
@ -16,7 +18,8 @@ class Order extends HiveObject {
this.amount,
this.receiveAddress,
this.walletId})
: stateRaw = state?.raw;
: providerRaw = provider?.raw,
stateRaw = state?.raw;
static const typeId = 8;
static const boxName = 'Orders';
@ -51,5 +54,11 @@ class Order extends HiveObject {
@HiveField(8)
String walletId;
@HiveField(9)
int providerRaw;
BuyProviderDescription get provider =>
BuyProviderDescription.deserialize(raw: providerRaw);
String amountFormatted() => formatAmount(amount);
}

@ -0,0 +1,163 @@
import 'dart:convert';
import 'package:cake_wallet/buy/buy_exception.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
class WyreBuyProvider extends BuyProvider {
WyreBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
: super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
baseApiUrl = isTestEnvironment
? _baseTestApiUrl
: _baseProductApiUrl;
}
static const _baseTestApiUrl = 'https://api.testwyre.com';
static const _baseProductApiUrl = 'https://api.sendwyre.com';
static const _trackTestUrl = 'https://dash.testwyre.com/track/';
static const _trackProductUrl = 'https://dash.sendwyre.com/track/';
static const _ordersSuffix = '/v3/orders';
static const _reserveSuffix = '/reserve';
static const _quoteSuffix = '/quote/partner';
static const _timeStampSuffix = '?timestamp=';
static const _transferSuffix = '/v2/transfer/';
static const _trackSuffix = '/track';
static const _countryCode = 'US';
static const _secretKey = secrets.wyreSecretKey;
static const _accountId = secrets.wyreAccountId;
@override
String get title => 'Wyre';
@override
BuyProviderDescription get description => BuyProviderDescription.wyre;
@override
String get trackUrl => isTestEnvironment
? _trackTestUrl
: _trackProductUrl;
String baseApiUrl;
@override
Future<String> requestUrl(String amount, String sourceCurrency) async {
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
_timeStampSuffix + timestamp;
final body = {
'amount': amount,
'sourceCurrency': sourceCurrency,
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
'referrerAccountId': _accountId,
'lockFields': ['amount', 'sourceCurrency', 'destCurrency', 'dest']
};
final response = await post(url,
headers: {
'Authorization': 'Bearer $_secretKey',
'Content-Type': 'application/json',
'cache-control': 'no-cache'
},
body: json.encode(body));
if (response.statusCode != 200) {
throw BuyException(
description: description,
text: 'Url $url is not found!');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final urlFromResponse = responseJSON['url'] as String;
return urlFromResponse;
}
@override
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
final quoteUrl = _baseProductApiUrl + _ordersSuffix + _quoteSuffix;
final body = {
'amount': amount,
'sourceCurrency': sourceCurrency,
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
'accountId': _accountId,
'country': _countryCode
};
final response = await post(quoteUrl,
headers: {
'Authorization': 'Bearer $_secretKey',
'Content-Type': 'application/json',
'cache-control': 'no-cache'
},
body: json.encode(body));
if (response.statusCode != 200) {
throw BuyException(
description: description,
text: 'Quote is not found!');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final sourceAmount = responseJSON['sourceAmount'] as double;
final destAmount = responseJSON['destAmount'] as double;
return BuyAmount(sourceAmount: sourceAmount, destAmount: destAmount);
}
@override
Future<Order> findOrderById(String id) async {
final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
final orderResponse = await get(orderUrl);
if (orderResponse.statusCode != 200) {
throw BuyException(
description: description,
text: 'Order $id is not found!');
}
final orderResponseJSON =
json.decode(orderResponse.body) as Map<String, dynamic>;
final transferId = orderResponseJSON['transferId'] as String;
final from = orderResponseJSON['sourceCurrency'] as String;
final to = orderResponseJSON['destCurrency'] as String;
final status = orderResponseJSON['status'] as String;
final state = TradeState.deserialize(raw: status.toLowerCase());
final createdAtRaw = orderResponseJSON['createdAt'] as int;
final createdAt =
DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
final transferUrl =
baseApiUrl + _transferSuffix + transferId + _trackSuffix;
final transferResponse = await get(transferUrl);
if (transferResponse.statusCode != 200) {
throw BuyException(
description: description,
text: 'Transfer $transferId is not found!');
}
final transferResponseJSON =
json.decode(transferResponse.body) as Map<String, dynamic>;
final amount = transferResponseJSON['destAmount'] as double;
return Order(
id: id,
provider: description,
transferId: transferId,
from: from,
to: to,
state: state,
createdAt: createdAt,
amount: amount.toString(),
receiveAddress: walletAddress,
walletId: walletId
);
}
}

@ -4,11 +4,9 @@ import 'package:cake_wallet/core/backup_service.dart';
import 'package:cake_wallet/core/wallet_service.dart';
import 'package:cake_wallet/entities/biometric_auth.dart';
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/load_current_wallet.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/entities/transaction_info.dart';
import 'package:cake_wallet/entities/wyre_service.dart';
import 'package:cake_wallet/monero/monero_wallet_service.dart';
import 'package:cake_wallet/entities/contact.dart';
import 'package:cake_wallet/entities/node.dart';
@ -16,7 +14,8 @@ import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/reactions/on_authentication_state_change.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/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
@ -45,7 +44,6 @@ import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.da
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
import 'package:cake_wallet/src/screens/wyre/wyre_page.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:cake_wallet/store/node_list_store.dart';
import 'package:cake_wallet/store/secret_store.dart';
@ -64,6 +62,8 @@ import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.d
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
import 'package:cake_wallet/store/wallet_list_store.dart';
import 'package:cake_wallet/view_model/backup_view_model.dart';
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart';
@ -95,7 +95,6 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:flutter/widgets.dart';
import 'package:get_it/get_it.dart';
import 'package:hive/hive.dart';
@ -118,6 +117,7 @@ import 'package:cake_wallet/store/templates/exchange_template_store.dart';
import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/entities/push_notifications_service.dart';
final getIt = GetIt.instance;
@ -157,6 +157,7 @@ Future setup(
final isBitcoinBuyEnabled = (secrets.wyreSecretKey?.isNotEmpty ?? false) &&
(secrets.wyreApiKey?.isNotEmpty ?? false) &&
(secrets.wyreAccountId?.isNotEmpty ?? false);
final settingsStore = await SettingsStoreBase.load(
nodeSource: _nodeSource, isBitcoinBuyEnabled: isBitcoinBuyEnabled);
@ -237,6 +238,9 @@ Future setup(
settingsStore: getIt.get<SettingsStore>(),
fiatConvertationStore: getIt.get<FiatConversionStore>()));
getIt.registerFactory(() => PushNotificationsService());
getIt.registerFactory(() => DashboardViewModel(
balanceViewModel: getIt.get<BalanceViewModel>(),
appStore: getIt.get<AppStore>(),
@ -244,9 +248,8 @@ Future setup(
tradeFilterStore: getIt.get<TradeFilterStore>(),
transactionFilterStore: getIt.get<TransactionFilterStore>(),
settingsStore: settingsStore,
ordersSource: _ordersSource,
ordersStore: getIt.get<OrdersStore>(),
wyreViewModel: getIt.get<WyreViewModel>()));
pushNotificationsService: getIt.get<PushNotificationsService>()));
getIt.registerFactory<AuthService>(() => AuthService(
secureStorage: getIt.get<FlutterSecureStorage>(),
@ -492,10 +495,14 @@ Future setup(
getIt
.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>(
(TransactionInfo transactionInfo, _) => TransactionDetailsViewModel(
transactionInfo: transactionInfo,
transactionDescriptionBox: _transactionDescriptionBox,
settingsStore: getIt.get<SettingsStore>()));
(TransactionInfo transactionInfo, _) {
final wallet = getIt.get<AppStore>().wallet;
return TransactionDetailsViewModel(
transactionInfo: transactionInfo,
transactionDescriptionBox: _transactionDescriptionBox,
wallet: wallet,
settingsStore: getIt.get<SettingsStore>());
});
getIt.registerFactoryParam<TransactionDetailsPage, TransactionInfo, void>(
(TransactionInfo transactionInfo, _) => TransactionDetailsPage(
@ -542,22 +549,37 @@ Future setup(
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
getIt.registerFactory(() => BuyAmountViewModel());
getIt.registerFactory(() {
return WyreService(appStore: getIt.get<AppStore>());
final wallet = getIt.get<AppStore>().wallet;
return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(),
getIt.get<SettingsStore>(), getIt.get<BuyAmountViewModel>(),
wallet: wallet);
});
getIt.registerFactory(() {
return WyreViewModel(ordersSource, getIt.get<OrdersStore>(),
wyreService: getIt.get<WyreService>());
return PreOrderPage(buyViewModel: getIt.get<BuyViewModel>());
});
getIt.registerFactoryParam<WyrePage, String, void>((String url, _) =>
WyrePage(getIt.get<WyreViewModel>(),
ordersStore: getIt.get<OrdersStore>(), url: url));
getIt.registerFactoryParam<BuyWebViewPage, List, void>(
(List args, _) {
final url = args.first as String;
final buyViewModel = args[1] as BuyViewModel;
return BuyWebViewPage(buyViewModel: buyViewModel,
ordersStore: getIt.get<OrdersStore>(), url: url);
});
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>(
(order, _) {
final wallet = getIt.get<AppStore>().wallet;
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) =>
OrderDetailsViewModel(
wyreViewModel: getIt.get<WyreViewModel>(), orderForDetails: order));
return OrderDetailsViewModel(
wallet: wallet,
orderForDetails: order);
});
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));

@ -7,7 +7,7 @@ class BiometricAuth {
Future<bool> isAuthenticated() async {
try {
return await _localAuth.authenticateWithBiometrics(
return await _localAuth.authenticate(
localizedReason: S.current.biometric_auth_reason,
useErrorDialogs: true,
stickyAuth: false);

@ -19,4 +19,5 @@ class PreferencesKey {
'current_default_settings_migration_version';
static const moneroTransactionPriority = 'current_fee_priority_monero';
static const bitcoinTransactionPriority = 'current_fee_priority_bitcoin';
static const shouldShowReceiveWarning = 'should_show_receive_warning';
}

@ -0,0 +1,49 @@
import 'dart:io';
import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
class PushNotificationsService {
PushNotificationsService._();
factory PushNotificationsService() => _instance;
static final PushNotificationsService _instance = PushNotificationsService._();
static Future<dynamic> _onBackgroundMessage(Map<String, dynamic> message) async {}
static Future<void> _showNotification(Map<String, dynamic> message) async {
Map<dynamic, dynamic> alert = <dynamic, dynamic>{};
String msg = '';
String title = '';
if (Platform.isIOS) {
alert = message['aps']['alert'] as Map<dynamic, dynamic> ?? <dynamic, dynamic>{};
msg = alert['body'] as String ?? '';
title = alert['title'] as String ?? '';
}
if (Platform.isAndroid) {
msg = message['notification']['body'] as String ?? '';
title = message['notification']['title'] as String ?? '';
}
await showBar<void>(navigatorKey.currentContext, msg, titleText: title, duration: null);
}
final _firebaseMessaging = FirebaseMessaging();
bool _initialized = false;
Future<void> init() async {
if (_initialized) {
return;
}
_firebaseMessaging.requestNotificationPermissions();
_firebaseMessaging.configure(
onMessage: (message) async => _showNotification(message),
onLaunch: (message) async => _showNotification(message),
onResume: (message) async => _showNotification(message),
onBackgroundMessage: _onBackgroundMessage);
_initialized = true;
}
}

@ -71,7 +71,7 @@ String walletTypeToDisplayName(WalletType type) {
case WalletType.bitcoin:
return 'Bitcoin (Electrum)';
case WalletType.litecoin:
return 'Litecoin';
return 'Litecoin (Electrum)';
default:
return '';
}

@ -1,8 +0,0 @@
class WyreException implements Exception {
WyreException(this.description);
String description;
@override
String toString() => description;
}

@ -1,113 +0,0 @@
import 'dart:convert';
import 'package:cake_wallet/entities/wyre_exception.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
class WyreService {
WyreService({@required this.appStore, this.isTestEnvironment = false}) {
baseApiUrl = isTestEnvironment ? _baseTestApiUrl : _baseProductApiUrl;
trackUrl = isTestEnvironment ? _trackTestUrl : _trackProductUrl;
}
static const _baseTestApiUrl = 'https://api.testwyre.com';
static const _baseProductApiUrl = 'https://api.sendwyre.com';
static const _trackTestUrl = 'https://dash.testwyre.com/track/';
static const _trackProductUrl = 'https://dash.sendwyre.com/track/';
static const _ordersSuffix = '/v3/orders';
static const _reserveSuffix = '/reserve';
static const _timeStampSuffix = '?timestamp=';
static const _transferSuffix = '/v2/transfer/';
static const _trackSuffix = '/track';
final bool isTestEnvironment;
final AppStore appStore;
WalletType get walletType => appStore.wallet.type;
String get walletAddress => appStore.wallet.address;
String get walletId => appStore.wallet.id;
String baseApiUrl;
String trackUrl;
Future<String> getWyreUrl() async {
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
final url = baseApiUrl +
_ordersSuffix +
_reserveSuffix +
_timeStampSuffix +
timestamp;
final secretKey = secrets.wyreSecretKey;
final accountId = secrets.wyreAccountId;
final body = {
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
'dest':
walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
'referrerAccountId': accountId,
'lockFields': ['destCurrency', 'dest']
};
final response = await post(url,
headers: {
'Authorization': 'Bearer $secretKey',
'Content-Type': 'application/json',
'cache-control': 'no-cache'
},
body: json.encode(body));
if (response.statusCode != 200) {
throw WyreException('Url $url is not found!');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final urlFromResponse = responseJSON['url'] as String;
return urlFromResponse;
}
Future<Order> findOrderById(String id) async {
final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
final orderResponse = await get(orderUrl);
if (orderResponse.statusCode != 200) {
throw WyreException('Order $id is not found!');
}
final orderResponseJSON =
json.decode(orderResponse.body) as Map<String, dynamic>;
final transferId = orderResponseJSON['transferId'] as String;
final from = orderResponseJSON['sourceCurrency'] as String;
final to = orderResponseJSON['destCurrency'] as String;
final status = orderResponseJSON['status'] as String;
final state = TradeState.deserialize(raw: status.toLowerCase());
final createdAtRaw = orderResponseJSON['createdAt'] as int;
final createdAt =
DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
final transferUrl =
baseApiUrl + _transferSuffix + transferId + _trackSuffix;
final transferResponse = await get(transferUrl);
if (transferResponse.statusCode != 200) {
throw WyreException('Transfer $transferId is not found!');
}
final transferResponseJSON =
json.decode(transferResponse.body) as Map<String, dynamic>;
final amount = transferResponseJSON['destAmount'] as double;
return Order(
id: id,
transferId: transferId,
from: from,
to: to,
state: state,
createdAt: createdAt,
amount: amount.toString(),
receiveAddress: walletAddress,
walletId: walletId);
}
}

@ -27,6 +27,12 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
static const finished = TradeState(raw: 'finished', title: 'Finished');
static const waiting = TradeState(raw: 'waiting', title: 'Waiting');
static const processing = TradeState(raw: 'processing', title: 'Processing');
static const waitingPayment =
TradeState(raw: 'waitingPayment', title: 'Waiting payment');
static const waitingAuthorization =
TradeState(raw: 'waitingAuthorization', title: 'Waiting authorization');
static const failed = TradeState(raw: 'failed', title: 'Failed');
static const completed = TradeState(raw: 'completed', title: 'Completed');
static TradeState deserialize({String raw}) {
switch (raw) {
@ -62,6 +68,14 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
return waiting;
case 'processing':
return processing;
case 'waitingPayment':
return waitingPayment;
case 'waitingAuthorization':
return waitingAuthorization;
case 'failed':
return failed;
case 'completed':
return completed;
default:
return null;
}

@ -1,5 +1,5 @@
import 'package:cake_wallet/entities/language_service.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hive/hive.dart';

@ -8,7 +8,7 @@ import 'package:cw_monero/transaction_history.dart';
class MoneroTransactionInfo extends TransactionInfo {
MoneroTransactionInfo(this.id, this.height, this.direction, this.date,
this.isPending, this.amount, this.accountIndex, this.fee);
this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee);
MoneroTransactionInfo.fromMap(Map map)
: id = (map['hash'] ?? '') as String,
@ -21,6 +21,7 @@ class MoneroTransactionInfo extends TransactionInfo {
isPending = parseBoolFromString(map['isPending'] as String),
amount = map['amount'] as int,
accountIndex = int.parse(map['accountIndex'] as String),
addressIndex = map['addressIndex'] as int,
key = getTxKey((map['hash'] ?? '') as String),
fee = map['fee'] as int ?? 0;
@ -33,6 +34,7 @@ class MoneroTransactionInfo extends TransactionInfo {
isPending = row.isPending != 0,
amount = row.getAmount(),
accountIndex = row.subaddrAccount,
addressIndex = row.subaddrIndex,
key = getTxKey(row.getHash()),
fee = row.fee;
@ -44,6 +46,7 @@ class MoneroTransactionInfo extends TransactionInfo {
final bool isPending;
final int amount;
final int fee;
final int addressIndex;
String recipientAddress;
String key;

@ -271,6 +271,11 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
await walletInfo.save();
}
String getTransactionAddress(int accountIndex, int addressIndex) =>
monero_wallet.getAddress(
accountIndex: accountIndex,
addressIndex: addressIndex);
@override
Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async {
monero_transaction_history.refreshTransactions();

@ -23,6 +23,7 @@ class Palette {
static const Color persianRed = Color.fromRGBO(206, 55, 55, 1.0);
static const Color blueCraiola = Color.fromRGBO(69, 110, 255, 1.0);
static const Color blueGreyCraiola = Color.fromRGBO(106, 177, 207, 1.0);
static const Color greyBlueCraiola = Color.fromRGBO(116, 139, 219, 1.0);
static const Color darkBlueCraiola = Color.fromRGBO(53, 86, 136, 1.0);
static const Color pinkFlamingo = Color.fromRGBO(240, 60, 243, 1.0);
static const Color redHat = Color.fromRGBO(209, 68, 37, 1.0);

@ -1,8 +1,10 @@
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/transaction_description.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/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
@ -11,8 +13,8 @@ import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
import 'package:cake_wallet/src/screens/support/support_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/wyre/wyre_page.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
import 'package:flutter/cupertino.dart';
@ -302,10 +304,17 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) =>
getIt.get<OrderDetailsPage>(param1: settings.arguments as Order));
case Routes.wyre:
case Routes.preOrder:
return MaterialPageRoute<void>(
builder: (_) =>
getIt.get<WyrePage>(param1: settings.arguments as String));
getIt.get<PreOrderPage>());
case Routes.buyWebView:
final args = settings.arguments as List;
return MaterialPageRoute<void>(
builder: (_) =>
getIt.get<BuyWebViewPage>(param1: args));
case Routes.restoreWalletFromSeedDetails:
final args = settings.arguments as List;

@ -53,7 +53,8 @@ class Routes {
static const restoreFromBackup = '/restore_from_backup';
static const support = '/support';
static const orderDetails = '/order_details';
static const wyre = '/wyre';
static const preOrder = '/pre_order';
static const buyWebView = '/buy_web_view';
static const unspentCoinsList = '/unspent_coins_list';
static const unspentCoinsDetails = '/unspent_coins_details';
}

@ -1,20 +1,23 @@
import 'dart:async';
import 'dart:io';
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
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/store/dashboard/orders_store.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WyrePage extends BasePage {
WyrePage(this.wyreViewModel,
{@required this.ordersStore, @required this.url});
class BuyWebViewPage extends BasePage {
BuyWebViewPage({@required this.buyViewModel,
@required this.ordersStore, @required this.url});
final OrdersStore ordersStore;
final String url;
final WyreViewModel wyreViewModel;
final BuyViewModel buyViewModel;
@override
String get title => S.current.buy;
@ -27,26 +30,27 @@ class WyrePage extends BasePage {
@override
Widget body(BuildContext context) =>
WyrePageBody(wyreViewModel, ordersStore: ordersStore, url: url);
BuyWebViewPageBody(buyViewModel, ordersStore: ordersStore, url: url);
}
class WyrePageBody extends StatefulWidget {
WyrePageBody(this.wyreViewModel, {this.ordersStore, this.url});
class BuyWebViewPageBody extends StatefulWidget {
BuyWebViewPageBody(this.buyViewModel, {this.ordersStore, this.url});
final OrdersStore ordersStore;
final String url;
final WyreViewModel wyreViewModel;
final BuyViewModel buyViewModel;
@override
WyrePageBodyState createState() => WyrePageBodyState();
BuyWebViewPageBodyState createState() => BuyWebViewPageBodyState();
}
class WyrePageBodyState extends State<WyrePageBody> {
class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
String orderId;
WebViewController _webViewController;
GlobalKey _webViewkey;
Timer _timer;
bool _isSaving;
BuyProvider _provider;
@override
void initState() {
@ -54,9 +58,30 @@ class WyrePageBodyState extends State<WyrePageBody> {
_webViewkey = GlobalKey();
_isSaving = false;
widget.ordersStore.orderId = '';
_provider = widget.buyViewModel.selectedProvider;
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
if (_provider is WyreBuyProvider) {
_saveOrder(keyword: 'completed', splitSymbol: '/');
}
if (_provider is MoonPayBuyProvider) {
_saveOrder(keyword: 'transactionId', splitSymbol: '=');
}
}
@override
Widget build(BuildContext context) {
return WebView(
key: _webViewkey,
initialUrl: widget.url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller) =>
setState(() => _webViewController = controller));
}
void _saveOrder({String keyword, String splitSymbol}) {
_timer?.cancel();
_timer = Timer.periodic(Duration(seconds: 1), (timer) async {
@ -67,14 +92,14 @@ class WyrePageBodyState extends State<WyrePageBody> {
final url = await _webViewController.currentUrl();
if (url.contains('completed')) {
final urlParts = url.split('/');
if (url.contains(keyword)) {
final urlParts = url.split(splitSymbol);
orderId = urlParts.last;
widget.ordersStore.orderId = orderId;
if (orderId.isNotEmpty) {
_isSaving = true;
await widget.wyreViewModel.saveOrder(orderId);
await widget.buyViewModel.saveOrder(orderId);
timer.cancel();
}
}
@ -84,14 +109,4 @@ class WyrePageBodyState extends State<WyrePageBody> {
}
});
}
@override
Widget build(BuildContext context) {
return WebView(
key: _webViewkey,
initialUrl: widget.url,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller) =>
setState(() => _webViewController = controller));
}
}

@ -0,0 +1,287 @@
import 'dart:ui';
import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/src/screens/buy/widgets/buy_list_item.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/trail_button.dart';
import 'package:mobx/mobx.dart';
import 'package:url_launcher/url_launcher.dart';
class PreOrderPage extends BasePage {
PreOrderPage({@required this.buyViewModel})
: _amountFocus = FocusNode(),
_amountController = TextEditingController() {
_amountController.addListener(() {
final amount = _amountController.text;
if (amount != buyViewModel.buyAmountViewModel.amount) {
buyViewModel.buyAmountViewModel.amount = amount;
buyViewModel.selectedProvider = null;
}
});
reaction((_) => buyViewModel.buyAmountViewModel.amount, (String amount) {
if (_amountController.text != amount) {
_amountController.text = amount;
}
if (amount.isEmpty) {
buyViewModel.selectedProvider = null;
buyViewModel.isShowProviderButtons = false;
} else {
buyViewModel.isShowProviderButtons = true;
}
});
}
static const _amountPattern = '^([0-9]+([.\,][0-9]{0,2})?|[.\,][0-9]{1,2})\$';
final BuyViewModel buyViewModel;
final FocusNode _amountFocus;
final TextEditingController _amountController;
@override
String get title => S.current.buy + ' ' + walletTypeToString(buyViewModel.wallet.type);
@override
Color get titleColor => Colors.white;
@override
bool get resizeToAvoidBottomInset => false;
@override
bool get extendBodyBehindAppBar => true;
@override
AppBarStyle get appBarStyle => AppBarStyle.transparent;
@override
Widget trailing(context) => TrailButton(
caption: S.of(context).clear,
onPressed: () => buyViewModel.reset());
@override
Widget body(BuildContext context) {
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.body2
.backgroundColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFocus,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
height: 0,
color: Theme.of(context).backgroundColor,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Observer(builder: (_) => Column(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context)
.primaryTextTheme
.subhead
.decorationColor,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Padding(
padding: EdgeInsets.only(top: 100, bottom: 65),
child: Center(
child: Container(
width: 210,
child: BaseTextFormField(
focusNode: _amountFocus,
controller: _amountController,
keyboardType:
TextInputType.numberWithOptions(
signed: false, decimal: true),
inputFormatters: [
FilteringTextInputFormatter
.allow(RegExp(_amountPattern))
],
prefixIcon: Padding(
padding: EdgeInsets.only(top: 2),
child:
Text(buyViewModel.fiatCurrency.title + ': ',
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.w600,
color: Colors.white,
)),
),
hintText: '0.00',
borderColor: Theme.of(context)
.primaryTextTheme
.body2
.decorationColor,
borderWidth: 0.5,
textStyle: TextStyle(
fontSize: 36,
fontWeight: FontWeight.w500,
color: Colors.white),
placeholderTextStyle: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.headline
.decorationColor,
fontWeight: FontWeight.w500,
fontSize: 36),
)
)
)
)
),
if (buyViewModel.isShowProviderButtons) Padding(
padding: EdgeInsets.only(top: 38, bottom: 18),
child: Text(
S.of(context).buy_with + ':',
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.title.color,
fontSize: 18,
fontWeight: FontWeight.bold
),
)
),
if (buyViewModel.isShowProviderButtons)
...buyViewModel.items.map(
(item) => Observer(builder: (_) =>
FutureBuilder<BuyAmount>(
future: item.buyAmount,
builder: (context, AsyncSnapshot<BuyAmount> snapshot) {
double sourceAmount;
double destAmount;
int minAmount;
if (snapshot.hasData) {
sourceAmount = snapshot.data.sourceAmount;
destAmount = snapshot.data.destAmount;
minAmount = snapshot.data.minAmount;
} else {
sourceAmount = 0.0;
destAmount = 0.0;
minAmount = 0;
}
return Padding(
padding:
EdgeInsets.only(left: 15, top: 20, right: 15),
child: Observer(builder: (_) {
return BuyListItem(
selectedProvider:
buyViewModel.selectedProvider,
provider: item.provider,
sourceAmount: sourceAmount,
sourceCurrency: buyViewModel.fiatCurrency,
destAmount: destAmount,
destCurrency: buyViewModel.cryptoCurrency,
onTap: ((buyViewModel.doubleAmount != 0.0)
&& (snapshot.hasData)) ? () =>
onSelectBuyProvider(
context: context,
provider: item.provider,
sourceAmount: sourceAmount,
minAmount: minAmount
) : null
);
})
);
}
))
)
],
)),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Observer(builder: (_) {
return LoadingPrimaryButton(
onPressed: () => onPresentProvider(context: context),
text: buyViewModel.selectedProvider == null
? S.of(context).buy
: S.of(context).buy_with +
' ${buyViewModel.selectedProvider
.description.title}',
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white,
isLoading: buyViewModel.isRunning,
isDisabled: (buyViewModel.selectedProvider == null) ||
buyViewModel.isDisabled
);
})
)
)
);
}
void onSelectBuyProvider({BuildContext context, BuyProvider provider,
double sourceAmount, int minAmount}) {
if ((provider is MoonPayBuyProvider)&&
(buyViewModel.buyAmountViewModel.doubleAmount < minAmount)) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: 'MoonPay',
alertContent: S.of(context).moonpay_alert_text(
minAmount.toString(),
buyViewModel.fiatCurrency.toString()),
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
return;
}
buyViewModel.selectedProvider = provider;
sourceAmount > 0
? buyViewModel.isDisabled = false
: buyViewModel.isDisabled = true;
}
Future<void> onPresentProvider({BuildContext context}) async {
if (buyViewModel.isRunning) {
return;
}
buyViewModel.isRunning = true;
final url = await buyViewModel.fetchUrl();
if (url.isNotEmpty) {
if (buyViewModel.selectedProvider is MoonPayBuyProvider) {
if (await canLaunch(url)) await launch(url);
} else {
await Navigator.of(context)
.pushNamed(Routes.buyWebView,
arguments: [url, buyViewModel]);
}
}
buyViewModel.reset();
buyViewModel.isRunning = false;
}
}

@ -0,0 +1,116 @@
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
import 'package:cake_wallet/entities/crypto_currency.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
class BuyListItem extends StatelessWidget {
BuyListItem({
@required this.selectedProvider,
@required this.provider,
@required this.sourceAmount,
@required this.sourceCurrency,
@required this.destAmount,
@required this.destCurrency,
@required this.onTap
});
final BuyProvider selectedProvider;
final BuyProvider provider;
final double sourceAmount;
final FiatCurrency sourceCurrency;
final double destAmount;
final CryptoCurrency destCurrency;
final void Function() onTap;
@override
Widget build(BuildContext context) {
final isSelected = selectedProvider?.description == provider.description;
final providerIcon = getBuyProviderIcon(provider.description,
isWhiteIconColor: isSelected);
final backgroundColor = isSelected
? Palette.greyBlueCraiola
: Palette.shadowWhite;
final primaryTextColor = isSelected
? Colors.white
: Palette.darkGray;
final secondaryTextColor = isSelected
? Colors.white
: Palette.darkBlueCraiola;
return GestureDetector(
onTap: () => onTap?.call(),
child: Container(
height: 102,
padding: EdgeInsets.only(
left: 20,
//top: 33,
right: 20
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(25)),
color: backgroundColor
),
child: Stack(
children: [
Positioned(
top: 33,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (providerIcon != null) Padding(
padding: EdgeInsets.only(right: 10),
child: providerIcon
),
Text(
provider.description.title,
style: TextStyle(
color: secondaryTextColor,
fontSize: 20,
fontWeight: FontWeight.bold
),
)
],
),
Text(
'${destAmount?.toString()} ${destCurrency.title}',
style: TextStyle(
color: secondaryTextColor,
fontSize: 20,
fontWeight: FontWeight.bold
),
),
],
)
),
Positioned(
top: 65,
right: 0,
child: Text(
'${sourceAmount?.toString()} ${sourceCurrency.title}',
style: TextStyle(
color: primaryTextColor,
fontSize: 16,
fontWeight: FontWeight.bold
),
),
)
],
)
)
);
}
}

@ -132,29 +132,12 @@ class DashboardPage extends BasePage {
image: exchangeImage,
title: S.of(context).exchange,
route: Routes.exchange),
Observer(
builder: (_) => Stack(
clipBehavior: Clip.none,
alignment: Alignment.topCenter,
children: [
if (walletViewModel.isRunningWebView)
Positioned(
top: -5,
child: SpinKitRing(
color: Theme.of(context).buttonColor,
lineWidth: 3,
size: 70.0,
),
),
ActionButton(
image: buyImage,
title: S.of(context).buy,
onClick: walletViewModel.isRunningWebView
? null
: () async =>
await _onClickBuyButton(context))
],
)),
ActionButton(
image: buyImage,
title: S.of(context).buy,
onClick: () async =>
await _onClickBuyButton(context),
),
],
),
)
@ -167,7 +150,8 @@ class DashboardPage extends BasePage {
return;
}
pages.add(AddressPage(addressListViewModel: addressListViewModel));
pages.add(AddressPage(addressListViewModel: addressListViewModel,
walletViewModel: walletViewModel));
pages.add(BalancePage(dashboardViewModel: walletViewModel));
pages.add(TransactionsPage(dashboardViewModel: walletViewModel));
@ -183,7 +167,7 @@ class DashboardPage extends BasePage {
return AlertWithOneAction(
alertTitle: S.of(context).pre_seed_title,
alertContent:
S.of(context).outdated_electrum_wallet_desceription,
S.of(context).outdated_electrum_wallet_description,
buttonText: S.of(context).understand,
buttonAction: () => Navigator.of(context).pop());
});
@ -196,17 +180,7 @@ class DashboardPage extends BasePage {
final walletType = walletViewModel.type;
switch (walletType) {
case WalletType.bitcoin:
try {
walletViewModel.isRunningWebView = true;
final url = await walletViewModel.wyreViewModel.wyreUrl;
await Navigator.of(context).pushNamed(Routes.wyre, arguments: url);
walletViewModel.isRunningWebView = false;
} catch (_) {
walletViewModel.isRunningWebView = false;
}
break;
default:
case WalletType.monero:
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
@ -217,6 +191,9 @@ class DashboardPage extends BasePage {
buttonAction: () => Navigator.of(context).pop());
});
break;
default:
Navigator.of(context).pushNamed(Routes.preOrder);
break;
}
}
}

@ -1,5 +1,11 @@
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.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/settings_store.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart';
@ -7,17 +13,43 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart';
class AddressPage extends StatelessWidget {
AddressPage({@required this.addressListViewModel})
AddressPage({@required this.addressListViewModel,
this.walletViewModel})
: _cryptoAmountFocus = FocusNode();
final WalletAddressListViewModel addressListViewModel;
final DashboardViewModel walletViewModel;
final FocusNode _cryptoAmountFocus;
@override
Widget build(BuildContext context) {
autorun((_) async {
if (!walletViewModel.isOutdatedElectrumWallet
|| !walletViewModel.settingsStore.shouldShowReceiveWarning) {
return;
}
await Future<void>.delayed(Duration(seconds: 1));
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle: S.of(context).pre_seed_title,
alertContent: S.of(context).outdated_electrum_wallet_receive_warning,
leftButtonText: S.of(context).understand,
actionLeftButton: () => Navigator.of(context).pop(),
rightButtonText: S.of(context).do_not_show_me,
actionRightButton: () {
walletViewModel.settingsStore.setShouldShowReceiveWarning(false);
Navigator.of(context).pop();
});
});
});
return KeyboardActions(
autoScroll: false,
disableScroll: true,
@ -42,7 +74,8 @@ class AddressPage extends StatelessWidget {
child: Observer(builder: (_) => QRWidget(
addressListViewModel: addressListViewModel,
amountTextFieldFocusNode: _cryptoAmountFocus,
isAmountFieldShow: !addressListViewModel.hasAccounts))
isAmountFieldShow: !addressListViewModel.hasAccounts,
isBright: walletViewModel.settingsStore.currentTheme.type == ThemeType.bright))
),
Observer(builder: (_) {
return addressListViewModel.hasAddressList

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:auto_size_text/auto_size_text.dart';

@ -1,22 +1,33 @@
import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/store/settings_store.dart';
class OrderRow extends StatelessWidget {
OrderRow({
@required this.onTap,
@required this.provider,
this.from,
this.to,
this.createdAtFormattedDate,
this.formattedAmount});
final VoidCallback onTap;
final BuyProviderDescription provider;
final String from;
final String to;
final String createdAtFormattedDate;
final String formattedAmount;
final wyreImage =
Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
@override
Widget build(BuildContext context) {
final currentTheme = getIt.get<SettingsStore>().currentTheme;
final isWhiteIconColor = currentTheme.type != ThemeType.light;
final providerIcon = getBuyProviderIcon(provider,
isWhiteIconColor: isWhiteIconColor);
return InkWell(
onTap: onTap,
child: Container(
@ -26,8 +37,10 @@ class OrderRow extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
wyreImage,
SizedBox(width: 12),
if (providerIcon != null) Padding(
padding: EdgeInsets.only(right: 12),
child: providerIcon,
),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,

@ -84,6 +84,7 @@ class TransactionsPage extends StatelessWidget {
onTap: () => Navigator.of(context).pushNamed(
Routes.orderDetails,
arguments: order),
provider: order.provider,
from: order.from,
to: order.to,
createdAtFormattedDate:

@ -52,7 +52,7 @@ class ExchangePage extends BasePage {
Color get titleColor => Colors.white;
@override
bool get resizeToAvoidBottomPadding => false;
bool get resizeToAvoidBottomInset => false;
@override
bool get extendBodyBehindAppBar => true;

@ -37,7 +37,7 @@ class ExchangeTemplatePage extends BasePage {
Color get titleColor => Colors.white;
@override
bool get resizeToAvoidBottomPadding => false;
bool get resizeToAvoidBottomInset => false;
@override
bool get extendBodyBehindAppBar => true;
@ -176,7 +176,7 @@ class ExchangeTemplatePage extends BasePage {
initialIsAddressEditable:
exchangeViewModel.isReceiveAddressEnabled,
isAmountEstimated: true,
currencies: CryptoCurrency.all,
currencies: exchangeViewModel.receiveCurrencies,
onCurrencySelected: (currency) =>
exchangeViewModel.changeReceiveCurrency(
currency: currency),

@ -45,6 +45,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
color: Palette.darkBlueCraiola,
);
final int crossAxisCount = 3;
final int maxNumberItemsInAlert = 12;
final int itemsCount;
final double backgroundHeight = 280;
final double thumbHeight = 72;
@ -148,6 +149,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
);
})
),
if (itemsCount > maxNumberItemsInAlert)
CakeScrollbar(
backgroundHeight: backgroundHeight,
thumbHeight: thumbHeight,

@ -98,6 +98,12 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
showInformation(widget.exchangeTradeViewModel, context);
}
@override
void dispose() {
super.dispose();
widget.exchangeTradeViewModel.timer?.cancel();
}
@override
Widget build(BuildContext context) {
final copyImage = Image.asset('assets/images/copy_content.png',

@ -19,7 +19,33 @@ class OrderDetailsPage extends BasePage {
final OrderDetailsViewModel orderDetailsViewModel;
@override
Widget body(BuildContext context) {
Widget body(BuildContext context) =>
OrderDetailsPageBody(orderDetailsViewModel);
}
class OrderDetailsPageBody extends StatefulWidget {
OrderDetailsPageBody(this.orderDetailsViewModel);
final OrderDetailsViewModel orderDetailsViewModel;
@override
OrderDetailsPageBodyState createState() =>
OrderDetailsPageBodyState(orderDetailsViewModel);
}
class OrderDetailsPageBodyState extends State<OrderDetailsPageBody> {
OrderDetailsPageBodyState(this.orderDetailsViewModel);
final OrderDetailsViewModel orderDetailsViewModel;
@override
void dispose() {
super.dispose();
orderDetailsViewModel.timer?.cancel();
}
@override
Widget build(BuildContext context) {
return Observer(builder: (_) {
return SectionStandardList(
sectionCount: 1,
@ -44,4 +70,5 @@ class OrderDetailsPage extends BasePage {
});
});
}
}

@ -1,6 +1,7 @@
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -34,6 +35,9 @@ class ReceivePage extends BasePage {
@override
Color get backgroundDarkColor => Colors.transparent;
@override
bool get resizeToAvoidBottomInset => false;
final FocusNode _cryptoAmountFocus;
@override
@ -124,7 +128,8 @@ class ReceivePage extends BasePage {
child: QRWidget(
addressListViewModel: addressListViewModel,
isAmountFieldShow: true,
amountTextFieldFocusNode: _cryptoAmountFocus),
amountTextFieldFocusNode: _cryptoAmountFocus,
isBright: currentTheme.type == ThemeType.bright),
),
Observer(
builder: (_) => ListView.separated(

@ -13,7 +13,8 @@ class QRWidget extends StatelessWidget {
QRWidget(
{@required this.addressListViewModel,
this.isAmountFieldShow = false,
this.amountTextFieldFocusNode})
this.amountTextFieldFocusNode,
this.isBright})
: amountController = TextEditingController(),
_formKey = GlobalKey<FormState>() {
amountController.addListener(() => addressListViewModel.amount =
@ -25,6 +26,7 @@ class QRWidget extends StatelessWidget {
final TextEditingController amountController;
final FocusNode amountTextFieldFocusNode;
final GlobalKey<FormState> _formKey;
final bool isBright;
@override
Widget build(BuildContext context) {
@ -55,7 +57,7 @@ class QRWidget extends StatelessWidget {
),
child: QrImage(
data: addressListViewModel.uri.toString(),
backgroundColor: Colors.transparent,
backgroundColor: isBright ? Colors.black : Colors.transparent,
foregroundColor: Theme.of(context).accentTextTheme.
display3.backgroundColor,
),

@ -67,7 +67,7 @@ class SendPage extends BasePage {
Color get titleColor => Colors.white;
@override
bool get resizeToAvoidBottomPadding => false;
bool get resizeToAvoidBottomInset => false;
@override
bool get extendBodyBehindAppBar => true;

@ -34,7 +34,7 @@ class SendTemplatePage extends BasePage {
Color get titleColor => Colors.white;
@override
bool get resizeToAvoidBottomPadding => false;
bool get resizeToAvoidBottomInset => false;
@override
bool get extendBodyBehindAppBar => true;

@ -19,7 +19,33 @@ class TradeDetailsPage extends BasePage {
final TradeDetailsViewModel tradeDetailsViewModel;
@override
Widget body(BuildContext context) {
Widget body(BuildContext context) =>
TradeDetailsPageBody(tradeDetailsViewModel);
}
class TradeDetailsPageBody extends StatefulWidget {
TradeDetailsPageBody(this.tradeDetailsViewModel);
final TradeDetailsViewModel tradeDetailsViewModel;
@override
TradeDetailsPageBodyState createState() =>
TradeDetailsPageBodyState(tradeDetailsViewModel);
}
class TradeDetailsPageBodyState extends State<TradeDetailsPageBody> {
TradeDetailsPageBodyState(this.tradeDetailsViewModel);
final TradeDetailsViewModel tradeDetailsViewModel;
@override
void dispose() {
super.dispose();
tradeDetailsViewModel.timer?.cancel();
}
@override
Widget build(BuildContext context) {
return Observer(builder: (_) {
return SectionStandardList(
sectionCount: 1,
@ -44,4 +70,5 @@ class TradeDetailsPage extends BasePage {
});
});
}
}

@ -26,7 +26,8 @@ class BaseTextFormField extends StatelessWidget {
this.placeholderTextStyle,
this.maxLength,
this.focusNode,
this.initialValue});
this.initialValue,
this.borderWidth = 1.0});
final TextEditingController controller;
final TextInputType keyboardType;
@ -52,6 +53,7 @@ class BaseTextFormField extends StatelessWidget {
final bool readOnly;
final bool enableInteractiveSelection;
final String initialValue;
final double borderWidth;
@override
Widget build(BuildContext context) {
@ -88,17 +90,17 @@ class BaseTextFormField extends StatelessWidget {
borderSide: BorderSide(
color: borderColor ??
Theme.of(context).primaryTextTheme.title.backgroundColor,
width: 1.0)),
width: borderWidth)),
disabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ??
Theme.of(context).primaryTextTheme.title.backgroundColor,
width: 1.0)),
width: borderWidth)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: borderColor ??
Theme.of(context).primaryTextTheme.title.backgroundColor,
width: 1.0))),
width: borderWidth))),
validator: validator,
);
}

@ -1,5 +1,5 @@
import 'dart:async';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';

@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:package_info/package_info.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -18,6 +17,7 @@ import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/entities/node.dart';
import 'package:cake_wallet/entities/monero_transaction_priority.dart';
import 'package:cake_wallet/entities/action_list_display_mode.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
part 'settings_store.g.dart';
@ -147,6 +147,12 @@ abstract class SettingsStoreBase with Store {
bool isBitcoinBuyEnabled;
bool get shouldShowReceiveWarning =>
_sharedPreferences.getBool(PreferencesKey.shouldShowReceiveWarning) ?? true;
Future<void> setShouldShowReceiveWarning(bool value) async =>
_sharedPreferences.setBool(PreferencesKey.shouldShowReceiveWarning, value);
static Future<SettingsStore> load(
{@required Box<Node> nodeSource,
@required bool isBitcoinBuyEnabled,
@ -242,8 +248,13 @@ abstract class SettingsStoreBase with Store {
BitcoinTransactionPriority.medium,
BalanceDisplayMode initialBalanceDisplayMode =
BalanceDisplayMode.availableBalance}) async {
final isBitcoinBuyEnabled = (secrets.wyreSecretKey?.isNotEmpty ?? false) &&
(secrets.wyreApiKey?.isNotEmpty ?? false) &&
(secrets.wyreAccountId?.isNotEmpty ?? false);
final settings = await SettingsStoreBase.load(
nodeSource: nodeSource,
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
initialBalanceDisplayMode: initialBalanceDisplayMode,
initialFiatCurrency: initialFiatCurrency,
initialMoneroTransactionPriority: initialMoneroTransactionPriority,

@ -2,8 +2,11 @@ import 'package:flushbar/flushbar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Future<T> showBar<T>(BuildContext context, String text,
{bool isDark = false, Duration duration = const Duration(seconds: 1), bool isDismissible = true}) {
Future<T> showBar<T>(BuildContext context, String messageText,
{bool isDark = false,
Duration duration = const Duration(seconds: 1),
bool isDismissible = true,
String titleText}) {
final bar = Flushbar<T>(
boxShadows: [
BoxShadow(
@ -14,9 +17,14 @@ Future<T> showBar<T>(BuildContext context, String text,
backgroundColor: isDark ? Colors.black : Colors.white,
borderRadius: 35,
margin: EdgeInsets.all(50),
messageText: Text(text,
titleText: titleText != null
? Text(titleText,
textAlign: TextAlign.center,
style: TextStyle(color: isDark ? Colors.white : Colors.black, fontWeight: FontWeight.bold, fontSize: 24.0))
: null,
messageText: Text(messageText,
textAlign: TextAlign.center,
style: TextStyle(color: isDark ? Colors.white : Colors.black)),
style: TextStyle(color: isDark ? Colors.white : Colors.black, fontSize: 16)),
duration: duration,
isDismissible: isDismissible,
flushbarPosition: FlushbarPosition.TOP,

@ -0,0 +1,28 @@
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
part 'buy_amount_view_model.g.dart';
class BuyAmountViewModel = BuyAmountViewModelBase with _$BuyAmountViewModel;
abstract class BuyAmountViewModelBase with Store {
BuyAmountViewModelBase() : amount = '';
@observable
String amount;
FiatCurrency get fiatCurrency => FiatCurrency.usd;
@computed
double get doubleAmount {
double _amount;
try {
_amount = double.parse(amount.replaceAll(',', '.')) ?? 0.0;
} catch (e) {
_amount = 0.0;
}
return _amount;
}
}

@ -0,0 +1,29 @@
import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
class BuyItem {
BuyItem({this.provider, this.buyAmountViewModel});
final BuyProvider provider;
final BuyAmountViewModel buyAmountViewModel;
double get amount => buyAmountViewModel.doubleAmount;
FiatCurrency get fiatCurrency => buyAmountViewModel.fiatCurrency;
Future<BuyAmount> get buyAmount async {
BuyAmount _buyAmount;
try {
_buyAmount = await provider
.calculateAmount(amount?.toString(), fiatCurrency.title);
} catch (e) {
_buyAmount = BuyAmount(sourceAmount: 0.0, destAmount: 0.0);
print(e.toString());
}
return _buyAmount;
}
}

@ -0,0 +1,114 @@
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
import 'package:cake_wallet/entities/crypto_currency.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/buy/buy_item.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'buy_amount_view_model.dart';
part 'buy_view_model.g.dart';
class BuyViewModel = BuyViewModelBase with _$BuyViewModel;
abstract class BuyViewModelBase with Store {
BuyViewModelBase(this.ordersSource, this.ordersStore, this.settingsStore,
this.buyAmountViewModel, {@required this.wallet}) {
_fetchBuyItems();
isRunning = false;
isDisabled = true;
isShowProviderButtons = false;
}
final Box<Order> ordersSource;
final OrdersStore ordersStore;
final SettingsStore settingsStore;
final BuyAmountViewModel buyAmountViewModel;
final WalletBase wallet;
@observable
BuyProvider selectedProvider;
@observable
List<BuyItem> items;
@observable
bool isRunning;
@observable
bool isDisabled;
@observable
bool isShowProviderButtons;
WalletType get type => wallet.type;
double get doubleAmount => buyAmountViewModel.doubleAmount;
FiatCurrency get fiatCurrency => buyAmountViewModel.fiatCurrency;
CryptoCurrency get cryptoCurrency => walletTypeToCryptoCurrency(type);
Future <String> fetchUrl() async {
String _url = '';
try {
_url = await selectedProvider
?.requestUrl(doubleAmount?.toString(), fiatCurrency.title);
} catch (e) {
print(e.toString());
}
return _url;
}
Future<void> saveOrder(String orderId) async {
try {
final order = await selectedProvider?.findOrderById(orderId);
order.from = fiatCurrency.title;
order.to = cryptoCurrency.title;
await ordersSource.add(order);
ordersStore.setOrder(order);
} catch (e) {
print(e.toString());
}
}
void reset() {
buyAmountViewModel.amount = '';
selectedProvider = null;
}
Future<void> _fetchBuyItems() async {
final List<BuyProvider> _providerList = [];
if (wallet.type == WalletType.bitcoin) {
_providerList.add(WyreBuyProvider(wallet: wallet));
}
var isMoonPayEnabled = false;
try {
isMoonPayEnabled = await MoonPayBuyProvider.onEnabled();
} catch (e) {
isMoonPayEnabled = false;
print(e.toString());
}
if (isMoonPayEnabled) {
_providerList.add(MoonPayBuyProvider(wallet: wallet));
}
items = _providerList.map((provider) =>
BuyItem(provider: provider, buyAmountViewModel: buyAmountViewModel))
.toList();
}
}

@ -1,6 +1,9 @@
import 'package:cake_wallet/core/transaction_history.dart';
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/entities/push_notifications_service.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/transaction_history.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/monero/account.dart';
import 'package:cake_wallet/monero/monero_balance.dart';
import 'package:cake_wallet/monero/monero_transaction_info.dart';
@ -17,7 +20,9 @@ import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/action_list_display_mode.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/services.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/wallet_base.dart';
@ -42,9 +47,9 @@ abstract class DashboardViewModelBase with Store {
this.tradeFilterStore,
this.transactionFilterStore,
this.settingsStore,
this.ordersSource,
this.ordersStore,
this.wyreViewModel}) {
PushNotificationsService pushNotificationsService}) {
_pushNotificationsService = pushNotificationsService;
filterItems = {
S.current.transactions: [
FilterItem(
@ -79,8 +84,6 @@ abstract class DashboardViewModelBase with Store {
]
};
isRunningWebView = false;
name = appStore.wallet?.name;
wallet ??= appStore.wallet;
type = wallet.type;
@ -133,6 +136,8 @@ abstract class DashboardViewModelBase with Store {
return true;
});
Future.delayed(Duration(seconds: 2), () => _pushNotificationsService.init());
}
@observable
@ -147,9 +152,6 @@ abstract class DashboardViewModelBase with Store {
@observable
String subname;
@observable
bool isRunningWebView;
@computed
String get address => wallet.address;
@ -205,8 +207,6 @@ abstract class DashboardViewModelBase with Store {
bool get hasRescan => wallet.type == WalletType.monero;
Box<Order> ordersSource;
BalanceViewModel balanceViewModel;
AppStore appStore;
@ -221,24 +221,24 @@ abstract class DashboardViewModelBase with Store {
TransactionFilterStore transactionFilterStore;
WyreViewModel wyreViewModel;
Map<String, List<FilterItem>> filterItems;
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
PushNotificationsService _pushNotificationsService;
ReactionDisposer _onMoneroAccountChangeReaction;
ReactionDisposer _onMoneroBalanceChangeReaction;
@observable
bool isOutdatedElectrumWallet;
Future<void> reconnect() async {
final node = appStore.settingsStore.getCurrentNode(wallet.type);
await wallet.connectToNode(node: node);
}
@observable
bool isOutdatedElectrumWallet;
@action
void _onWalletChange(
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,

@ -1,4 +1,4 @@
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';

@ -45,7 +45,7 @@ abstract class ExchangeTradeViewModelBase with Store {
_updateTrade();
_timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateTrade());
timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateTrade());
}
final WalletBase wallet;
@ -71,7 +71,7 @@ abstract class ExchangeTradeViewModelBase with Store {
ExchangeProvider _provider;
Timer _timer;
Timer timer;
@action
Future confirmSending() async {

@ -1,12 +1,16 @@
import 'dart:async';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/utils/date_formatter.dart';
import 'package:cake_wallet/view_model/wyre_view_model.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
part 'order_details_view_model.g.dart';
@ -14,16 +18,27 @@ class OrderDetailsViewModel = OrderDetailsViewModelBase
with _$OrderDetailsViewModel;
abstract class OrderDetailsViewModelBase with Store {
OrderDetailsViewModelBase({this.wyreViewModel, Order orderForDetails}) {
OrderDetailsViewModelBase({WalletBase wallet, Order orderForDetails}) {
order = orderForDetails;
if (order.provider != null) {
switch (order.provider) {
case BuyProviderDescription.wyre:
_provider = WyreBuyProvider(wallet: wallet);
break;
case BuyProviderDescription.moonPay:
_provider = MoonPayBuyProvider(wallet: wallet);
break;
}
}
items = ObservableList<StandartListItem>();
_updateItems();
_updateOrder();
_timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
}
@observable
@ -32,21 +47,25 @@ abstract class OrderDetailsViewModelBase with Store {
@observable
ObservableList<StandartListItem> items;
WyreViewModel wyreViewModel;
BuyProvider _provider;
Timer _timer;
Timer timer;
@action
Future<void> _updateOrder() async {
try {
final updatedOrder =
await wyreViewModel.wyreService.findOrderById(order.id);
updatedOrder.receiveAddress = order.receiveAddress;
updatedOrder.walletId = order.walletId;
order = updatedOrder;
_updateItems();
if (_provider != null) {
final updatedOrder = await _provider.findOrderById(order.id);
updatedOrder.from = order.from;
updatedOrder.to = order.to;
updatedOrder.receiveAddress = order.receiveAddress;
updatedOrder.walletId = order.walletId;
if (order.provider != null) {
updatedOrder.providerRaw = order.provider.raw;
}
order = updatedOrder;
_updateItems();
}
} catch (e) {
print(e.toString());
}
@ -54,8 +73,6 @@ abstract class OrderDetailsViewModelBase with Store {
void _updateItems() {
final dateFormat = DateFormatter.withCurrentLocal();
final buildURL =
wyreViewModel.trackUrl + '${order.transferId}';
items?.clear();
@ -68,18 +85,37 @@ abstract class OrderDetailsViewModelBase with Store {
value: order.state != null
? order.state.toString()
: S.current.trade_details_fetching),
TrackTradeListItem(
title: 'Track',
value: buildURL,
onTap: () {
launch(buildURL);
}),
StandartListItem(
title: S.current.trade_details_created_at,
value: dateFormat.format(order.createdAt).toString()),
StandartListItem(
title: S.current.trade_details_pair,
value: '${order.from}${order.to}')
]);
if (order.provider != null) {
items.add(
StandartListItem(
title: 'Buy provider',
value: order.provider.title)
);
}
if (_provider?.trackUrl?.isNotEmpty ?? false) {
final buildURL = _provider.trackUrl + '${order.transferId}';
items.add(
TrackTradeListItem(
title: 'Track',
value: buildURL,
onTap: () => launch(buildURL)
)
);
}
items.add(
StandartListItem(
title: S.current.trade_details_created_at,
value: dateFormat.format(order.createdAt).toString())
);
items.add(
StandartListItem(
title: S.current.trade_details_pair,
value: '${order.from}${order.to}')
);
}
}

@ -24,6 +24,15 @@ abstract class SupportViewModelBase with Store {
title: 'Email',
linkTitle: 'support@cakewallet.com',
link: 'mailto:support@cakewallet.com'),
LinkListItem(
title: 'Website',
linkTitle: 'cakewallet.com',
link: 'https://cakewallet.com'),
LinkListItem(
title: 'GitHub',
icon: 'assets/images/github.png',
linkTitle: S.current.apk_update,
link: 'https://github.com/cake-tech/cake_wallet/releases'),
LinkListItem(
title: 'Telegram',
icon: 'assets/images/Telegram.png',

@ -39,7 +39,7 @@ abstract class TradeDetailsViewModelBase with Store {
_updateTrade();
_timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateTrade());
timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateTrade());
}
final Box<Trade> trades;
@ -52,7 +52,7 @@ abstract class TradeDetailsViewModelBase with Store {
ExchangeProvider _provider;
Timer _timer;
Timer timer;
@action
Future<void> _updateTrade() async {

@ -1,11 +1,14 @@
import 'package:cake_wallet/bitcoin/electrum_transaction_info.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/transaction_info.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/monero/monero_transaction_info.dart';
import 'package:cake_wallet/monero/monero_wallet.dart';
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
import 'package:cake_wallet/src/screens/transaction_details/textfield_list_item.dart';
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
import 'package:cake_wallet/src/screens/transaction_details/blockexplorer_list_item.dart';
import 'package:cake_wallet/entities/transaction_direction.dart';
import 'package:cake_wallet/utils/date_formatter.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:hive/hive.dart';
@ -23,6 +26,7 @@ abstract class TransactionDetailsViewModelBase with Store {
TransactionDetailsViewModelBase(
{this.transactionInfo,
this.transactionDescriptionBox,
this.wallet,
this.settingsStore})
: items = [] {
showRecipientAddress = settingsStore?.shouldSaveRecipientAddress ?? false;
@ -51,6 +55,25 @@ abstract class TransactionDetailsViewModelBase with Store {
StandartListItem(title: S.current.transaction_key, value: tx.key));
}
if ((tx.direction == TransactionDirection.incoming)&&
(wallet is MoneroWallet)) {
try {
final accountIndex = tx.accountIndex;
final addressIndex = tx.addressIndex;
final _wallet = wallet as MoneroWallet;
final address =
_wallet.getTransactionAddress(accountIndex, addressIndex);
if (address?.isNotEmpty ?? false) {
_items.add(
StandartListItem(
title: S.current.transaction_details_recipient_address,
value: address));
}
} catch (e) {
print(e.toString());
}
}
items.addAll(_items);
}
@ -124,6 +147,7 @@ abstract class TransactionDetailsViewModelBase with Store {
final TransactionInfo transactionInfo;
final Box<TransactionDescription> transactionDescriptionBox;
final SettingsStore settingsStore;
final WalletBase wallet;
final List<TransactionDetailsListItem> items;
bool showRecipientAddress;

@ -1,34 +0,0 @@
import 'package:cake_wallet/entities/wyre_service.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:cake_wallet/entities/order.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:mobx/mobx.dart';
part 'wyre_view_model.g.dart';
class WyreViewModel = WyreViewModelBase with _$WyreViewModel;
abstract class WyreViewModelBase with Store {
WyreViewModelBase(this.ordersSource, this.ordersStore,
{@required this.wyreService});
Future<String> get wyreUrl => wyreService.getWyreUrl();
String get trackUrl => wyreService.trackUrl;
final Box<Order> ordersSource;
final OrdersStore ordersStore;
final WyreService wyreService;
Future<void> saveOrder(String orderId) async {
try {
final order = await wyreService.findOrderById(orderId);
await ordersSource.add(order);
ordersStore.setOrder(order);
} catch (e) {
print(e.toString());
}
}
}

@ -362,6 +362,34 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0-nullsafety.2"
firebase_core:
dependency: transitive
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.3"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1+1"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
url: "https://pub.dartlang.org"
source: hosted
version: "7.0.3"
fixnum:
dependency: transitive
description:
@ -565,7 +593,7 @@ packages:
name: local_auth
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
version: "1.1.6"
logging:
dependency: transitive
description:

@ -11,7 +11,7 @@ description: Cake Wallet.
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 4.2.0+49
version: 4.2.3+53
environment:
sdk: ">=2.7.0 <3.0.0"
@ -49,7 +49,7 @@ dependencies:
path: ./cw_monero
hive: ^1.4.4+1
hive_flutter: ^0.3.1
local_auth: ^1.1.1
local_auth: ^1.1.6
package_info: ^2.0.0
devicelocale: ^0.4.1
auto_size_text: ^2.1.0
@ -78,6 +78,7 @@ dependencies:
file_picker: ^3.0.0-nullsafety.2
unorm_dart: ^0.2.0
permission_handler: ^5.0.1+1
firebase_messaging: ^7.0.3
dev_dependencies:
flutter_test:
@ -151,4 +152,4 @@ flutter:
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
# see https://flutter.dev/custom-fonts/#from-packages

@ -1,8 +1,8 @@
{
"welcome" : "Willkommen zu",
"welcome" : "Willkommen bei",
"cake_wallet" : "Cake Wallet",
"first_wallet_text" : "tolle Brieftasche zum Monero und Bitcoin",
"please_make_selection" : "Bitte treffen Sie unten eine Auswahl zu Erstellen oder Wiederherstellen Ihrer Brieftasche.",
"first_wallet_text" : "Eine großartige Wallet für Monero und Bitcoin",
"please_make_selection" : "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.",
"create_new" : "Neue Wallet erstellen",
"restore_wallet" : "Wallet wiederherstellen",
@ -18,9 +18,9 @@
"please_select" : "Bitte auswählen:",
"cancel" : "Abbrechen",
"ok" : "OK",
"contact_name" : "Name des Ansprechpartners",
"contact_name" : "Name des Kontakts",
"reset" : "Zurücksetzen",
"save" : "speichern",
"save" : "Speichern",
"address_remove_contact" : "Kontakt entfernen",
"address_remove_content" : "Sind Sie sicher, dass Sie den ausgewählten Kontakt entfernen möchten?",
@ -30,88 +30,88 @@
"failed_authentication" : "Authentifizierung fehlgeschlagen. ${state_error}",
"wallet_menu" : "Brieftaschen-Menü",
"Blocks_remaining" : "${status} Verbleibende Blöcke",
"please_try_to_connect_to_another_node" : "Bitte versuchen Sie, eine Verbindung zu einem anderen Knoten herzustellen",
"wallet_menu" : "Wallet-Menü",
"Blocks_remaining" : "${status} verbleibende Blöcke",
"please_try_to_connect_to_another_node" : "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden",
"xmr_hidden" : "Versteckt",
"xmr_available_balance" : "Verfügbares Guthaben",
"xmr_full_balance" : "Volle Balance",
"xmr_full_balance" : "Gesamtguthaben",
"send" : "Senden",
"receive" : "Erhalten",
"receive" : "Empfangen",
"transactions" : "Transaktionen",
"incoming" : "Eingehend",
"outgoing" : "Ausgehend",
"transactions_by_date" : "Transaktionen nach Datum",
"trades" : "Handel",
"trades" : "Börsen",
"filters" : "Filter",
"today" : "Heute",
"yesterday" : "Gestern",
"received" : "Empfangen",
"sent" : "Geschickt",
"pending" : " (steht aus)",
"sent" : "Versendet",
"pending" : " (ausstehend)",
"rescan" : "Erneut scannen",
"reconnect" : "Erneut verbinden",
"wallets" : "Wallets",
"show_seed" : "Seed zeigen",
"show_keys" : "Samen/Schlüssel anzeigen",
"show_keys" : "Seed/Schlüssel anzeigen",
"address_book_menu" : "Adressbuch",
"reconnection" : "Wiederverbindung",
"reconnect_alert_text" : "Sind Sie sicher, dass Sie die Verbindung wiederherstellen möchten?",
"reconnection" : "Neu verbinden",
"reconnect_alert_text" : "Sind Sie sicher, dass Sie sich neu verbinden möchten?",
"exchange" : "Austausch",
"clear" : "klar",
"exchange" : "Umwechseln",
"clear" : "Zurücksetzen",
"refund_address" : "Rückerstattungsadresse",
"change_exchange_provider" : "Wechseln Sie den Exchange-Anbieter",
"change_exchange_provider" : "Exchange-Anbieter ändern",
"you_will_send" : "Konvertieren von",
"you_will_get" : "Konvertieren zu",
"amount_is_guaranteed" : "Der Empfangsbetrag ist garantiert",
"amount_is_estimate" : "Der empfangene Betrag ist eine Schätzung",
"powered_by" : "Unterstützt von ${title}",
"error" : "Error",
"powered_by" : "Ermöglicht durch ${title}",
"error" : "Fehler",
"estimated" : "Geschätzt",
"min_value" : "Mindest: ${value} ${currency}",
"min_value" : "Min: ${value} ${currency}",
"max_value" : "Max: ${value} ${currency}",
"change_currency" : "Währung ändern",
"copy_id" : "ID kopieren",
"exchange_result_write_down_trade_id" : "Bitte kopieren oder notieren Sie die Handel-ID, um fortzufahren.",
"trade_id" : "Handel-ID:",
"exchange_result_write_down_trade_id" : "Bitte kopieren oder notieren Sie die Handels-ID, um fortzufahren.",
"trade_id" : "Handels-ID:",
"copied_to_clipboard" : "In die Zwischenablage kopiert",
"saved_the_trade_id" : "Ich habe die Geschäfts-ID gespeichert",
"fetching" : "holen",
"saved_the_trade_id" : "Ich habe die Handels-ID gespeichert",
"fetching" : "Frage ab",
"id" : "ID: ",
"amount" : "Menge: ",
"payment_id" : "Zahlungs ID: ",
"amount" : "Betrag: ",
"payment_id" : "Zahlungs-ID: ",
"status" : "Status: ",
"offer_expires_in" : "Angebot läuft ab in: ",
"trade_is_powered_by" : "Dieser Handel wird betrieben von ${provider}",
"trade_is_powered_by" : "Dieser Handel wird angeboten von ${provider}",
"copy_address" : "Adresse kopieren",
"exchange_result_confirm" : "Durch Drücken von Bestätigen wird gesendet ${fetchingLabel} ${from} von Ihrer Brieftasche aus angerufen ${walletName} an die unten angegebene Adresse. Oder Sie können von Ihrem externen Portemonnaie an die unten angegebene Adresse / QR-Code senden.\n\nBitte bestätigen Sie, um fortzufahren, oder gehen Sie zurück, um die Beträge zu änderns.",
"exchange_result_confirm" : "Durch Drücken von \"Bestätigen\" wird ${fetchingLabel} ${from} von Ihrer Wallet namens ${walletName} an die unten angegebene Adresse gesendet. Alternativ können Sie von einer externen Wallet an die unten angegebene Adresse / QR-Code senden.\n\nBitte bestätigen Sie, um fortzufahren, oder gehen Sie zurück, um die Beträge zu ändern.",
"exchange_result_description" : "Sie müssen mindestens ${fetchingLabel} ${from} an die auf der nächsten Seite angegebene Adresse senden. Wenn Sie einen Betrag unter ${fetchingLabel} ${from} senden, wird dieser möglicherweise nicht konvertiert und möglicherweise nicht erstattet.",
"exchange_result_write_down_ID" : "*Bitte kopieren oder notieren Sie Ihren oben gezeigten Ausweis.",
"exchange_result_write_down_ID" : "*Bitte kopieren oder notieren Sie sich die oben gezeigte ID.",
"confirm" : "Bestätigen",
"confirm_sending" : "Bestätigen Sie das Senden",
"commit_transaction_amount_fee" : "Transaktion festschreiben\nMenge: ${amount}\nGebühr: ${fee}",
"confirm_sending" : "Senden bestätigen",
"commit_transaction_amount_fee" : "Transaktion absenden\nBetrag: ${amount}\nGebühr: ${fee}",
"sending" : "Senden",
"transaction_sent" : "Transaktion gesendet!",
"expired" : "Abgelaufen",
"time" : "${minutes}m ${seconds}s",
"send_xmr" : "Senden XMR",
"send_xmr" : "XMR senden",
"exchange_new_template" : "Neue Vorlage",
"faq" : "FAQ",
"faq" : "Häufig gestellte Fragen",
"enter_your_pin" : "PIN eingeben",
"loading_your_wallet" : "Laden Sie Ihre Brieftasche",
"loading_your_wallet" : "Wallet wird geladen",
"new_wallet" : "Neues Wallet",
"new_wallet" : "Neue Wallet",
"wallet_name" : "Walletname",
"continue_text" : "Fortsetzen",
"choose_wallet_currency" : "Bitte wählen Sie die Brieftaschenwährung:",
"continue_text" : "Weiter",
"choose_wallet_currency" : "Bitte wählen Sie die Währung der Wallet:",
"node_new" : "Neuer Knoten",
@ -121,27 +121,27 @@
"password" : "Passwort",
"nodes" : "Knoten",
"node_reset_settings_title" : "Einstellungen zurücksetzen",
"nodes_list_reset_to_default_message" : "Möchten Sie die Einstellungen wirklich auf die Standardeinstellungen zurücksetzen?",
"change_current_node" : "Möchten Sie den aktuellen Knoten wirklich auf ändern? ${node}?",
"change" : "Veränderung",
"nodes_list_reset_to_default_message" : "Möchten Sie wirklich die Standardeinstellungen wiederherstellen?",
"change_current_node" : "Möchten Sie den aktuellen Knoten wirklich zu ${node}? ändern?",
"change" : "Ändern",
"remove_node" : "Knoten entfernen",
"remove_node_message" : "Möchten Sie den ausgewählten Knoten wirklich entfernen?",
"remove" : "Löschen",
"remove" : "Entfernen",
"delete" : "Löschen",
"add_new_node" : "Neuen Knoten hinzufügen",
"change_current_node_title" : "Ändern Sie den aktuellen Knoten",
"change_current_node_title" : "Aktuellen Knoten ändern",
"node_test" : "Test",
"node_connection_successful" : "Die Verbindung war erfolgreich",
"node_connection_failed" : "Verbindung fehlgeschlagen",
"new_node_testing" : "Neuer Knotentest",
"new_node_testing" : "Neuen Knoten testen",
"use" : "Verwenden Sie ",
"digit_pin" : "-stelliger PIN",
"use" : "Wechsel zu ",
"digit_pin" : "-stellige PIN",
"share_address" : "Adresse teilen ",
"receive_amount" : "Menge",
"receive_amount" : "Betrag",
"subaddresses" : "Unteradressen",
"addresses" : "Adressen",
"scan_qr_code" : "Scannen Sie den QR-Code, um die Adresse zu erhalten",
@ -152,78 +152,78 @@
"restore_restore_wallet" : "Wallet wiederherstellen",
"restore_title_from_seed_keys" : "Vom Seed / Schlüssel wiederherstellen",
"restore_description_from_seed_keys" : "Holen Sie sich Ihr Wallet von Seed / Schlüsseln zurück, die Sie an einem sicheren Ort aufbewahrt haben",
"restore_next" : "Nächster",
"restore_title_from_seed_keys" : "Aus Seed/Schlüssel wiederherstellen",
"restore_description_from_seed_keys" : "Stellen Sie Ihr Wallet aus Seed/Schlüsseln wieder her, die Sie sicher aufbewahrt haben",
"restore_next" : "Weiter",
"restore_title_from_backup" : "Aus einer Sicherungsdatei wiederherstellen",
"restore_description_from_backup" : "Sie können die gesamte Cake Wallet-App von wiederherstellen Ihre Sicherungsdatei",
"restore_seed_keys_restore" : "Seed / Schlüssel wiederherstellen",
"restore_description_from_backup" : "Sie können die gesamte Cake Wallet-App aus Ihrer Sicherungsdatei wiederherstellen",
"restore_seed_keys_restore" : "Seed/Schlüssel wiederherstellen",
"restore_title_from_seed" : "Aus Seed wiederherstellen",
"restore_description_from_seed" : "Stellen Sie Ihr Wallet aus den 25 Wörtern wieder her oder 13-Wort-Kombinationscode",
"restore_title_from_keys" : "Wiederherstellen von Schlüsseln",
"restore_description_from_keys" : "Stellen Sie Ihr Wallet von generiert wieder her Tastenanschläge, die von Ihren privaten Schlüsseln gespeichert wurden",
"restore_description_from_seed" : "Stellen Sie Ihre Wallet aus den 25 Wörtern oder dem 13-Wort-Kombinationscode wieder her",
"restore_title_from_keys" : "Aus Schlüsseln wiederherstellen",
"restore_description_from_keys" : "Stellen Sie Ihr Wallet aus generierten Tastenanschlägen her, die von Ihren privaten Schlüsseln gespeichert wurden",
"restore_wallet_name" : "Walletname",
"restore_address" : "Adresse",
"restore_view_key_private" : "Schlüssel anzeigen(geheim)",
"restore_spend_key_private" : "Schlüssel ausgeben (geheim)",
"restore_recover" : "Genesen",
"restore_wallet_restore_description" : "Beschreibung zur Wiederherstellung der Brieftasche",
"restore_view_key_private" : "View Key (geheim)",
"restore_spend_key_private" : "Spend Key (geheim)",
"restore_recover" : "Wiederherstellen",
"restore_wallet_restore_description" : "Beschreibung zur Wallet-Wiederherstellung",
"restore_new_seed" : "Neuer Seed",
"restore_active_seed" : "Aktives Seed",
"restore_active_seed" : "Aktiver Seed",
"restore_bitcoin_description_from_seed" : "Stellen Sie Ihre Brieftasche aus dem 24-Wort-Kombinationscode wieder her",
"restore_bitcoin_description_from_keys" : "Stellen Sie Ihre Brieftasche aus der generierten WIF-Zeichenfolge aus Ihren privaten Schlüsseln wieder her",
"restore_bitcoin_title_from_keys" : "Aus WIF wiederherstellen",
"restore_from_date_or_blockheight" : "Bitte geben Sie einige Tage vor dem Erstellen dieser Brieftasche ein Datum ein. Oder wenn Sie die Blockhöhe kennen, geben Sie sie stattdessen ein",
"restore_from_date_or_blockheight" : "Bitte geben Sie ein Datum ein, das einige Tage vor dem Erstellen dieser Brieftasche liegt. Oder wenn Sie die Blockhöhe kennen, geben Sie stattdessen diese ein",
"seed_reminder" : "Bitte notieren Sie diese, falls Sie Ihr Telefon verlieren oder abwischen",
"seed_reminder" : "Bitte notieren Sie diese für den Fall, dass Sie Ihr Telefon verlieren oder es kaputtgeht",
"seed_title" : "Seed",
"seed_share" : "Teilen Sie Seed",
"seed_share" : "Seed teilen",
"copy" : "Kopieren",
"seed_language_choose" : "Bitte wählen Sie die Ausgangssprache:",
"seed_choose" : "Wählen Sie die Ausgangssprache",
"seed_language_next" : "Nächster",
"seed_language_choose" : "Bitte wählen Sie die Sprache des Seeds:",
"seed_choose" : "Seed-Sprache auswählen",
"seed_language_next" : "Weiter",
"seed_language_english" : "Englisch",
"seed_language_chinese" : "Chinesisch",
"seed_language_dutch" : "Niederländisch",
"seed_language_german" : "Deutsche",
"seed_language_german" : "Deutsch",
"seed_language_japanese" : "Japanisch",
"seed_language_portuguese" : "Portugiesisch",
"seed_language_russian" : "Russisch",
"seed_language_spanish" : "Spanisch",
"send_title" : "Senden Sie",
"send_your_wallet" : "Deine Geldbörse",
"send_title" : "Senden",
"send_your_wallet" : "Ihre Wallet",
"send_address" : "${cryptoCurrency}-Adresse",
"send_payment_id" : "Zahlungs ID (wahlweise)",
"all" : "ALLE",
"send_error_minimum_value" : "Der Mindestbetrag beträgt 0,01",
"send_error_currency" : "Die Währung kann nur Zahlen enthalten",
"send_payment_id" : "Zahlungs-ID (optional)",
"all" : "ALLES",
"send_error_minimum_value" : "Der Mindestbetrag ist 0,01",
"send_error_currency" : "Die Währung darf nur Zahlen enthalten",
"send_estimated_fee" : "Geschätzte Gebühr:",
"send_priority" : "Derzeit ist die Gebühr auf festgelegt ${transactionPriority} priorität.\nDie Transaktionspriorität kann in den Einstellungen angepasst werden",
"send_creating_transaction" : "Transaktion erstellen",
"send_priority" : "Derzeit ist ${transactionPriority} als Gebührenpriorität eingestellt.\nDie Transaktionspriorität kann in den Einstellungen angepasst werden",
"send_creating_transaction" : "Erstelle Transaktion",
"send_templates" : "Vorlagen",
"send_new" : "Neu",
"send_amount" : "Menge:",
"send_amount" : "Betrag:",
"send_fee" : "Gebühr:",
"send_name" : "Name",
"send_got_it" : "Ich habs",
"send_got_it" : "Verstanden",
"send_sending" : "Senden...",
"send_success" : "Ihr ${crypto} wurde erfolgreich gesendet",
"send_success" : "Ihr ${crypto} wurde erfolgreich versendet",
"settings_title" : "die Einstellungen",
"settings_title" : "Einstellungen",
"settings_nodes" : "Knoten",
"settings_current_node" : "Aktueller Knoten",
"settings_wallets" : "Brieftaschen",
"settings_display_balance_as" : "Kontostand anzeigen als",
"settings_wallets" : "Wallets",
"settings_display_balance_as" : "Kontostand anzeigen in",
"settings_currency" : "Währung",
"settings_fee_priority" : "Gebührenpriorität",
"settings_save_recipient_address" : "Empfängeradresse speichern",
"settings_personal" : "persönlich",
"settings_personal" : "Persönlich",
"settings_change_pin" : "PIN ändern",
"settings_change_language" : "Sprache ändern",
"settings_allow_biometrical_authentication" : "Biometrische Authentifizierung zulassen",
@ -232,10 +232,10 @@
"settings_trades" : "Handel",
"settings_display_on_dashboard_list" : "Anzeige in der Dashboard-Liste",
"settings_all" : "ALLE",
"settings_only_trades" : "Nur Trades",
"settings_only_trades" : "Nur Handel",
"settings_only_transactions" : "Nur Transaktionen",
"settings_none" : "Keiner",
"settings_support" : "Unterstützung",
"settings_support" : "Unterstützen",
"settings_terms_and_conditions" : "Geschäftsbedingungen",
"pin_is_incorrect" : "PIN ist falsch",
@ -245,61 +245,61 @@
"setup_successful" : "Ihre PIN wurde erfolgreich eingerichtet!",
"wallet_keys" : "Brieftaschensamen / Schlüssel",
"wallet_seed" : "Brieftaschensamen",
"private_key" : "Privat Schlüssel",
"wallet_keys" : "Wallet-Seed/-Schlüssel",
"wallet_seed" : "Wallet-Seed",
"private_key" : "Privater Schlüssel",
"public_key" : "Öffentlicher Schlüssel",
"view_key_private" : "Schlüssel anzeigen (eheim)",
"view_key_public" : "Schlüssel anzeigen (Öffentlichkeit)",
"spend_key_private" : "Schlüssel ausgeben (geheim)",
"spend_key_public" : "Schlüssel ausgeben (Öffentlichkeit)",
"copied_key_to_clipboard" : "Kopiert ${key} Zur Zwischenablage",
"view_key_private" : "View Key (geheim)",
"view_key_public" : "View Key (öffentlich)",
"spend_key_private" : "Spend Key (geheim)",
"spend_key_public" : "Spend Key (öffentlich)",
"copied_key_to_clipboard" : "${key} in Zwischenablage kopiert",
"new_subaddress_title" : "Neue Adresse",
"new_subaddress_label_name" : "Markenname",
"new_subaddress_label_name" : "Bezeichnung",
"new_subaddress_create" : "Erstellen",
"subaddress_title" : "Unteradressenliste",
"trade_details_title" : "Handel Einzelheiten",
"trade_details_title" : "Handelsdetails",
"trade_details_id" : "ID",
"trade_details_state" : "Zustand",
"trade_details_fetching" : "Holen",
"trade_details_state" : "Status",
"trade_details_fetching" : "Wird ermittelt",
"trade_details_provider" : "Anbieter",
"trade_details_created_at" : "Hergestellt in",
"trade_details_created_at" : "Erzeugt am",
"trade_details_pair" : "Paar",
"trade_details_copied" : "${title} in die Zwischenablage kopiert",
"trade_history_title" : "Handelsgeschichte",
"trade_history_title" : "Handelsverlauf",
"transaction_details_title" : "Transaktionsdetails",
"transaction_details_transaction_id" : "Transaktions-ID",
"transaction_details_date" : "Datum",
"transaction_details_height" : "Höhe",
"transaction_details_amount" : "Menge",
"transaction_details_amount" : "Betrag",
"transaction_details_fee" : "Gebühr",
"transaction_details_copied" : "${title} in die Zwischenablage kopiert",
"transaction_details_recipient_address" : "Empfängeradresse",
"wallet_list_title" : "Monero Wallet",
"wallet_list_title" : "Monero-Wallet",
"wallet_list_create_new_wallet" : "Neue Wallet erstellen",
"wallet_list_restore_wallet" : "Wallet wiederherstellen",
"wallet_list_load_wallet" : "Wallet einlegen",
"wallet_list_loading_wallet" : "Wird geladen ${wallet_name} Wallet",
"wallet_list_failed_to_load" : "Laden fehlgeschlagen ${wallet_name} Wallet. ${error}",
"wallet_list_removing_wallet" : "Entfernen ${wallet_name} Wallet",
"wallet_list_failed_to_remove" : "Fehler beim Entfernen ${wallet_name} Wallet. ${error}",
"wallet_list_load_wallet" : "Wallet laden",
"wallet_list_loading_wallet" : "Wallet ${wallet_name} wird geladen",
"wallet_list_failed_to_load" : "Laden der Wallet ${wallet_name} fehlgeschlagen. ${error}",
"wallet_list_removing_wallet" : "Wallet ${wallet_name} wird entfernt",
"wallet_list_failed_to_remove" : "Fehler beim Entfernen der Wallet ${wallet_name}. ${error}",
"widgets_address" : "Adresse",
"widgets_restore_from_blockheight" : "Aus Blockhöhe wiederherstellen",
"widgets_restore_from_date" : "Vom Datum wiederherstellen",
"widgets_restore_from_blockheight" : "Ab Blockhöhe wiederherstellen",
"widgets_restore_from_date" : "Ab Datum wiederherstellen",
"widgets_or" : "oder",
"widgets_seed" : "Seed",
@ -307,56 +307,56 @@
"router_no_route" : "Keine Route definiert für ${name}",
"error_text_account_name" : "Der Kontoname darf nur Wallet und Zahlen enthalten\nund muss zwischen 1 und 15 Zeichen lang sein",
"error_text_contact_name" : "Kontaktname darf nicht enthalten sein ` , ' \" Symbole\nund muss zwischen 1 und 32 Zeichen lang sein",
"error_text_address" : "Die Walletadresse muss dem Typ entsprechen\nder Kryptowährung",
"error_text_account_name" : "Der Kontoname darf nur Buchstaben und Zahlen enthalten\nund muss zwischen 1 und 15 Zeichen lang sein",
"error_text_contact_name" : "Kontaktname darf nicht die Zeichen ` , ' \" enthalten\nund muss zwischen 1 und 32 Zeichen lang sein",
"error_text_address" : "Die Walletadresse muss dem Typ der Kryptowährung\nentsprechen",
"error_text_node_address" : "Bitte geben Sie eine iPv4-Adresse ein",
"error_text_node_port" : "Der Knotenport kann nur Nummern zwischen 0 und 65535 enthalten",
"error_text_payment_id" : "Die Zahlungs-ID kann nur 16 bis 64 hexadezimale Zeichen enthalten",
"error_text_xmr" : "Der XMR-Wert kann das verfügbare Guthaben nicht überschreiten.\nDie Anzahl der Nachkommastellen muss kleiner oder gleich 12 sein",
"error_text_node_port" : "Der Knotenport darf nur Nummern zwischen 0 und 65535 enthalten",
"error_text_payment_id" : "Die Zahlungs-ID darf nur 16 bis 64 hexadezimale Zeichen enthalten",
"error_text_xmr" : "Der XMR-Wert darf das verfügbare Guthaben nicht überschreiten.\nDie Anzahl der Nachkommastellen muss kleiner oder gleich 12 sein",
"error_text_fiat" : "Der Wert des Betrags darf den verfügbaren Kontostand nicht überschreiten.\nDie Anzahl der Nachkommastellen muss kleiner oder gleich 2 sein",
"error_text_subaddress_name" : "Der Name der Unteradresse darf nicht enthalten sein ` , ' \" symbole\nund muss zwischen 1 und 20 Zeichen lang sein",
"error_text_amount" : "Betrag kann nur Zahlen enthalten",
"error_text_wallet_name" : "Der Wallet darf nur Buchstaben und Zahlen enthalten\nund muss zwischen 1 und 15 Zeichen lang sein",
"error_text_subaddress_name" : "Der Name der Unteradresse darf nicht die Zeichen ` , ' \" enthalten\nund muss zwischen 1 und 20 Zeichen lang sein",
"error_text_amount" : "Betrag darf nur Zahlen enthalten",
"error_text_wallet_name" : "Der Walletname darf nur Buchstaben und Zahlen enthalten\nund muss zwischen 1 und 15 Zeichen lang sein",
"error_text_keys" : "Walletschlüssel können nur 64 hexadezimale Zeichen enthalten",
"error_text_crypto_currency" : "Die Anzahl der Nachkommastellen\nmuss kleiner oder gleich 12 sein.",
"error_text_minimal_limit" : "Handel für ${provider} wird nicht erstellt. Menge ist weniger als minimal: ${min} ${currency}",
"error_text_maximum_limit" : "Handel für ${provider} wird nicht erstellt. Menge ist mehr als maximal: ${max} ${currency}",
"error_text_minimal_limit" : "Handel für ${provider} wird nicht erstellt. Menge ist unter dem Minimum: ${min} ${currency}",
"error_text_maximum_limit" : "Handel für ${provider} wird nicht erstellt. Menge ist über dem Maximum: ${max} ${currency}",
"error_text_limits_loading_failed" : "Handel für ${provider} wird nicht erstellt. Das Laden der Limits ist fehlgeschlagen",
"error_text_template" : "Vorlagenname und Adresse dürfen nicht enthalten ` , ' \" symbole\nund muss zwischen 1 und 106 Zeichen lang sein",
"error_text_template" : "Vorlagenname und Adresse dürfen nicht die Zeichen ` , ' \" enthalten\nund müssen zwischen 1 und 106 Zeichen lang sein",
"auth_store_ban_timeout" : "Auszeit verbieten",
"auth_store_ban_timeout" : "ban_timeout",
"auth_store_banned_for" : "Gebannt für ",
"auth_store_banned_minutes" : " Protokoll",
"auth_store_incorrect_password" : "Falsches PIN",
"wallet_store_monero_wallet" : "Monero Wallet",
"wallet_restoration_store_incorrect_seed_length" : "Falsche Samenlänge",
"auth_store_banned_minutes" : " Minuten",
"auth_store_incorrect_password" : "Falsche PIN",
"wallet_store_monero_wallet" : "Monero-Wallet",
"wallet_restoration_store_incorrect_seed_length" : "Falsche Seed-Länge",
"full_balance" : "Volle Balance",
"full_balance" : "Gesamtguthaben",
"available_balance" : "Verfügbares Guthaben",
"hidden_balance" : "Verstecktes Gleichgewicht",
"hidden_balance" : "Verstecktes Guthaben",
"sync_status_syncronizing" : "SYNCHRONISIERUNG",
"sync_status_syncronizing" : "SYNCHRONISIERE",
"sync_status_syncronized" : "SYNCHRONISIERT",
"sync_status_not_connected" : "NICHT VERBUNDEN",
"sync_status_starting_sync" : "STARTEN DER SYNCHRONISIERUNG",
"sync_status_starting_sync" : "STARTE SYNCHRONISIERUNG",
"sync_status_failed_connect" : "GETRENNT",
"sync_status_connecting" : "ANSCHLUSS",
"sync_status_connected" : "IN VERBINDUNG GEBRACHT",
"sync_status_connecting" : "VERBINDEN",
"sync_status_connected" : "VERBUNDEN",
"transaction_priority_slow" : "Schleppend",
"transaction_priority_regular" : "Regulär",
"transaction_priority_slow" : "Langsam",
"transaction_priority_regular" : "Normal",
"transaction_priority_medium" : "Mittel",
"transaction_priority_fast" : "Schnell",
"transaction_priority_fastest" : "Am schnellsten",
"trade_for_not_created" : "Handel für ${title} wird nicht erstellt.",
"trade_not_created" : "Handel nicht angelegt.",
"trade_not_created" : "Handel nicht erstellt.",
"trade_id_not_found" : "Handel ${tradeId} von ${title} nicht gefunden.",
"trade_not_found" : "Handel nicht gefunden.",
@ -364,28 +364,28 @@
"trade_state_pending" : "Steht aus",
"trade_state_confirming" : "Bestätigung",
"trade_state_trading" : "Handel",
"trade_state_traded" : "Handeln",
"trade_state_complete" : "Komplett",
"trade_state_to_be_created" : "Geschaffen werden",
"trade_state_traded" : "Gehandelt",
"trade_state_complete" : "Abgeschlossen",
"trade_state_to_be_created" : "Noch nicht erstellt",
"trade_state_unpaid" : "Unbezahlt",
"trade_state_underpaid" : "Unterbezahlt",
"trade_state_paid_unconfirmed" : "Unbestätigt bezahlt",
"trade_state_paid" : "Bezahlt",
"trade_state_btc_sent" : "geschickt",
"trade_state_timeout" : "Auszeit",
"trade_state_btc_sent" : "Btc gesendet",
"trade_state_timeout" : "Timeout",
"trade_state_created" : "Erstellt",
"trade_state_finished" : "Fertig",
"change_language" : "Sprache ändern",
"change_language_to" : "Ändern Sie die Sprache in ${language}?",
"change_language_to" : "Sprache zu ${language} ändern?",
"paste" : "Einfügen",
"restore_from_seed_placeholder" : "Bitte geben Sie hier Ihren Code ein",
"restore_from_seed_placeholder" : "Seed bitte hier eingeben oder einfügen",
"add_new_word" : "Neues Wort hinzufügen",
"incorrect_seed" : "Der eingegebene Text ist ungültig.",
"biometric_auth_reason" : "Scannen Sie Ihren Fingerabdruck zur Authentifizierung",
"version" : "Ausführung ${currentVersion}",
"version" : "Version ${currentVersion}",
"openalias_alert_title" : "XMR-Empfänger erkannt",
"openalias_alert_content" : "Sie senden Geld an\n${recipient_name}",
@ -398,81 +398,90 @@
"template" : "Vorlage",
"confirm_delete_template" : "Diese Aktion löscht diese Vorlage. Möchten Sie fortfahren?",
"confirm_delete_wallet" : "Diese Aktion löscht diese Brieftasche. Möchten Sie fortfahren?",
"confirm_delete_wallet" : "Diese Aktion löscht diese Wallet. Möchten Sie fortfahren?",
"picker_description" : "Um ChangeNOW oder MorphToken zu wählen, ändern Sie bitte zuerst Ihr Handelspaar",
"change_wallet_alert_title" : "Ändern Sie die aktuelle Brieftasche",
"change_wallet_alert_content" : "Möchten Sie die aktuelle Brieftasche in ändern ${wallet_name}?",
"change_wallet_alert_title" : "Aktuelle Wallet ändern",
"change_wallet_alert_content" : "Möchten Sie die aktuelle Wallet zu ${wallet_name} ändern?",
"creating_new_wallet" : "Neue Brieftasche erstellen",
"creating_new_wallet_error" : "Error: ${description}",
"creating_new_wallet" : "Neue Wallet erstellen",
"creating_new_wallet_error" : "Fehler: ${description}",
"seed_alert_title" : "Beachtung",
"seed_alert_content" : "Der Samen ist der einzige Weg, um Ihren Geldbeutel wiederzugewinnen. Hast du es aufgeschrieben?",
"seed_alert_back" : "Geh zurück",
"seed_alert_title" : "Achtung",
"seed_alert_content" : "Der Seed ist der einzige Weg, Ihre Wallet wiederherzustellen. Haben Sie ihn aufgeschrieben?",
"seed_alert_back" : "Zurückgehen",
"seed_alert_yes" : "Ja, habe ich",
"exchange_sync_alert_content" : "Bitte warten Sie, bis Ihre Brieftasche synchronisiert ist",
"exchange_sync_alert_content" : "Bitte warten Sie, bis Ihre Wallet synchronisiert ist",
"pre_seed_title" : "WICHTIG",
"pre_seed_description" : "Auf der nächsten Seite sehen Sie eine Reihe von ${words} Wörtern. Dies ist Ihr einzigartiger und privater Samen und der EINZIGE Weg, um Ihren Geldbeutel im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen. Es liegt in IHRER Verantwortung, es aufzuschreiben und an einem sicheren Ort außerhalb der Cake Wallet App aufzubewahren.",
"pre_seed_button_text" : "Ich verstehe. Zeig mir meinen Samen",
"pre_seed_description" : "Auf der nächsten Seite sehen Sie eine Reihe von ${words} Wörtern. Dies ist Ihr einzigartiger und privater Seed und der EINZIGE Weg, um Ihre Wallet im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen. Es liegt in IHRER Verantwortung, ihn aufzuschreiben und an einem sicheren Ort außerhalb der Cake Wallet-App aufzubewahren.",
"pre_seed_button_text" : "Verstanden. Zeig mir meinen Seed",
"xmr_to_error" : "XMR.TO-Fehler",
"xmr_to_error_description" : "Ungültiger Betrag. Höchstgrenze 8 Stellen nach dem Dezimalpunkt",
"provider_error" : "${provider} Error",
"provider_error" : "${provider}-Fehler",
"use_ssl" : "Verwenden Sie SSL",
"use_ssl" : "SSL verwenden",
"color_theme" : "Farbthema",
"light_theme" : "Licht",
"bright_theme" : "Hell",
"light_theme" : "Hell",
"bright_theme" : "Strahlend hell",
"dark_theme" : "Dunkel",
"enter_your_note" : "Geben Sie Ihre Notiz ein…",
"note_optional" : "Hinweis (optional)",
"note_tap_to_change" : "Hinweis (zum Ändern tippen)",
"enter_your_note" : "Geben Sie Ihre Bemerkung ein…",
"note_optional" : "Bemerkung (optional)",
"note_tap_to_change" : "Bemerkung (zum Ändern tippen)",
"transaction_key" : "Transaktionsschlüssel",
"confirmations" : "Bestätigungen",
"recipient_address" : "Empfängeradresse",
"extra_id" : "Zusätzliche ID:",
"extra_id" : "Extra ID:",
"destination_tag" : "Ziel-Tag:",
"memo" : "Memo:",
"backup" : "Backup",
"backup" : "Sicherung",
"change_password" : "Passwort ändern",
"backup_password" : "Passwort sichern",
"write_down_backup_password" : "Bitte notieren Sie sich Ihr Sicherungskennwort, das für den Import Ihrer Sicherungsdateien verwendet wird.",
"export_backup" : "Backup exportieren",
"save_backup_password" : "Bitte stellen Sie sicher, dass Sie Ihr Sicherungskennwort gespeichert haben. Ohne diese können Sie Ihre Sicherungsdateien nicht importieren.",
"backup_file" : "Sicherungskopie",
"write_down_backup_password" : "Bitte notieren Sie sich Ihr Sicherungskennwort, das für den Import Ihrer Sicherungsdateien gebraucht wird.",
"export_backup" : "Sicherung exportieren",
"save_backup_password" : "Bitte stellen Sie sicher, dass Sie Ihr Sicherungskennwort gespeichert haben. Ohne dieses können Sie Ihre Sicherungsdateien nicht importieren.",
"backup_file" : "Sicherungsdatei",
"edit_backup_password" : "Sicherungskennwort bearbeiten",
"save_backup_password_alert" : "Sicherungskennwort speichern",
"change_backup_password_alert" : "Ihre vorherigen Sicherungsdateien können nicht mit einem neuen Sicherungskennwort importiert werden. Das neue Sicherungskennwort wird nur für neue Sicherungsdateien verwendet. Sind Sie sicher, dass Sie das Sicherungskennwort ändern möchten?",
"enter_backup_password" : "Geben Sie hier das Sicherungskennwort ein",
"select_backup_file" : "Wählen Sie die Sicherungsdatei",
"enter_backup_password" : "Sicherungskennwort hier eingeben",
"select_backup_file" : "Sicherungsdatei auswählen",
"import" : "Importieren",
"please_select_backup_file" : "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.",
"fixed_rate" : "Fester Zinssatz",
"fixed_rate_alert" : "Sie können den Empfangsbetrag eingeben, wenn der Festpreismodus aktiviert ist. Möchten Sie in den Festpreismodus wechseln?",
"fixed_rate" : "Feste Rate",
"fixed_rate_alert" : "Sie können den Empfangsbetrag eingeben, wenn der Festratenmodus aktiviert ist. Möchten Sie in den Festratenmodus wechseln?",
"xlm_extra_info" : "Bitte vergessen Sie nicht, die Memo-ID anzugeben, während Sie die XLM-Transaktion für den Austausch senden",
"xrp_extra_info" : "Bitte vergessen Sie nicht, das Ziel-Tag anzugeben, während Sie die XRP-Transaktion für den Austausch senden",
"exchange_incorrect_current_wallet_for_xmr" : "Wenn Sie XMR von Ihrem Cake Wallet Monero-Guthaben austauschen möchten, wechseln Sie bitte zuerst zu Ihrem Monero Wallet.",
"exchange_incorrect_current_wallet_for_xmr" : "Wenn Sie XMR von Ihrem Cake Wallet Monero-Guthaben umtauschen möchten, wechseln Sie bitte zuerst zu Ihrer Monero-Wallet.",
"confirmed" : "Bestätigt",
"unconfirmed" : "Unbestätigt",
"displayable" : "Anzeigebar",
"submit_request" : "Einen Antrag stellen",
"submit_request" : "Eine Anfrage stellen",
"buy_alert_content" : "Derzeit unterstützen wir nur den Kauf von Bitcoin. Um Bitcoin zu kaufen, erstellen Sie bitte Ihre Bitcoin-Brieftasche oder wechseln Sie zu dieser",
"buy_alert_content" : "Derzeit unterstützen wir nur den Kauf von Bitcoin und Litecoin. Um Bitcoin oder Litecoin zu kaufen, erstellen oder wechseln Sie bitte zu Ihrem Bitcoin- oder Litecoin-Wallet.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
}
"outdated_electrum_wallet_description" : "Neue Bitcoin-Wallets, die in Cake erstellt wurden, haben jetzt einen 24-Wort-Seed. Sie müssen eine neue Bitcoin-Wallet erstellen, Ihr gesamtes Geld in die neue 24-Wort-Wallet überweisen und keine Wallet mit einem 12-Wort-Seed mehr verwenden. Bitte tun Sie dies sofort, um Ihr Geld zu sichern.",
"understand" : "Ich verstehe",
"apk_update" : "APK-Update",
"buy_bitcoin" : "Bitcoin kaufen",
"buy_with" : "Kaufen mit",
"moonpay_alert_text" : "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein",
"outdated_electrum_wallet_receive_warning": "Wenn diese Brieftasche einen 12-Wort-Seed hat und in Cake erstellt wurde, zahlen Sie KEINE Bitcoins in diese Brieftasche ein. Alle auf diese Wallet übertragenen BTC können verloren gehen. Erstellen Sie eine neue 24-Wort-Wallet (tippen Sie auf das Menü oben rechts, wählen Sie Wallets, wählen Sie Neue Wallet erstellen und dann Bitcoin) und verschieben Sie Ihre BTC SOFORT dorthin. Neue (24-Wort-)BTC-Wallets von Cake sind sicher",
"do_not_show_me": "Zeig mir das nicht noch einmal"
}

@ -471,8 +471,17 @@
"submit_request" : "submit a request",
"buy_alert_content" : "Currently we only support the purchase of Bitcoin. To buy Bitcoin, please create or switch to your Bitcoin wallet",
"buy_alert_content" : "Currently we only support the purchase of Bitcoin and Litecoin. To buy Bitcoin or Litecoin, please create or switch to your Bitcoin or Litecoin wallet.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand",
"apk_update" : "APK update",
"buy_bitcoin" : "Buy Bitcoin",
"buy_with" : "Buy with",
"moonpay_alert_text" : "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "If this wallet has a 12-word seed and was created in Cake, DO NOT deposit Bitcoin into this wallet. Any BTC transferred to this wallet may be lost. Create a new 24-word wallet (tap the menu at the top right, select Wallets, choose Create New Wallet, then select Bitcoin) and IMMEDIATELY move your BTC there. New (24-word) BTC wallets from Cake are secure",
"do_not_show_me": "Do not show me this again"
}

@ -471,8 +471,17 @@
"submit_request" : "presentar una solicitud",
"buy_alert_content" : "Actualmente solo apoyamos la compra de Bitcoin. Para comprar Bitcoin, cree o cambie a su billetera Bitcoin",
"buy_alert_content" : "Actualmente solo apoyamos la compra de Bitcoin y Litecoin. Para comprar Bitcoin o Litecoin, cree o cambie a su billetera Bitcoin o Litecoin.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Las nuevas carteras de Bitcoin creadas en Cake ahora tienen una semilla de 24 palabras. Es obligatorio que cree una nueva billetera de Bitcoin y transfiera todos sus fondos a la nueva billetera de 24 palabras, y deje de usar billeteras con una semilla de 12 palabras. Haga esto de inmediato para asegurar sus fondos.",
"understand" : "Entiendo",
"apk_update" : "Actualización de APK",
"buy_bitcoin" : "Comprar Bitcoin",
"buy_with" : "Compra con",
"moonpay_alert_text" : "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Si esta billetera tiene una semilla de 12 palabras y se creó en Cake, NO deposite Bitcoin en esta billetera. Cualquier BTC transferido a esta billetera se puede perder. Cree una nueva billetera de 24 palabras (toque el menú en la parte superior derecha, seleccione Monederos, elija Crear nueva billetera, luego seleccione Bitcoin) e INMEDIATAMENTE mueva su BTC allí. Las nuevas carteras BTC (24 palabras) de Cake son seguras",
"do_not_show_me": "no me muestres esto otra vez"
}

@ -471,8 +471,17 @@
"submit_request" : "एक अनुरोध सबमिट करें",
"buy_alert_content" : "वर्तमान में हम केवल बिटकॉइन की खरीद का समर्थन करते हैं। बिटकॉइन खरीदने के लिए, कृपया अपना बिटकॉइन वॉलेट बनाएं या स्विच करें",
"buy_alert_content" : "वर्तमान में हम केवल बिटकॉइन और लिटकोइन की खरीद का समर्थन करते हैं। बिटकॉइन या लाइटकोइन खरीदने के लिए, कृपया अपना बिटकॉइन या लाइटकोइन वॉलेट बनाएं या स्विच करें",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "केक में बनाए गए नए बिटकॉइन वॉलेट में अब 24-शब्द का बीज है। यह अनिवार्य है कि आप एक नया बिटकॉइन वॉलेट बनाएं और अपने सभी फंड को नए 24-शब्द वाले वॉलेट में स्थानांतरित करें, और 12-शब्द बीज वाले वॉलेट का उपयोग करना बंद करें। कृपया अपने धन को सुरक्षित करने के लिए इसे तुरंत करें।",
"understand" : "मुझे समझ",
"apk_update" : "APK अद्यतन",
"buy_bitcoin" : "बिटकॉइन खरीदें",
"buy_with" : "के साथ खरीदें",
"moonpay_alert_text" : "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "अगर इस वॉलेट में 12 शब्दों का बीज है और इसे केक में बनाया गया है, तो इस वॉलेट में बिटकॉइन जमा न करें। इस वॉलेट में स्थानांतरित किया गया कोई भी बीटीसी खो सकता है। एक नया 24-शब्द वॉलेट बनाएं (ऊपर दाईं ओर स्थित मेनू पर टैप करें, वॉलेट चुनें, नया वॉलेट बनाएं चुनें, फिर बिटकॉइन चुनें) और तुरंत अपना बीटीसी वहां ले जाएं। केक से नए (24-शब्द) बीटीसी वॉलेट सुरक्षित हैं",
"do_not_show_me": "मुझे यह फिर न दिखाएं"
}

@ -471,8 +471,17 @@
"submit_request" : "podnesi zahtjev",
"buy_alert_content" : "Currently we only support the purchase of Bitcoin. To buy Bitcoin, please create or switch to your Bitcoin wallet",
"buy_alert_content" : "Trenutno podržavamo samo kupnju Bitcoina i Litecoina. Da biste kupili Bitcoin ili Litecoin, stvorite ili pređite na svoj Bitcoin ili Litecoin novčanik.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Novi Bitcoin novčanici stvoreni u Cakeu sada imaju sjeme od 24 riječi. Obavezno je stvoriti novi Bitcoin novčanik i prenijeti sva svoja sredstva u novi novčanik od 24 riječi te prestati koristiti novčanike s sjemenkom od 12 riječi. Učinite to odmah kako biste osigurali svoja sredstva.",
"understand" : "Razumijem",
"apk_update" : "APK ažuriranje",
"buy_bitcoin" : "Kupite Bitcoin",
"buy_with" : "Kupite s",
"moonpay_alert_text" : "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Ako ovaj novčanik sadrži sjeme od 12 riječi i stvoren je u Torti, NEMOJTE polagati Bitcoin u ovaj novčanik. Bilo koji BTC prebačen u ovaj novčanik može se izgubiti. Stvorite novi novčanik od 24 riječi (taknite izbornik u gornjem desnom dijelu, odaberite Novčanici, odaberite Stvori novi novčanik, a zatim odaberite Bitcoin) i ODMAH premjestite svoj BTC tamo. Novi BTC novčanici (s 24 riječi) tvrtke Cake sigurni su",
"do_not_show_me": "Ne pokazuj mi ovo više"
}

@ -471,8 +471,17 @@
"submit_request" : "invia una richiesta",
"buy_alert_content" : "Currently we only support the purchase of Bitcoin. To buy Bitcoin, please create or switch to your Bitcoin wallet",
"buy_alert_content" : "Attualmente supportiamo solo l'acquisto di Bitcoin e Litecoin. Per acquistare Bitcoin o Litecoin, crea o passa al tuo portafoglio Bitcoin o Litecoin.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "I nuovi portafogli Bitcoin creati in Cake ora hanno un seme di 24 parole. È obbligatorio creare un nuovo portafoglio Bitcoin e trasferire tutti i fondi nel nuovo portafoglio di 24 parole e smettere di usare portafogli con un seme di 12 parole. Ti preghiamo di farlo immediatamente per proteggere i tuoi fondi.",
"understand" : "Capisco",
"apk_update" : "Aggiornamento APK",
"buy_bitcoin" : "Acquista Bitcoin",
"buy_with" : "Acquista con",
"moonpay_alert_text" : "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Se questo portafoglio ha un seme di 12 parole ed è stato creato in Cake, NON depositare Bitcoin in questo portafoglio. Qualsiasi BTC trasferito su questo portafoglio potrebbe andare perso. Crea un nuovo portafoglio di 24 parole (tocca il menu in alto a destra, seleziona Portafogli, scegli Crea nuovo portafoglio, quindi seleziona Bitcoin) e sposta IMMEDIATAMENTE lì il tuo BTC. I nuovi portafogli BTC (24 parole) di Cake sono sicuri",
"do_not_show_me": "Non mostrarmelo di nuovo"
}

@ -471,8 +471,17 @@
"submit_request" : "リクエストを送信する",
"buy_alert_content" : "現在、ビットコインの購入のみをサポートしています。 ビットコインを購入するには、ビットコインウォレットを作成するか切り替えてください",
"buy_alert_content" : "現在、ビットコインとライトコインの購入のみをサポートしています。 ビットコインまたはライトコインを購入するには、ビットコインまたはライトコインのウォレットを作成するか、ウォレットに切り替えてください",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Cakeで作成された新しいビットコインウォレットには、24ワードのシードがあります。 新しいビットコインウォレットを作成し、すべての資金を新しい24ワードのウォレットに転送し、12ワードのシードを持つウォレットの使用を停止することが必須です。 あなたの資金を確保するためにこれをすぐに行ってください。",
"understand" : "わかります",
"apk_update" : "APKアップデート",
"buy_bitcoin" : "ビットコインを購入する",
"buy_with" : "で購入",
"moonpay_alert_text" : "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "このウォレットに 12 ワードのシードがあり、Cake で作成された場合、このウォレットにビットコインを入金しないでください。 このウォレットに転送された BTC は失われる可能性があります。 新しい 24 ワードのウォレットを作成し (右上のメニューをタップし、[ウォレット]、[新しいウォレットの作成]、[ビットコイン] の順に選択)、すぐに BTC をそこに移動します。 Cake の新しい (24 ワード) BTC ウォレットは安全です",
"do_not_show_me": "また僕にこれを見せないでください"
}

@ -471,8 +471,17 @@
"submit_request" : "요청을 제출",
"buy_alert_content" : "현재 우리는 비트 코인 구매 만 지원합니다. 비트 코인을 구매하려면 비트 코인 지갑을 생성하거나 전환하십시오",
"buy_alert_content" : "현재 우리는 비트 코인과 라이트 코인 구매 만 지원합니다. 비트 코인 또는 라이트 코인을 구매하려면 비트 코인 또는 라이트 코인 지갑을 생성하거나 전환하십시오.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Cake에서 생성 된 새로운 비트 코인 지갑에는 이제 24 단어 시드가 있습니다. 새로운 비트 코인 지갑을 생성하고 모든 자금을 새로운 24 단어 지갑으로 이체하고 12 단어 시드가있는 지갑 사용을 중지해야합니다. 자금을 확보하려면 즉시이 작업을 수행하십시오.",
"understand" : "이해 했어요",
"apk_update" : "APK 업데이트",
"buy_bitcoin" : "비트 코인 구매",
"buy_with" : "구매",
"moonpay_alert_text" : "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "이 지갑에 12 단어 시드가 있고 Cake에서 생성 된 경우이 지갑에 비트 코인을 입금하지 마십시오. 이 지갑으로 전송 된 모든 BTC는 손실 될 수 있습니다. 새로운 24 단어 지갑을 생성하고 (오른쪽 상단의 메뉴를 탭하고 지갑을 선택한 다음 새 지갑 생성을 선택한 다음 비트 코인을 선택하십시오) 즉시 BTC를 그곳으로 이동하십시오. Cake의 새로운 (24 단어) BTC 지갑은 안전합니다",
"do_not_show_me": "나를 다시 표시하지 않음"
}

@ -471,8 +471,17 @@
"submit_request" : "een verzoek indienen",
"buy_alert_content" : "Momenteel ondersteunen we alleen de aankoop van Bitcoin. Om Bitcoin te kopen, moet u uw Bitcoin-portemonnee aanmaken of naar uw Bitcoin-portemonnee overschakelen",
"buy_alert_content" : "Momenteel ondersteunen we alleen de aankoop van Bitcoin en Litecoin. Om Bitcoin of Litecoin te kopen, maakt u uw Bitcoin- of Litecoin-portemonnee aan of schakelt u over naar deze.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Nieuwe Bitcoin-portefeuilles die in Cake zijn gemaakt, hebben nu een zaadje van 24 woorden. Het is verplicht dat u een nieuwe Bitcoin-portemonnee maakt en al uw geld overmaakt naar de nieuwe portemonnee van 24 woorden, en stopt met het gebruik van wallets met een seed van 12 woorden. Doe dit onmiddellijk om uw geld veilig te stellen.",
"understand" : "Ik begrijp het",
"apk_update" : "APK-update",
"buy_bitcoin" : "Koop Bitcoin",
"buy_with" : "Koop met",
"moonpay_alert_text" : "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Als deze portemonnee een seed van 12 woorden heeft en is gemaakt in Cake, stort dan GEEN Bitcoin in deze portemonnee. Elke BTC die naar deze portemonnee is overgebracht, kan verloren gaan. Maak een nieuwe portemonnee van 24 woorden (tik op het menu rechtsboven, selecteer Portefeuilles, kies Nieuwe portemonnee maken en selecteer vervolgens Bitcoin) en verplaats je BTC ONMIDDELLIJK daar. Nieuwe (24-woorden) BTC-portefeuilles van Cake zijn veilig",
"do_not_show_me": "laat me dit niet opnieuw zien"
}

@ -471,8 +471,17 @@
"submit_request" : "złożyć wniosek",
"buy_alert_content" : "Obecnie obsługujemy tylko zakup Bitcoinów. Aby kupić Bitcoin, utwórz lub przełącz się na swój portfel Bitcoin",
"buy_alert_content" : "Obecnie obsługujemy tylko zakup Bitcoin i Litecoin. Aby kupić Bitcoin lub Litecoin, utwórz lub przełącz się na swój portfel Bitcoin lub Litecoin.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Nowe portfele Bitcoin utworzone w Cake mają teraz ziarno składające się z 24 słów. Konieczne jest utworzenie nowego portfela Bitcoin i przeniesienie wszystkich środków do nowego portfela na 24 słowa oraz zaprzestanie korzystania z portfeli z zalążkiem na 12 słów. Zrób to natychmiast, aby zabezpieczyć swoje fundusze.",
"understand" : "Rozumiem",
"apk_update" : "Aktualizacja APK",
"buy_bitcoin" : "Kup Bitcoin",
"buy_with" : "Kup za pomocą",
"moonpay_alert_text" : "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Jeśli ten portfel ma 12-wyrazowy seed i został utworzony w Cake, NIE Wpłacaj Bitcoina do tego portfela. Wszelkie BTC przeniesione do tego portfela mogą zostać utracone. Utwórz nowy portfel z 24 słowami (dotknij menu w prawym górnym rogu, wybierz Portfele, wybierz Utwórz nowy portfel, a następnie Bitcoin) i NATYCHMIAST przenieś tam swoje BTC. Nowe (24 słowa) portfele BTC firmy Cake są bezpieczne",
"do_not_show_me": "Nie pokazuj mi tego ponownie"
}

@ -471,8 +471,17 @@
"submit_request" : "enviar um pedido",
"buy_alert_content" : "Atualmente, apoiamos apenas a compra de Bitcoin. Para comprar Bitcoin, crie ou mude para sua carteira Bitcoin",
"buy_alert_content" : "Atualmente, apoiamos apenas a compra de Bitcoin e Litecoin. Para comprar Bitcoin ou Litecoin, crie ou troque para sua carteira Bitcoin ou Litecoin.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "As novas carteiras Bitcoin criadas no Cake agora têm uma semente de 24 palavras. É obrigatório que você crie uma nova carteira Bitcoin e transfira todos os seus fundos para a nova carteira de 24 palavras, e pare de usar carteiras com semente de 12 palavras. Faça isso imediatamente para garantir seus fundos.",
"understand" : "Entendo",
"apk_update" : "Atualização de APK",
"buy_bitcoin" : "Compre Bitcoin",
"buy_with" : "Compre com",
"moonpay_alert_text" : "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Se esta carteira tiver uma semente de 12 palavras e foi criada no Cake, NÃO deposite Bitcoin nesta carteira. Qualquer BTC transferido para esta carteira pode ser perdido. Crie uma nova carteira de 24 palavras (toque no menu no canto superior direito, selecione Carteiras, escolha Criar Nova Carteira e selecione Bitcoin) e mova IMEDIATAMENTE seu BTC para lá. As novas carteiras BTC (24 palavras) da Cake são seguras",
"do_not_show_me": "não me mostre isso novamente"
}

@ -471,8 +471,17 @@
"submit_request" : "отправить запрос",
"buy_alert_content" : "В настоящее время мы поддерживаем только покупку Bitcoin. Чтобы купить Bitcoin, создайте или переключитесь на ваш Bitcoin кошелек",
"buy_alert_content" : "В настоящее время мы поддерживаем только покупку Bitcoin и Litecoin. Чтобы купить Bitcoin или Litecoin, создайте или переключитесь на свой Bitcoin или Litecoin кошелек.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Новые биткойн-кошельки, созданные в Cake, теперь содержат мнемоническую фразу из 24 слов. Вы обязательно должны создать новый биткойн-кошелек и перевести все свои средства в новый кошелек из 24 слов, а также прекратить использование кошельков с мнемонической фразой из 12 слов. Пожалуйста, сделайте это немедленно, чтобы обезопасить свои средства.",
"understand" : "Понятно",
"apk_update" : "Обновление APK",
"buy_bitcoin" : "Купить Bitcoin",
"buy_with" : "Купить с помощью",
"moonpay_alert_text" : "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Если этот кошелек имеет мнемоническую фразу из 12 слов и был создан в Cake, НЕ переводите биткойны на этот кошелек. Любые BTC, переведенные на этот кошелек, могут быть потеряны. Создайте новый кошелек с мнемоническои фразы из 24 слов (коснитесь меню в правом верхнем углу, выберите «Кошельки», выберите «Создать новый кошелек», затем выберите «Bitcoin») и НЕМЕДЛЕННО переведите туда свои BTC. Новые (24 слова) кошельки BTC от Cake безопасны",
"do_not_show_me": "Не показывай мне это больше"
}

@ -471,8 +471,17 @@
"submit_request" : "надіслати запит",
"buy_alert_content" : "На даний час ми підтримуємо тільки покупку Bitcoin. Щоб купити Bitcoin, будь ласка, створіть або переключіться на ваш Bitcoin гаманець",
"buy_alert_content" : "В даний час ми підтримуємо лише придбання Bitcoin та Litecoin. Щоб купити Bitcoin або Litecoin, будь ласка, створіть або перейдіть на свій гаманець Bitcoin або Litecoin.",
"outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.",
"understand" : "I understand"
"outdated_electrum_wallet_description" : "Нові біткойн-гаманці, створені в Cake, тепер містять мнемонічну фразу з 24 слів. Обов’язково стовріть новий біткойн-гаманець, переведіть всі кошти на новий гаманець із 24 слів і припиніть використання гаманців із мнемонічною фразою з 12 слів. Зробіть це негайно, щоб убезпечити свої кошти.",
"understand" : "Зрозуміло",
"apk_update" : "Оновлення APK",
"buy_bitcoin" : "Купити Bitcoin",
"buy_with" : "Купити за допомогою",
"moonpay_alert_text" : "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Якщо цей гаманець має мнемонічну фразу з 12 слів і був створений у Cake, НЕ переводьте біткойни на цей гаманець. Будь-які BTC, переведений на цей гаманець, можуть бути втраченими. Створіть новий гаманець з мнемонічною фразою з 24 слів (торкніться меню у верхньому правому куті, виберіть Гаманці, виберіть Створити новий гаманець, потім виберіть Bitcoin) і НЕГАЙНО переведіть туди свії BTC. Нові (з мнемонічною фразою з 24 слів) гаманці BTC від Cake надійно захищені",
"do_not_show_me": "Не показуй мені це знову"
}

@ -169,7 +169,7 @@
"restore_recover" : "恢复",
"restore_wallet_restore_description" : "钱包还原说明",
"restore_new_seed" : "新种子",
"restore_active_seed" : "活种子",
"restore_active_seed" : "活种子",
"restore_bitcoin_description_from_seed" : "从24个文字的组成码恢复您的钱包",
"restore_bitcoin_description_from_keys" : "从私钥中生成的WIF字符串恢复您钱包",
"restore_bitcoin_title_from_keys" : "从WIF还原",
@ -267,7 +267,7 @@
"trade_details_title" : "交易明细",
"trade_details_id" : "ID",
"trade_details_state" : "条件",
"trade_details_fetching" : "正在取",
"trade_details_fetching" : "正在取",
"trade_details_provider" : "提供者",
"trade_details_created_at" : "创建于",
"trade_details_pair" : "对",
@ -322,7 +322,7 @@
"error_text_crypto_currency" : "小数位数\n必须小于或等于12",
"error_text_minimal_limit" : "未创建 ${provider} 交易。 金额小于最小值:${min} ${currency}",
"error_text_maximum_limit" : "未创建 ${provider} 交易。 金额大于最大值:${max} ${currency}",
"error_text_limits_loading_failed" : "未创建 ${provider} 交易。 限制加载失",
"error_text_limits_loading_failed" : "未创建 ${provider} 交易。 限制加载失",
"error_text_template" : "模板名称和地址不能包含`' \" 符号\n并且必须在1到106个字符之间",
@ -471,8 +471,17 @@
"submit_request" : "提交请求",
"buy_alert_content" : "目前,我们仅支持购买比特币。要购买比特币,请创建或切换到您的比特币钱包",
"buy_alert_content" : "目前我们只支持购买比特币和莱特币。 要购买比特币或莱特币,请创建或切换到您的比特币或莱特币钱包。",
"outdated_electrum_wallet_desceription" : "在Cake创建的新比特币钱包现在有一个24字的种子。你必须创建一个新的比特币钱包并将你所有的资金转移到新的24字钱包并停止使用12字种子的钱包。请立即这样做以保证你的资金安全。",
"understand" : "我已知晓"
"outdated_electrum_wallet_description" : "在Cake创建的新比特币钱包现在有一个24字的种子。你必须创建一个新的比特币钱包并将你所有的资金转移到新的24字钱包并停止使用12字种子的钱包。请立即这样做以保证你的资金安全。",
"understand" : "我已知晓",
"apk_update" : "APK更新",
"buy_bitcoin" : "购买比特币",
"buy_with" : "一起购买",
"moonpay_alert_text" : "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "如果这个钱包有一个 12 字的种子并且是在 Cake 中创建的,不要将比特币存入这个钱包。 任何转移到此钱包的 BTC 都可能丢失。 创建一个新的 24 字钱包(点击右上角的菜单,选择钱包,选择创建新钱包,然后选择比特币)并立即将您的 BTC 移到那里。 Cake 的新24 字BTC 钱包是安全的",
"do_not_show_me": "不再提示"
}
Loading…
Cancel
Save