Add additional Buy Provider (#1071)

* CW-466 Add Buy Options Page

* CW-466 Add Buy Options

* CW-466 Add Default Buy Provider to Other Settings

* CW-466 Onramper is working from Buy Options

* CW-466 Onramper is working from Buy Options

* CW-466 Translation improvements

* CW-466 Add Onramper & Robinhood Logos

* CW-466 Implement Robinhood Flow

* CW-466 Fix Robinhood Flow

* CW-466 Add RH-Secrets

* CW-466 Have RH Translation in English only

* Add missing URI details

* CW-466 Implement default Buy Provider

* CW-466 Fix Padding Buy Provider Options

* CW-466 Fix Bitcoin and Litecoin Signatures

* CW-466 Fix Error Message

* CW-466 Resolve requested changes

* Add exception handler to robinhood API calls

* CW-466 Fix Theming

---------

Co-authored-by: Justin Ehrenhofer <justin.ehrenhofer@gmail.com>
Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
Konstantin Ullrich 2023-09-14 21:14:49 +02:00 committed by GitHub
parent ce4d375abf
commit d972363417
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 548 additions and 477 deletions

View file

@ -128,6 +128,8 @@ jobs:
echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_ethereum/lib/.secrets.g.dart echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_ethereum/lib/.secrets.g.dart
echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
echo "const robinhoodCIdApiSecret = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
- name: Rename app - name: Rename app
run: echo -e "id=com.cakewallet.test\nname=$GITHUB_HEAD_REF" > /opt/android/cake_wallet/android/app.properties run: echo -e "id=com.cakewallet.test\nname=$GITHUB_HEAD_REF" > /opt/android/cake_wallet/android/app.properties

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -740,4 +740,14 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
@override @override
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError; void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
@override
String signMessage(String message, {String? address = null}) {
final index = address != null
? walletAddresses.addresses.firstWhere((element) => element.address == address).index
: null;
return index == null
? base64Encode(hd.sign(message))
: base64Encode(hd.derive(index).sign(message));
}
} }

View file

@ -83,4 +83,6 @@ abstract class WalletBase<
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => null; void setExceptionHandler(void Function(FlutterErrorDetails) onError) => null;
Future<void> renameWalletFiles(String newWalletName); Future<void> renameWalletFiles(String newWalletName);
String signMessage(String message, {String? address = null}) => throw UnimplementedError();
} }

View file

@ -31,6 +31,7 @@ import 'package:hive/hive.dart';
import 'package:hex/hex.dart'; import 'package:hex/hex.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:web3dart/crypto.dart';
import 'package:web3dart/web3dart.dart'; import 'package:web3dart/web3dart.dart';
import 'package:bip39/bip39.dart' as bip39; import 'package:bip39/bip39.dart' as bip39;
import 'package:bip32/bip32.dart' as bip32; import 'package:bip32/bip32.dart' as bip32;
@ -503,4 +504,8 @@ abstract class EthereumWalletBase
_transactionsUpdateTimer?.cancel(); _transactionsUpdateTimer?.cancel();
} }
} }
@override
String signMessage(String message, {String? address = null}) =>
bytesToHex(_ethPrivateKey.signPersonalMessageToUint8List(ascii.encode(message)));
} }

View file

@ -1,10 +1,13 @@
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class OnRamperBuyProvider { class OnRamperBuyProvider {
OnRamperBuyProvider({required SettingsStore settingsStore, required WalletBase wallet}) OnRamperBuyProvider({required SettingsStore settingsStore, required WalletBase wallet})
@ -69,4 +72,13 @@ class OnRamperBuyProvider {
'cardColor': cardColor 'cardColor': cardColor
}); });
} }
Future<void> launchProvider(BuildContext context) async {
final uri = requestUrl(context);
if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]);
} else {
await launchUrl(uri);
}
}
} }

View file

@ -0,0 +1,92 @@
import 'dart:convert';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:url_launcher/url_launcher.dart';
class RobinhoodBuyProvider {
RobinhoodBuyProvider({required WalletBase wallet})
: this._wallet = wallet;
final WalletBase _wallet;
static const _baseUrl = 'applink.robinhood.com';
static const _cIdBaseUrl = 'exchange-helper.cakewallet.com';
String get _applicationId => secrets.robinhoodApplicationId;
String get _apiSecret => secrets.robinhoodCIdApiSecret;
bool get isAvailable =>
[WalletType.bitcoin, WalletType.litecoin, WalletType.ethereum].contains(_wallet.type);
String getSignature(String message) {
switch (_wallet.type) {
case WalletType.ethereum:
return _wallet.signMessage(message);
case WalletType.litecoin:
case WalletType.bitcoin:
return _wallet.signMessage(message, address: _wallet.walletAddresses.address);
default:
throw Exception("WalletType is not available for Robinhood");
}
}
Future<String> getConnectId() async {
final walletAddress = _wallet.walletAddresses.address;
final valid_until = (DateTime.now().millisecondsSinceEpoch / 1000).round() + 10;
final message = "$_apiSecret:${valid_until}";
final signature = getSignature(message);
final uri = Uri.https(_cIdBaseUrl, "/api/robinhood");
var response = await http.post(uri,
headers: {'Content-Type': 'application/json'},
body: json
.encode({'valid_until': valid_until, 'wallet': walletAddress, 'signature': signature}));
if (response.statusCode == 200) {
return (jsonDecode(response.body) as Map<String, dynamic>)['connectId'] as String;
} else {
throw Exception('Provider currently unavailable. Status: ${response.statusCode} ${response.body}');
}
}
Future<Uri> requestUrl() async {
final connectId = await getConnectId();
final networkName = _wallet.currency.fullName?.toUpperCase().replaceAll(" ", "_");
return Uri.https(_baseUrl, '/u/connect', <String, dynamic>{
'applicationId': _applicationId,
'connectId': connectId,
'walletAddress': _wallet.walletAddresses.address,
'userIdentifier': _wallet.walletAddresses.address,
'supportedNetworks': networkName
});
}
Future<void> launchProvider(BuildContext context) async {
try {
final uri = await requestUrl();
await launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (e, s) {
ExceptionHandler.onError(FlutterErrorDetails(exception: e, stack: s));
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: "Robinhood Connect",
alertContent: S.of(context).buy_provider_unavailable,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
}
}
}

View file

@ -208,6 +208,7 @@ class BackupService {
final isAppSecure = data[PreferencesKey.isAppSecureKey] as bool?; final isAppSecure = data[PreferencesKey.isAppSecureKey] as bool?;
final disableBuy = data[PreferencesKey.disableBuyKey] as bool?; final disableBuy = data[PreferencesKey.disableBuyKey] as bool?;
final disableSell = data[PreferencesKey.disableSellKey] as bool?; final disableSell = data[PreferencesKey.disableSellKey] as bool?;
final defaultBuyProvider = data[PreferencesKey.defaultBuyProvider] as int?;
final currentTransactionPriorityKeyLegacy = final currentTransactionPriorityKeyLegacy =
data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?; data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?;
final allowBiometricalAuthentication = final allowBiometricalAuthentication =
@ -276,6 +277,9 @@ class BackupService {
if (disableSell != null) if (disableSell != null)
await _sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell); await _sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell);
if (defaultBuyProvider != null)
await _sharedPreferences.setInt(PreferencesKey.defaultBuyProvider, defaultBuyProvider);
if (currentTransactionPriorityKeyLegacy != null) if (currentTransactionPriorityKeyLegacy != null)
await _sharedPreferences.setInt( await _sharedPreferences.setInt(
PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy); PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy);
@ -476,6 +480,7 @@ class BackupService {
_sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey), _sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey),
PreferencesKey.disableBuyKey: _sharedPreferences.getBool(PreferencesKey.disableBuyKey), PreferencesKey.disableBuyKey: _sharedPreferences.getBool(PreferencesKey.disableBuyKey),
PreferencesKey.disableSellKey: _sharedPreferences.getBool(PreferencesKey.disableSellKey), PreferencesKey.disableSellKey: _sharedPreferences.getBool(PreferencesKey.disableSellKey),
PreferencesKey.defaultBuyProvider: _sharedPreferences.getInt(PreferencesKey.defaultBuyProvider),
PreferencesKey.isDarkThemeLegacy: PreferencesKey.isDarkThemeLegacy:
_sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy), _sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy),
PreferencesKey.currentPinLength: _sharedPreferences.getInt(PreferencesKey.currentPinLength), PreferencesKey.currentPinLength: _sharedPreferences.getInt(PreferencesKey.currentPinLength),

View file

@ -3,6 +3,7 @@ import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart'; import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
import 'package:cake_wallet/core/yat_service.dart'; import 'package:cake_wallet/core/yat_service.dart';
import 'package:cake_wallet/entities/background_tasks.dart'; import 'package:cake_wallet/entities/background_tasks.dart';
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart'; import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
@ -15,6 +16,7 @@ import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_tip.dart'; import 'package:cake_wallet/ionia/ionia_tip.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart'; import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_options_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
@ -95,7 +97,6 @@ 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/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_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_list_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
@ -688,6 +689,9 @@ Future<void> setup({
editingNode: editingNode, editingNode: editingNode,
isSelected: isSelected)); isSelected: isSelected));
getIt.registerFactory<RobinhoodBuyProvider>(
() => RobinhoodBuyProvider(wallet: getIt.get<AppStore>().wallet!));
getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider( getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider(
settingsStore: getIt.get<AppStore>().settingsStore, settingsStore: getIt.get<AppStore>().settingsStore,
wallet: getIt.get<AppStore>().wallet!, wallet: getIt.get<AppStore>().wallet!,
@ -816,6 +820,8 @@ Future<void> setup({
getIt.registerFactory(() => BuyAmountViewModel()); getIt.registerFactory(() => BuyAmountViewModel());
getIt.registerFactory(() => BuyOptionsPage());
getIt.registerFactory(() { getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet; final wallet = getIt.get<AppStore>().wallet;
@ -824,10 +830,6 @@ Future<void> setup({
wallet: wallet!); wallet: wallet!);
}); });
getIt.registerFactory(() {
return PreOrderPage(buyViewModel: getIt.get<BuyViewModel>());
});
getIt.registerFactoryParam<BuyWebViewPage, List, void>((List args, _) { getIt.registerFactoryParam<BuyWebViewPage, List, void>((List args, _) {
final url = args.first as String; final url = args.first as String;
final buyViewModel = args[1] as BuyViewModel; final buyViewModel = args[1] as BuyViewModel;

View file

@ -0,0 +1,19 @@
import 'package:cake_wallet/generated/i18n.dart';
enum BuyProviderType {
AskEachTime,
Robinhood,
Onramper;
@override
String toString() {
switch (this) {
case BuyProviderType.AskEachTime:
return S.current.ask_each_time;
case BuyProviderType.Robinhood:
return "Robinhood";
case BuyProviderType.Onramper:
return "Onramper";
}
}
}

View file

@ -1,6 +1,8 @@
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/buy_provider_types.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@ -41,23 +43,30 @@ class MainActions {
isEnabled: (viewModel) => viewModel.isEnabledBuyAction, isEnabled: (viewModel) => viewModel.isEnabledBuyAction,
canShow: (viewModel) => viewModel.hasBuyAction, canShow: (viewModel) => viewModel.hasBuyAction,
onTap: (BuildContext context, DashboardViewModel viewModel) async { onTap: (BuildContext context, DashboardViewModel viewModel) async {
final defaultBuyProvider = viewModel.defaultBuyProvider;
final walletType = viewModel.type; final walletType = viewModel.type;
if (!viewModel.isEnabledBuyAction) return;
switch (walletType) { switch (walletType) {
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.ethereum: case WalletType.ethereum:
case WalletType.monero: switch (defaultBuyProvider) {
if (viewModel.isEnabledBuyAction) { case BuyProviderType.AskEachTime:
final uri = getIt.get<OnRamperBuyProvider>().requestUrl(context); Navigator.pushNamed(context, Routes.buy);
if (DeviceInfo.instance.isMobile) { break;
Navigator.of(context) case BuyProviderType.Onramper:
.pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]); await getIt.get<OnRamperBuyProvider>().launchProvider(context);
} else { break;
await launchUrl(uri); case BuyProviderType.Robinhood:
} await getIt.get<RobinhoodBuyProvider>().launchProvider(context);
break;
} }
break; break;
case WalletType.monero:
await getIt.get<OnRamperBuyProvider>().launchProvider(context);
break;
default: default:
await showPopUp<void>( await showPopUp<void>(
context: context, context: context,

View file

@ -13,6 +13,7 @@ class PreferencesKey {
static const isAppSecureKey = 'is_app_secure'; static const isAppSecureKey = 'is_app_secure';
static const disableBuyKey = 'disable_buy'; static const disableBuyKey = 'disable_buy';
static const disableSellKey = 'disable_sell'; static const disableSellKey = 'disable_sell';
static const defaultBuyProvider = 'default_buy_provider';
static const currentFiatApiModeKey = 'current_fiat_api_mode'; static const currentFiatApiModeKey = 'current_fiat_api_mode';
static const allowBiometricalAuthenticationKey = static const allowBiometricalAuthenticationKey =
'allow_biometrical_authentication'; 'allow_biometrical_authentication';

View file

@ -7,9 +7,9 @@ import 'package:cake_wallet/entities/qr_view_data.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart'; import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/backup/backup_page.dart'; import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_options_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart'; import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart'; import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart'; import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart'; import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart';
@ -383,10 +383,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => builder: (_) =>
getIt.get<OrderDetailsPage>(param1: settings.arguments as Order)); getIt.get<OrderDetailsPage>(param1: settings.arguments as Order));
case Routes.preOrder: case Routes.buy:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<BuyOptionsPage>());
builder: (_) =>
getIt.get<PreOrderPage>());
case Routes.buyWebView: case Routes.buyWebView:
final args = settings.arguments as List; final args = settings.arguments as List;

View file

@ -50,7 +50,7 @@ class Routes {
static const supportLiveChat = '/support/live_chat'; static const supportLiveChat = '/support/live_chat';
static const supportOtherLinks = '/support/other'; static const supportOtherLinks = '/support/other';
static const orderDetails = '/order_details'; static const orderDetails = '/order_details';
static const preOrder = '/pre_order'; static const buy = '/buy';
static const buyWebView = '/buy_web_view'; static const buyWebView = '/buy_web_view';
static const unspentCoinsList = '/unspent_coins_list'; static const unspentCoinsList = '/unspent_coins_list';
static const unspentCoinsDetails = '/unspent_coins_details'; static const unspentCoinsDetails = '/unspent_coins_details';

View file

@ -0,0 +1,76 @@
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/option_tile.dart';
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
import 'package:flutter/material.dart';
class BuyOptionsPage extends BasePage {
final iconDarkRobinhood = 'assets/images/robinhood_dark.png';
final iconLightRobinhood = 'assets/images/robinhood_light.png';
final iconDarkOnramper = 'assets/images/onramper_dark.png';
final iconLightOnramper = 'assets/images/onramper_light.png';
@override
String get title => S.current.buy;
@override
AppBarStyle get appBarStyle => AppBarStyle.regular;
@override
Widget body(BuildContext context) {
final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
final iconRobinhood =
Image.asset(isLightMode ? iconLightRobinhood : iconDarkRobinhood, height: 40, width: 40);
final iconOnramper =
Image.asset(isLightMode ? iconLightOnramper : iconDarkOnramper, height: 40, width: 40);
return Container(
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 330),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 24),
child: OptionTile(
image: iconRobinhood,
title: "Robinhood Connect",
description: S.of(context).robinhood_option_description,
onPressed: () async =>
await getIt.get<RobinhoodBuyProvider>().launchProvider(context),
),
),
Padding(
padding: EdgeInsets.only(top: 24),
child: OptionTile(
image: iconOnramper,
title: "Onramper",
description: S.of(context).onramper_option_description,
onPressed: () async =>
await getIt.get<OnRamperBuyProvider>().launchProvider(context),
),
),
Spacer(),
Padding(
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
child: Text(
S.of(context).select_buy_provider_notice,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
),
),
),
],
),
),
),
);
}
}

View file

@ -1,304 +0,0 @@
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/fiat_currency.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cw_core/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/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
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).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFocus,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
height: 0,
color: Theme.of(context).colorScheme.background,
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).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
], 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: GestureDetector(
onTap: () {
showPopUp<void>(
context: context,
builder: (_) => Picker(
hintText: S.current.search_currency,
items: FiatCurrency.currenciesAvailableToBuyWith,
selectedAtIndex:
FiatCurrency.currenciesAvailableToBuyWith.indexOf(buyViewModel.fiatCurrency),
onItemSelected: (FiatCurrency selectedCurrency) {
buyViewModel.buyAmountViewModel.fiatCurrency = selectedCurrency;
},
images: FiatCurrency.currenciesAvailableToBuyWith
.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png"))
.toList(),
isGridView: true,
matchingCriteria: (FiatCurrency currency, String searchText) {
return currency.title.toLowerCase().contains(searchText) ||
currency.fullName.toLowerCase().contains(searchText);
},
),
);
},
child: Padding(
padding: EdgeInsets.only(top: 2),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.keyboard_arrow_down, color: Colors.white),
Text(
buyViewModel.fiatCurrency.title + ': ',
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
],
),
),
),
hintText: '0.00',
borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
borderWidth: 0.5,
textStyle: TextStyle(fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
placeholderTextStyle: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
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).extension<CakeTextTheme>()!.titleColor,
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;
double achAmount;
int minAmount;
if (snapshot.hasData && snapshot.data != null) {
sourceAmount = snapshot.data!.sourceAmount;
destAmount = snapshot.data!.destAmount;
minAmount = snapshot.data!.minAmount;
achAmount = snapshot.data!.achSourceAmount ?? 0;
} else {
sourceAmount = 0.0;
destAmount = 0.0;
minAmount = 0;
achAmount = 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,
achSourceAmount: achAmount,
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).primaryColor,
textColor: Colors.white,
isLoading: buyViewModel.isRunning,
isDisabled: (buyViewModel.selectedProvider == null) ||
buyViewModel.isDisabled
);
})
)
)
);
}
void onSelectBuyProvider({required BuildContext context, required BuyProvider provider,
required double sourceAmount, required 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({required 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;
}
}

View file

@ -2,6 +2,7 @@ import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/option_tile.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart'; import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
import 'package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart'; import 'package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart';
@ -9,7 +10,6 @@ import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/src/screens/restore/widgets/restore_button.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
@ -35,7 +35,7 @@ class RestoreOptionsPage extends BasePage {
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
RestoreButton( OptionTile(
onPressed: () => Navigator.pushNamed( onPressed: () => Navigator.pushNamed(
context, Routes.restoreWalletFromSeedKeys, context, Routes.restoreWalletFromSeedKeys,
arguments: isNewInstall), arguments: isNewInstall),
@ -45,7 +45,7 @@ class RestoreOptionsPage extends BasePage {
if (isNewInstall) if (isNewInstall)
Padding( Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: RestoreButton( child: OptionTile(
onPressed: () => Navigator.pushNamed(context, Routes.restoreFromBackup), onPressed: () => Navigator.pushNamed(context, Routes.restoreFromBackup),
image: imageBackup, image: imageBackup,
title: S.of(context).restore_title_from_backup, title: S.of(context).restore_title_from_backup,
@ -53,7 +53,7 @@ class RestoreOptionsPage extends BasePage {
), ),
Padding( Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: RestoreButton( child: OptionTile(
onPressed: () async { onPressed: () async {
bool isPinSet = false; bool isPinSet = false;
if (isNewInstall) { if (isNewInstall) {

View file

@ -1,74 +0,0 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class RestoreButton extends StatelessWidget {
const RestoreButton(
{required this.onPressed,
required this.image,
required this.title,
required this.description});
final VoidCallback onPressed;
final Image image;
final String title;
final String description;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPressed,
child: Container(
width: double.infinity,
height: 170,
padding: EdgeInsets.all(24),
alignment: Alignment.topLeft,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12)),
color: Theme.of(context).cardColor,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
image,
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 16),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
description,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.extension<TransactionTradeTheme>()!
.detailsTitlesColor,
),
),
)
],
),
),
)
],
),
),
);
}
}

View file

@ -1,3 +1,5 @@
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/entities/buy_provider_types.dart';
import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -33,6 +35,13 @@ class OtherSettingsPage extends BasePage {
selectedItem: _otherSettingsViewModel.transactionPriority, selectedItem: _otherSettingsViewModel.transactionPriority,
onItemSelected: _otherSettingsViewModel.onDisplayPrioritySelected, onItemSelected: _otherSettingsViewModel.onDisplayPrioritySelected,
), ),
SettingsPickerCell(
title: S.current.default_buy_provider,
items: BuyProviderType.values,
displayItem: _otherSettingsViewModel.getBuyProviderType,
selectedItem: _otherSettingsViewModel.buyProviderType,
onItemSelected: _otherSettingsViewModel.onBuyProviderTypeSelected,
),
SettingsCellWithArrow( SettingsCellWithArrow(
title: S.current.settings_terms_and_conditions, title: S.current.settings_terms_and_conditions,
handler: (BuildContext context) => handler: (BuildContext context) =>

View file

@ -25,4 +25,4 @@ class SettingsVersionCell extends StatelessWidget {
), ),
); );
} }
} }

View file

@ -1,7 +1,7 @@
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/support/widgets/support_tiles.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/option_tile.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/view_model/support_view_model.dart'; import 'package:cake_wallet/view_model/support_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -32,7 +32,7 @@ class SupportPage extends BasePage {
children: [ children: [
Padding( Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: SupportTile( child: OptionTile(
image: imageLiveSupport, image: imageLiveSupport,
title: S.of(context).support_title_live_chat, title: S.of(context).support_title_live_chat,
description: S.of(context).support_description_live_chat, description: S.of(context).support_description_live_chat,
@ -47,7 +47,7 @@ class SupportPage extends BasePage {
), ),
Padding( Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: SupportTile( child: OptionTile(
image: imageWalletGuides, image: imageWalletGuides,
title: S.of(context).support_title_guides, title: S.of(context).support_title_guides,
description: S.of(context).support_description_guides, description: S.of(context).support_description_guides,
@ -56,7 +56,7 @@ class SupportPage extends BasePage {
), ),
Padding( Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: SupportTile( child: OptionTile(
image: imageMoreLinks, image: imageMoreLinks,
title: S.of(context).support_title_other_links, title: S.of(context).support_title_other_links,
description: S.of(context).support_description_other_links, description: S.of(context).support_description_other_links,

View file

@ -1,9 +1,8 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SupportTile extends StatelessWidget { class OptionTile extends StatelessWidget {
const SupportTile( const OptionTile(
{required this.onPressed, {required this.onPressed,
required this.image, required this.image,
required this.title, required this.title,
@ -45,7 +44,7 @@ class SupportTile extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor, color: Theme.of(context).extension<OptionTileTheme>()!.titleColor,
), ),
), ),
Padding( Padding(
@ -55,7 +54,7 @@ class SupportTile extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor, color: Theme.of(context).extension<OptionTileTheme>()!.descriptionColor,
), ),
), ),
) )

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart'; import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
import 'package:cake_wallet/entities/buy_provider_types.dart';
import 'package:cake_wallet/entities/cake_2fa_preset_options.dart'; import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
import 'package:cake_wallet/entities/background_tasks.dart'; import 'package:cake_wallet/entities/background_tasks.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart';
@ -47,6 +48,7 @@ abstract class SettingsStoreBase with Store {
required bool initialAppSecure, required bool initialAppSecure,
required bool initialDisableBuy, required bool initialDisableBuy,
required bool initialDisableSell, required bool initialDisableSell,
required BuyProviderType initialDefaultBuyProvider,
required FiatApiMode initialFiatMode, required FiatApiMode initialFiatMode,
required bool initialAllowBiometricalAuthentication, required bool initialAllowBiometricalAuthentication,
required String initialTotpSecretKey, required String initialTotpSecretKey,
@ -99,6 +101,7 @@ abstract class SettingsStoreBase with Store {
isAppSecure = initialAppSecure, isAppSecure = initialAppSecure,
disableBuy = initialDisableBuy, disableBuy = initialDisableBuy,
disableSell = initialDisableSell, disableSell = initialDisableSell,
defaultBuyProvider = initialDefaultBuyProvider,
shouldShowMarketPlaceInDashboard = initialShouldShowMarketPlaceInDashboard, shouldShowMarketPlaceInDashboard = initialShouldShowMarketPlaceInDashboard,
exchangeStatus = initialExchangeStatus, exchangeStatus = initialExchangeStatus,
currentTheme = initialTheme, currentTheme = initialTheme,
@ -200,6 +203,11 @@ abstract class SettingsStoreBase with Store {
(bool disableSell) => (bool disableSell) =>
sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell)); sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell));
reaction(
(_) => defaultBuyProvider,
(BuyProviderType defaultBuyProvider) =>
sharedPreferences.setInt(PreferencesKey.defaultBuyProvider, defaultBuyProvider.index));
reaction( reaction(
(_) => autoGenerateSubaddressStatus, (_) => autoGenerateSubaddressStatus,
(AutoGenerateSubaddressStatus autoGenerateSubaddressStatus) => sharedPreferences.setInt( (AutoGenerateSubaddressStatus autoGenerateSubaddressStatus) => sharedPreferences.setInt(
@ -380,6 +388,9 @@ abstract class SettingsStoreBase with Store {
@observable @observable
bool disableSell; bool disableSell;
@observable
BuyProviderType defaultBuyProvider;
@observable @observable
bool allowBiometricalAuthentication; bool allowBiometricalAuthentication;
@ -535,6 +546,7 @@ abstract class SettingsStoreBase with Store {
final isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? false; final isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? false;
final disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? false; final disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? false;
final disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? false; final disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? false;
final defaultBuyProvider = BuyProviderType.values[sharedPreferences.getInt(PreferencesKey.defaultBuyProvider) ?? 0];
final currentFiatApiMode = FiatApiMode.deserialize( final currentFiatApiMode = FiatApiMode.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ?? raw: sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ??
FiatApiMode.enabled.raw); FiatApiMode.enabled.raw);
@ -661,6 +673,7 @@ abstract class SettingsStoreBase with Store {
initialAppSecure: isAppSecure, initialAppSecure: isAppSecure,
initialDisableBuy: disableBuy, initialDisableBuy: disableBuy,
initialDisableSell: disableSell, initialDisableSell: disableSell,
initialDefaultBuyProvider: defaultBuyProvider,
initialFiatMode: currentFiatApiMode, initialFiatMode: currentFiatApiMode,
initialAllowBiometricalAuthentication: allowBiometricalAuthentication, initialAllowBiometricalAuthentication: allowBiometricalAuthentication,
initialCake2FAPresetOptions: selectedCake2FAPreset, initialCake2FAPresetOptions: selectedCake2FAPreset,
@ -747,6 +760,7 @@ abstract class SettingsStoreBase with Store {
isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure; isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure;
disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? disableBuy; disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? disableBuy;
disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? disableSell; disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? disableSell;
defaultBuyProvider = BuyProviderType.values[sharedPreferences.getInt(PreferencesKey.defaultBuyProvider) ?? 0];
allowBiometricalAuthentication = allowBiometricalAuthentication =
sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
allowBiometricalAuthentication; allowBiometricalAuthentication;

View file

@ -12,6 +12,7 @@ import 'package:cake_wallet/themes/extensions/info_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart'; import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart'; import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart'; import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/order_theme.dart'; import 'package:cake_wallet/themes/extensions/order_theme.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart'; import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:cake_wallet/themes/extensions/pin_code_theme.dart'; import 'package:cake_wallet/themes/extensions/pin_code_theme.dart';
@ -215,6 +216,10 @@ class DarkTheme extends ThemeBase {
qrCodeColor: PaletteDark.lightBlueGrey, qrCodeColor: PaletteDark.lightBlueGrey,
qrWidgetCopyButtonColor: PaletteDark.lightBlueGrey); qrWidgetCopyButtonColor: PaletteDark.lightBlueGrey);
@override
OptionTileTheme get optionTileTheme => OptionTileTheme(
titleColor: primaryTextColor, descriptionColor: primaryTextColor, useDarkImage: false);
@override @override
ThemeData get themeData => super.themeData.copyWith( ThemeData get themeData => super.themeData.copyWith(
dividerColor: PaletteDark.dividerColor, dividerColor: PaletteDark.dividerColor,

View file

@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
class OptionTileTheme extends ThemeExtension<OptionTileTheme> {
final Color titleColor;
final Color descriptionColor;
final bool useDarkImage;
OptionTileTheme(
{required this.titleColor, required this.descriptionColor, this.useDarkImage = false});
@override
OptionTileTheme copyWith({Color? titleColor, Color? descriptionColor, bool? useDarkImage}) =>
OptionTileTheme(
titleColor: titleColor ?? this.titleColor,
descriptionColor: descriptionColor ?? this.descriptionColor,
useDarkImage: useDarkImage ?? this.useDarkImage);
@override
OptionTileTheme lerp(ThemeExtension<OptionTileTheme>? other, double t) {
if (other is! OptionTileTheme) {
return this;
}
return OptionTileTheme(
titleColor: Color.lerp(titleColor, other.titleColor, t) ?? titleColor,
descriptionColor:
Color.lerp(descriptionColor, other.descriptionColor, t) ?? descriptionColor,
useDarkImage: other.useDarkImage);
}
}

View file

@ -9,6 +9,7 @@ import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:cake_wallet/themes/extensions/indicator_dot_theme.dart'; import 'package:cake_wallet/themes/extensions/indicator_dot_theme.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart'; import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart'; import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart'; import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart'; import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
@ -103,6 +104,10 @@ class HighContrastTheme extends MoneroLightTheme {
ReceivePageTheme get receivePageTheme => super.receivePageTheme.copyWith( ReceivePageTheme get receivePageTheme => super.receivePageTheme.copyWith(
tilesTextColor: Colors.white, iconsBackgroundColor: Colors.grey, iconsColor: Colors.black); tilesTextColor: Colors.white, iconsBackgroundColor: Colors.grey, iconsColor: Colors.black);
@override
OptionTileTheme get optionTileTheme => OptionTileTheme(
titleColor: Colors.white, descriptionColor: Colors.white, useDarkImage: false);
@override @override
ThemeData get themeData => super.themeData.copyWith( ThemeData get themeData => super.themeData.copyWith(
disabledColor: Colors.grey, disabledColor: Colors.grey,

View file

@ -12,6 +12,7 @@ import 'package:cake_wallet/themes/extensions/info_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart'; import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart'; import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart'; import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/order_theme.dart'; import 'package:cake_wallet/themes/extensions/order_theme.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart'; import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:cake_wallet/themes/extensions/pin_code_theme.dart'; import 'package:cake_wallet/themes/extensions/pin_code_theme.dart';
@ -215,6 +216,10 @@ class LightTheme extends ThemeBase {
qrCodeColor: Colors.white, qrCodeColor: Colors.white,
qrWidgetCopyButtonColor: PaletteDark.lightBlueGrey); qrWidgetCopyButtonColor: PaletteDark.lightBlueGrey);
@override
OptionTileTheme get optionTileTheme => OptionTileTheme(
titleColor: primaryTextColor, descriptionColor: primaryTextColor, useDarkImage: true);
@override @override
ThemeData get themeData => super.themeData.copyWith( ThemeData get themeData => super.themeData.copyWith(
dividerColor: Palette.paleBlue, dividerColor: Palette.paleBlue,

View file

@ -12,6 +12,7 @@ import 'package:cake_wallet/themes/extensions/info_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart'; import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart'; import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart'; import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/order_theme.dart'; import 'package:cake_wallet/themes/extensions/order_theme.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart'; import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:cake_wallet/themes/extensions/pin_code_theme.dart'; import 'package:cake_wallet/themes/extensions/pin_code_theme.dart';
@ -114,6 +115,8 @@ abstract class ThemeBase {
QRCodeTheme get qrCodeTheme; QRCodeTheme get qrCodeTheme;
OptionTileTheme get optionTileTheme;
ThemeData get themeData => generatedThemeData.copyWith( ThemeData get themeData => generatedThemeData.copyWith(
primaryColor: primaryColor, primaryColor: primaryColor,
cardColor: containerColor, cardColor: containerColor,
@ -144,6 +147,7 @@ abstract class ThemeBase {
accountListTheme, accountListTheme,
receivePageTheme, receivePageTheme,
qrCodeTheme, qrCodeTheme,
optionTileTheme
], ],
scrollbarTheme: generatedThemeData.scrollbarTheme.copyWith( scrollbarTheme: generatedThemeData.scrollbarTheme.copyWith(
thumbColor: MaterialStateProperty.all(scrollbarTheme.thumbColor), thumbColor: MaterialStateProperty.all(scrollbarTheme.thumbColor),

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart'; import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
import 'package:cake_wallet/entities/buy_provider_types.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart'; import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart'; import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
@ -277,6 +278,9 @@ abstract class DashboardViewModelBase with Store {
Map<String, List<FilterItem>> filterItems; Map<String, List<FilterItem>> filterItems;
BuyProviderType get defaultBuyProvider => settingsStore.defaultBuyProvider;
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled; bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup; bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/buy_provider_types.dart';
import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/balance.dart'; import 'package:cw_core/balance.dart';
@ -48,6 +49,9 @@ abstract class OtherSettingsViewModelBase with Store {
return priority; return priority;
} }
@computed
BuyProviderType get buyProviderType { return _settingsStore.defaultBuyProvider; }
String getDisplayPriority(dynamic priority) { String getDisplayPriority(dynamic priority) {
final _priority = priority as TransactionPriority; final _priority = priority as TransactionPriority;
@ -59,6 +63,16 @@ abstract class OtherSettingsViewModelBase with Store {
return priority.toString(); return priority.toString();
} }
String getBuyProviderType (dynamic buyProviderType) {
final _buyProviderType = buyProviderType as BuyProviderType;
return _buyProviderType.toString();
}
void onDisplayPrioritySelected(TransactionPriority priority) => void onDisplayPrioritySelected(TransactionPriority priority) =>
_settingsStore.priority[_wallet.type] = priority; _settingsStore.priority[_wallet.type] = priority;
void onBuyProviderTypeSelected(BuyProviderType buyProviderType) =>
_settingsStore.defaultBuyProvider = buyProviderType;
} }

View file

@ -682,7 +682,11 @@
"support_title_other_links": "روابط دعم أخرى", "support_title_other_links": "روابط دعم أخرى",
"support_description_other_links": "انضم إلى مجتمعاتنا أو تصل إلينا شركائنا من خلال أساليب أخرى", "support_description_other_links": "انضم إلى مجتمعاتنا أو تصل إلينا شركائنا من خلال أساليب أخرى",
"select_destination": ".ﻲﻃﺎﻴﺘﺣﻻﺍ ﺦﺴﻨﻟﺍ ﻒﻠﻣ ﺔﻬﺟﻭ ﺪﻳﺪﺤﺗ ءﺎﺟﺮﻟﺍ", "select_destination": ".ﻲﻃﺎﻴﺘﺣﻻﺍ ﺦﺴﻨﻟﺍ ﻒﻠﻣ ﺔﻬﺟﻭ ﺪﻳﺪﺤﺗ ءﺎﺟﺮﻟﺍ",
"auto_generate_subaddresses": "تلقائي توليد subddresses",
"save_to_downloads": "ﺕﻼﻳﺰﻨﺘﻟﺍ ﻲﻓ ﻆﻔﺣ", "save_to_downloads": "ﺕﻼﻳﺰﻨﺘﻟﺍ ﻲﻓ ﻆﻔﺣ",
"support_description_other_links": "انضم إلى مجتمعاتنا أو تصل إلينا شركائنا من خلال أساليب أخرى", "select_buy_provider_notice": "حدد مزود شراء أعلاه. يمكنك تخطي هذه الشاشة عن طريق تعيين مزود شراء الافتراضي في إعدادات التطبيق.",
"auto_generate_subaddresses": "تلقائي توليد subddresses" "onramper_option_description": "شراء بسرعة التشفير مع العديد من طرق الدفع. متوفر في معظم البلدان. ينتشر وتختلف الرسوم.",
} "default_buy_provider": "مزود شراء الافتراضي",
"ask_each_time": "اسأل في كل مرة",
"buy_provider_unavailable": "مزود حاليا غير متوفر."
}

View file

@ -679,5 +679,10 @@
"support_title_other_links": "Други връзки за поддръжка", "support_title_other_links": "Други връзки за поддръжка",
"support_description_other_links": "Присъединете се към нашите общности или се свържете с нас нашите партньори чрез други методи", "support_description_other_links": "Присъединете се към нашите общности или се свържете с нас нашите партньори чрез други методи",
"select_destination": "Моля, изберете дестинация за архивния файл.", "select_destination": "Моля, изберете дестинация за архивния файл.",
"save_to_downloads": "Запазване в Изтегляния" "save_to_downloads": "Запазване в Изтегляния",
} "select_buy_provider_notice": "Изберете доставчик на покупка по -горе. Можете да пропуснете този екран, като зададете вашия доставчик по подразбиране по подразбиране в настройките на приложението.",
"onramper_option_description": "Бързо купувайте криптовалута с много методи за плащане. Предлага се в повечето страни. Разпространенията и таксите варират.",
"default_buy_provider": "Доставчик по подразбиране купува",
"ask_each_time": "Питайте всеки път",
"buy_provider_unavailable": "Понастоящем доставчик не е наличен."
}

View file

@ -679,5 +679,10 @@
"support_title_other_links": "Další odkazy na podporu", "support_title_other_links": "Další odkazy na podporu",
"support_description_other_links": "Připojte se k našim komunitám nebo se k nám oslovte další metody", "support_description_other_links": "Připojte se k našim komunitám nebo se k nám oslovte další metody",
"select_destination": "Vyberte cíl pro záložní soubor.", "select_destination": "Vyberte cíl pro záložní soubor.",
"save_to_downloads": "Uložit do Stažených souborů" "save_to_downloads": "Uložit do Stažených souborů",
} "select_buy_provider_notice": "Vyberte výše uvedeného poskytovatele nákupu. Tuto obrazovku můžete přeskočit nastavením výchozího poskytovatele nákupu v nastavení aplikace.",
"onramper_option_description": "Rychle si koupte krypto s mnoha metodami plateb. K dispozici ve většině zemí. Rozpětí a poplatky se liší.",
"default_buy_provider": "Výchozí poskytovatel nákupu",
"ask_each_time": "Zeptejte se pokaždé",
"buy_provider_unavailable": "Poskytovatel aktuálně nedostupný."
}

View file

@ -364,8 +364,8 @@
"enter_your_note": "Geben Sie Ihre Bemerkung ein…", "enter_your_note": "Geben Sie Ihre Bemerkung ein…",
"note_optional": "Bemerkung (optional)", "note_optional": "Bemerkung (optional)",
"note_tap_to_change": "Bemerkung (zum Ändern tippen)", "note_tap_to_change": "Bemerkung (zum Ändern tippen)",
"view_in_block_explorer": "View in Block Explorer", "view_in_block_explorer": "In Block Explorer anzeigen",
"view_transaction_on": "View Transaction on ", "view_transaction_on": "Anzeigen der Transaktion auf ",
"transaction_key": "Transaktionsschlüssel", "transaction_key": "Transaktionsschlüssel",
"confirmations": "Bestätigungen", "confirmations": "Bestätigungen",
"recipient_address": "Empfängeradresse", "recipient_address": "Empfängeradresse",
@ -405,11 +405,11 @@
"moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein", "moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein",
"outdated_electrum_wallet_receive_warning": "Wenn diese Wallet einen 12-Wort-Seed hat und in Cake erstellt wurde, zahlen Sie KEINE Bitcoins in diese Wallet 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", "outdated_electrum_wallet_receive_warning": "Wenn diese Wallet einen 12-Wort-Seed hat und in Cake erstellt wurde, zahlen Sie KEINE Bitcoins in diese Wallet 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", "do_not_show_me": "Zeig mir das nicht noch einmal",
"unspent_coins_title": "Nicht ausgegebene Münzen", "unspent_coins_title": "Nicht ausgegebene Coins",
"unspent_coins_details_title": "Details zu nicht ausgegebenen Münzen", "unspent_coins_details_title": "Details zu nicht ausgegebenen Coins",
"freeze": "Einfrieren", "freeze": "Einfrieren",
"frozen": "Gefroren", "frozen": "Gefroren",
"coin_control": "Münzkontrolle (optional)", "coin_control": "Coin Control (optional)",
"address_detected": "Adresse erkannt", "address_detected": "Adresse erkannt",
"address_from_domain": "Diese Adresse ist von ${domain} auf Unstoppable Domains", "address_from_domain": "Diese Adresse ist von ${domain} auf Unstoppable Domains",
"add_receiver": "Fügen Sie einen weiteren Empfänger hinzu (optional)", "add_receiver": "Fügen Sie einen weiteren Empfänger hinzu (optional)",
@ -551,7 +551,7 @@
"custom_redeem_amount": "Benutzerdefinierter Einlösungsbetrag", "custom_redeem_amount": "Benutzerdefinierter Einlösungsbetrag",
"add_custom_redemption": "Benutzerdefinierte Einlösung hinzufügen", "add_custom_redemption": "Benutzerdefinierte Einlösung hinzufügen",
"remaining": "Rest", "remaining": "Rest",
"delete_wallet": "Geldbörse löschen", "delete_wallet": "Wallet löschen",
"delete_wallet_confirm_message": "Sind Sie sicher, dass Sie das ${wallet_name} Wallet löschen möchten?", "delete_wallet_confirm_message": "Sind Sie sicher, dass Sie das ${wallet_name} Wallet löschen möchten?",
"low_fee": "Niedrige Gebühr", "low_fee": "Niedrige Gebühr",
"low_fee_alert": "Sie verwenden derzeit eine niedrige Netzwerkgebührenpriorität. Dies kann zu langen Wartezeiten, unterschiedlichen Kursen oder stornierten Trades führen. Wir empfehlen, für ein besseres Erlebnis eine höhere Gebühr festzulegen.", "low_fee_alert": "Sie verwenden derzeit eine niedrige Netzwerkgebührenpriorität. Dies kann zu langen Wartezeiten, unterschiedlichen Kursen oder stornierten Trades führen. Wir empfehlen, für ein besseres Erlebnis eine höhere Gebühr festzulegen.",
@ -560,7 +560,7 @@
"do_not_share_warning_text": "Teilen Sie diese nicht mit anderen, einschließlich Support.\n\nIhr Geld kann und wird gestohlen werden!", "do_not_share_warning_text": "Teilen Sie diese nicht mit anderen, einschließlich Support.\n\nIhr Geld kann und wird gestohlen werden!",
"help": "hilfe", "help": "hilfe",
"all_transactions": "Alle Transaktionen", "all_transactions": "Alle Transaktionen",
"all_trades": "Alle Gewerke", "all_trades": "Alle Trades",
"connection_sync": "Verbindung und Synchronisierung", "connection_sync": "Verbindung und Synchronisierung",
"security_and_backup": "Sicherheit und Datensicherung", "security_and_backup": "Sicherheit und Datensicherung",
"create_backup": "Backup erstellen", "create_backup": "Backup erstellen",
@ -583,7 +583,7 @@
"unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein", "unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein",
"orbot_running_alert": "Bitte stellen Sie sicher, dass Orbot läuft, bevor Sie sich mit diesem Knoten verbinden.", "orbot_running_alert": "Bitte stellen Sie sicher, dass Orbot läuft, bevor Sie sich mit diesem Knoten verbinden.",
"contact_list_contacts": "Kontakte", "contact_list_contacts": "Kontakte",
"contact_list_wallets": "Meine Geldbörsen", "contact_list_wallets": "Meine Wallets",
"bitcoin_payments_require_1_confirmation": "Bitcoin-Zahlungen erfordern 1 Bestätigung, was 20 Minuten oder länger dauern kann. Danke für Ihre Geduld! Sie erhalten eine E-Mail, wenn die Zahlung bestätigt ist.", "bitcoin_payments_require_1_confirmation": "Bitcoin-Zahlungen erfordern 1 Bestätigung, was 20 Minuten oder länger dauern kann. Danke für Ihre Geduld! Sie erhalten eine E-Mail, wenn die Zahlung bestätigt ist.",
"send_to_this_address": "Senden Sie ${currency} ${tag}an diese Adresse", "send_to_this_address": "Senden Sie ${currency} ${tag}an diese Adresse",
"arrive_in_this_address": "${currency} ${tag}wird an dieser Adresse ankommen", "arrive_in_this_address": "${currency} ${tag}wird an dieser Adresse ankommen",
@ -592,8 +592,8 @@
"scan_qr_code": "QR-Code scannen", "scan_qr_code": "QR-Code scannen",
"cold_or_recover_wallet": "Fügen Sie eine Cold Wallet hinzu oder stellen Sie eine Paper Wallet wieder her", "cold_or_recover_wallet": "Fügen Sie eine Cold Wallet hinzu oder stellen Sie eine Paper Wallet wieder her",
"please_wait": "Warten Sie mal", "please_wait": "Warten Sie mal",
"sweeping_wallet": "Kehre Geldbörse", "sweeping_wallet": "Wallet leeren",
"sweeping_wallet_alert": "Das sollte nicht lange dauern. VERLASSEN SIE DIESEN BILDSCHIRM NICHT, ANDERNFALLS KÖNNEN DIE SWEPT-GELDER VERLOREN GEHEN", "sweeping_wallet_alert": "Das sollte nicht lange dauern. VERLASSEN SIE DIESEN BILDSCHIRM NICHT, ANDERNFALLS KÖNNEN DIE GELDER VERLOREN GEHEN",
"decimal_places_error": "Zu viele Nachkommastellen", "decimal_places_error": "Zu viele Nachkommastellen",
"edit_node": "Knoten bearbeiten", "edit_node": "Knoten bearbeiten",
"frozen_balance": "Gefrorenes Guthaben", "frozen_balance": "Gefrorenes Guthaben",
@ -630,7 +630,7 @@
"add_secret_code": "Fügen Sie diesen Geheimcode einem anderen Gerät hinzu", "add_secret_code": "Fügen Sie diesen Geheimcode einem anderen Gerät hinzu",
"totp_secret_code": "TOTP-Geheimcode", "totp_secret_code": "TOTP-Geheimcode",
"important_note": "Wichtiger Hinweis", "important_note": "Wichtiger Hinweis",
"setup_2fa_text": "Cake 2FA ist NICHT so sicher wie eine Kühllagerung. 2FA schützt vor grundlegenden Arten von Angriffen, z. B. wenn Ihr Freund Ihren Fingerabdruck bereitstellt, während Sie schlafen.\n\n Cake 2FA schützt NICHT vor einem kompromittierten Gerät durch einen raffinierten Angreifer.\n\n Wenn Sie den Zugriff auf Ihre 2FA-Codes verlieren , VERLIEREN SIE DEN ZUGANG ZU DIESEM WALLET. Sie müssen Ihre Wallet aus mnemonic Seed wiederherstellen. SIE MÜSSEN DESHALB IHRE MNEMONISCHEN SEEDS SICHERN! Außerdem kann jemand mit Zugriff auf Ihre mnemonischen Seed(s) Ihr Geld stehlen und Cake 2FA umgehen.\n\n Cake-Supportmitarbeiter können Ihnen nicht helfen, wenn Sie den Zugriff auf Ihre mnemonischen Seed(s) verlieren, da Cake Wallet eine Wallet ohne treuhänderische Verwahrung ist.", "setup_2fa_text": "Cake 2FA ist NICHT so sicher wie eine Cold Wallet. 2FA schützt vor grundlegenden Arten von Angriffen, z.B. wenn Ihr Freund Ihren Fingerabdruck verwendet, während Sie schlafen.\n\n Cake 2FA schützt NICHT vor einem kompromittierten Gerät durch einen raffinierten Angreifer.\n\n Wenn Sie den Zugriff auf Ihre 2FA-Codes verlieren , VERLIEREN SIE DEN ZUGANG ZU DIESEM WALLET. Sie müssen Ihre Wallet aus mnemonic Seed wiederherstellen. SIE MÜSSEN DESHALB IHRE MNEMONISCHEN SEEDS SICHERN! Außerdem kann jemand mit Zugriff auf Ihre mnemonischen Seed(s) Ihr Geld stehlen und Cake 2FA umgehen.\n\n Cake-Supportmitarbeiter können Ihnen nicht helfen, wenn Sie den Zugriff auf Ihre mnemonischen Seed(s) verlieren, da Cake Wallet eine Wallet ohne treuhänderische Verwahrung ist.",
"setup_totp_recommended": "TOTP einrichten (empfohlen)", "setup_totp_recommended": "TOTP einrichten (empfohlen)",
"disable_buy": "Kaufaktion deaktivieren", "disable_buy": "Kaufaktion deaktivieren",
"disable_sell": "Verkaufsaktion deaktivieren", "disable_sell": "Verkaufsaktion deaktivieren",
@ -641,7 +641,7 @@
"matrix_green_dark_theme": "Matrix Green Dark Theme", "matrix_green_dark_theme": "Matrix Green Dark Theme",
"monero_light_theme": "Monero Light-Thema", "monero_light_theme": "Monero Light-Thema",
"auto_generate_subaddresses": "Unteradressen automatisch generieren", "auto_generate_subaddresses": "Unteradressen automatisch generieren",
"cake_2fa_preset" : "Cake 2FA-Voreinstellung", "cake_2fa_preset": "Cake 2FA-Voreinstellung",
"narrow": "Eng", "narrow": "Eng",
"normal": "Normal", "normal": "Normal",
"aggressive": "Übereifrig", "aggressive": "Übereifrig",
@ -675,7 +675,7 @@
"alphabetical": "Alphabetisch", "alphabetical": "Alphabetisch",
"generate_name": "Namen generieren", "generate_name": "Namen generieren",
"balance_page": "Balance-Seite", "balance_page": "Balance-Seite",
"share": "Aktie", "share": "Teilen",
"slidable": "Verschiebbar", "slidable": "Verschiebbar",
"manage_nodes": "Knoten verwalten", "manage_nodes": "Knoten verwalten",
"etherscan_history": "Etherscan-Geschichte", "etherscan_history": "Etherscan-Geschichte",
@ -687,5 +687,10 @@
"support_title_other_links": "Andere Support-Links", "support_title_other_links": "Andere Support-Links",
"support_description_other_links": "Treten Sie unseren Communities bei oder erreichen Sie uns oder unsere Partner über andere Methoden", "support_description_other_links": "Treten Sie unseren Communities bei oder erreichen Sie uns oder unsere Partner über andere Methoden",
"select_destination": "Bitte wählen Sie das Ziel für die Sicherungsdatei aus.", "select_destination": "Bitte wählen Sie das Ziel für die Sicherungsdatei aus.",
"save_to_downloads": "Unter „Downloads“ speichern" "save_to_downloads": "Unter „Downloads“ speichern",
} "select_buy_provider_notice": "Wählen Sie oben einen Anbieter kaufen. Sie können diese Seite überspringen, indem Sie Ihren Standard-Kaufanbieter in den App-Einstellungen festlegen.",
"onramper_option_description": "Kaufen Sie schnell Krypto mit vielen Zahlungsmethoden. In den meisten Ländern erhältlich. Spreads und Gebühren variieren.",
"default_buy_provider": "Standard-Kaufanbieter",
"ask_each_time": "Jedes Mal fragen",
"buy_provider_unavailable": "Anbieter derzeit nicht verfügbar."
}

View file

@ -687,5 +687,11 @@
"support_title_other_links": "Other support links", "support_title_other_links": "Other support links",
"support_description_other_links": "Join our communities or reach us our our partners through other methods", "support_description_other_links": "Join our communities or reach us our our partners through other methods",
"select_destination": "Please select destination for the backup file.", "select_destination": "Please select destination for the backup file.",
"save_to_downloads": "Save to Downloads" "save_to_downloads": "Save to Downloads",
} "select_buy_provider_notice": "Select a buy provider above. You can skip this screen by setting your default buy provider in app settings.",
"onramper_option_description": "Quickly buy crypto with many payment methods. Available in most countries. Spreads and fees vary.",
"default_buy_provider": "Default Buy Provider",
"ask_each_time": "Ask each time",
"robinhood_option_description": "Buy and transfer instantly using your debit card, bank account, or Robinhood balance. USA only.",
"buy_provider_unavailable": "Provider currently unavailable."
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "Otros enlaces de soporte", "support_title_other_links": "Otros enlaces de soporte",
"support_description_other_links": "Únase a nuestras comunidades o comuníquese con nosotros nuestros socios a través de otros métodos", "support_description_other_links": "Únase a nuestras comunidades o comuníquese con nosotros nuestros socios a través de otros métodos",
"select_destination": "Seleccione el destino del archivo de copia de seguridad.", "select_destination": "Seleccione el destino del archivo de copia de seguridad.",
"save_to_downloads": "Guardar en Descargas" "save_to_downloads": "Guardar en Descargas",
} "select_buy_provider_notice": "Seleccione un proveedor de compra arriba. Puede omitir esta pantalla configurando su proveedor de compra predeterminado en la configuración de la aplicación.",
"onramper_option_description": "Compre rápidamente cripto con muchos métodos de pago. Disponible en la mayoría de los países. Los diferenciales y las tarifas varían.",
"default_buy_provider": "Proveedor de compra predeterminado",
"ask_each_time": "Pregunta cada vez",
"buy_provider_unavailable": "Proveedor actualmente no disponible."
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "Autres liens d'assistance", "support_title_other_links": "Autres liens d'assistance",
"support_description_other_links": "Rejoignez nos communautés ou contactez-nous nos partenaires à travers d'autres méthodes", "support_description_other_links": "Rejoignez nos communautés ou contactez-nous nos partenaires à travers d'autres méthodes",
"select_destination": "Veuillez sélectionner la destination du fichier de sauvegarde.", "select_destination": "Veuillez sélectionner la destination du fichier de sauvegarde.",
"save_to_downloads": "Enregistrer dans les téléchargements" "save_to_downloads": "Enregistrer dans les téléchargements",
} "select_buy_provider_notice": "Sélectionnez un fournisseur d'achat ci-dessus. Vous pouvez ignorer cet écran en définissant votre fournisseur d'achat par défaut dans les paramètres de l'application.",
"onramper_option_description": "Achetez rapidement la crypto avec de nombreux méthodes de paiement. Disponible dans la plupart des pays. Les écarts et les frais varient.",
"default_buy_provider": "Fournisseur d'achat par défaut",
"ask_each_time": "Demandez à chaque fois",
"buy_provider_unavailable": "Fournisseur actuellement indisponible."
}

View file

@ -665,5 +665,10 @@
"support_title_other_links": "Sauran hanyoyin tallafi", "support_title_other_links": "Sauran hanyoyin tallafi",
"support_description_other_links": "Kasance tare da al'ummominmu ko kuma ka kai mu abokanmu ta hanyar wasu hanyoyi", "support_description_other_links": "Kasance tare da al'ummominmu ko kuma ka kai mu abokanmu ta hanyar wasu hanyoyi",
"select_destination": "Da fatan za a zaɓi wurin da za a yi wa madadin fayil ɗin.", "select_destination": "Da fatan za a zaɓi wurin da za a yi wa madadin fayil ɗin.",
"save_to_downloads": "Ajiye zuwa Zazzagewa" "save_to_downloads": "Ajiye zuwa Zazzagewa",
} "select_buy_provider_notice": "Zaɓi mai ba da kyauta a sama. Zaka iya tsallake wannan allon ta hanyar saita mai ba da isasshen busasshen mai ba da isasshen busasshiyar saiti.",
"onramper_option_description": "Da sauri sayi Crypto tare da hanyoyin biyan kuɗi da yawa. Akwai a yawancin ƙasashe. Yaduwa da kudade sun bambanta.",
"default_buy_provider": "Tsohuwar Siyarwa",
"ask_each_time": "Tambaya kowane lokaci",
"buy_provider_unavailable": "Mai ba da kyauta a halin yanzu babu."
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "अन्य समर्थन लिंक", "support_title_other_links": "अन्य समर्थन लिंक",
"support_description_other_links": "हमारे समुदायों में शामिल हों या अन्य तरीकों के माध्यम से हमारे साथी तक पहुंचें", "support_description_other_links": "हमारे समुदायों में शामिल हों या अन्य तरीकों के माध्यम से हमारे साथी तक पहुंचें",
"select_destination": "कृपया बैकअप फ़ाइल के लिए गंतव्य का चयन करें।", "select_destination": "कृपया बैकअप फ़ाइल के लिए गंतव्य का चयन करें।",
"save_to_downloads": "डाउनलोड में सहेजें" "save_to_downloads": "डाउनलोड में सहेजें",
} "select_buy_provider_notice": "ऊपर एक खरीद प्रदाता का चयन करें। आप इस स्क्रीन को ऐप सेटिंग्स में अपना डिफ़ॉल्ट बाय प्रदाता सेट करके छोड़ सकते हैं।",
"onramper_option_description": "जल्दी से कई भुगतान विधियों के साथ क्रिप्टो खरीदें। अधिकांश देशों में उपलब्ध है। फैलता है और फीस अलग -अलग होती है।",
"default_buy_provider": "डिफ़ॉल्ट खरीद प्रदाता",
"ask_each_time": "हर बार पूछें",
"buy_provider_unavailable": "वर्तमान में प्रदाता अनुपलब्ध है।"
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "Ostale veze za podršku", "support_title_other_links": "Ostale veze za podršku",
"support_description_other_links": "Pridružite se našim zajednicama ili nam dosegnu naše partnere drugim metodama", "support_description_other_links": "Pridružite se našim zajednicama ili nam dosegnu naše partnere drugim metodama",
"select_destination": "Odaberite odredište za datoteku sigurnosne kopije.", "select_destination": "Odaberite odredište za datoteku sigurnosne kopije.",
"save_to_downloads": "Spremi u Preuzimanja" "save_to_downloads": "Spremi u Preuzimanja",
} "select_buy_provider_notice": "Odaberite gornji davatelj kupnje. Ovaj zaslon možete preskočiti postavljanjem zadanog davatelja usluga kupnje u postavkama aplikacija.",
"onramper_option_description": "Brzo kupite kriptovalute s mnogim načinima plaćanja. Dostupno u većini zemalja. Širenja i naknade variraju.",
"default_buy_provider": "Zadani davatelj kupnje",
"ask_each_time": "Pitajte svaki put",
"buy_provider_unavailable": "Davatelj trenutno nije dostupan."
}

View file

@ -675,5 +675,10 @@
"support_title_other_links": "Tautan dukungan lainnya", "support_title_other_links": "Tautan dukungan lainnya",
"support_description_other_links": "Bergabunglah dengan komunitas kami atau hubungi kami mitra kami melalui metode lain", "support_description_other_links": "Bergabunglah dengan komunitas kami atau hubungi kami mitra kami melalui metode lain",
"select_destination": "Silakan pilih tujuan untuk file cadangan.", "select_destination": "Silakan pilih tujuan untuk file cadangan.",
"save_to_downloads": "Simpan ke Unduhan" "save_to_downloads": "Simpan ke Unduhan",
} "select_buy_provider_notice": "Pilih penyedia beli di atas. Anda dapat melewatkan layar ini dengan mengatur penyedia pembelian default Anda di pengaturan aplikasi.",
"onramper_option_description": "Beli crypto dengan cepat dengan banyak metode pembayaran. Tersedia di sebagian besar negara. Spread dan biaya bervariasi.",
"default_buy_provider": "Penyedia beli default",
"ask_each_time": "Tanyakan setiap kali",
"buy_provider_unavailable": "Penyedia saat ini tidak tersedia."
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "Altri collegamenti di supporto", "support_title_other_links": "Altri collegamenti di supporto",
"support_description_other_links": "Unisciti alle nostre comunità o raggiungici i nostri partner attraverso altri metodi", "support_description_other_links": "Unisciti alle nostre comunità o raggiungici i nostri partner attraverso altri metodi",
"select_destination": "Seleziona la destinazione per il file di backup.", "select_destination": "Seleziona la destinazione per il file di backup.",
"save_to_downloads": "Salva in Download" "save_to_downloads": "Salva in Download",
} "select_buy_provider_notice": "Seleziona un fornitore di acquisto sopra. È possibile saltare questa schermata impostando il provider di acquisto predefinito nelle impostazioni dell'app.",
"onramper_option_description": "Acquista rapidamente la criptovaluta con molti metodi di pagamento. Disponibile nella maggior parte dei paesi. Gli spread e le commissioni variano.",
"default_buy_provider": "Provider di acquisto predefinito",
"ask_each_time": "Chiedi ogni volta",
"buy_provider_unavailable": "Provider attualmente non disponibile."
}

View file

@ -686,6 +686,11 @@
"support_title_other_links": "その他のサポートリンク", "support_title_other_links": "その他のサポートリンク",
"support_description_other_links": "私たちのコミュニティに参加するか、他の方法を通して私たちのパートナーに連絡してください", "support_description_other_links": "私たちのコミュニティに参加するか、他の方法を通して私たちのパートナーに連絡してください",
"select_destination": "バックアップファイルの保存先を選択してください。", "select_destination": "バックアップファイルの保存先を選択してください。",
"auto_generate_subaddresses": "Autoはサブアドレスを生成します",
"save_to_downloads": "ダウンロードに保存", "save_to_downloads": "ダウンロードに保存",
"auto_generate_subaddresses": "Autoはサブアドレスを生成します" "select_buy_provider_notice": "上記の購入プロバイダーを選択してください。デフォルトの購入プロバイダーをアプリ設定で設定して、この画面をスキップできます。",
} "onramper_option_description": "多くの支払い方法で暗号をすばやく購入してください。ほとんどの国で利用可能です。スプレッドと料金は異なります。",
"default_buy_provider": "デフォルトの購入プロバイダー",
"ask_each_time": "毎回尋ねてください",
"buy_provider_unavailable": "現在、プロバイダーは利用できません。"
}

View file

@ -686,6 +686,11 @@
"support_title_other_links": "다른 지원 링크", "support_title_other_links": "다른 지원 링크",
"support_description_other_links": "다른 방법을 통해 커뮤니티에 가입하거나 파트너에게 연락하십시오.", "support_description_other_links": "다른 방법을 통해 커뮤니티에 가입하거나 파트너에게 연락하십시오.",
"select_destination": "백업 파일의 대상을 선택하십시오.", "select_destination": "백업 파일의 대상을 선택하십시오.",
"auto_generate_subaddresses": "자동 생성 서브 아드 드레스",
"save_to_downloads": "다운로드에 저장", "save_to_downloads": "다운로드에 저장",
"auto_generate_subaddresses": "자동 생성 서브 아드 드레스" "select_buy_provider_notice": "위의 구매 제공자를 선택하십시오. 앱 설정에서 기본 구매 제공자를 설정 하여이 화면을 건너 뛸 수 있습니다.",
} "onramper_option_description": "많은 결제 방법으로 암호화를 신속하게 구입하십시오. 대부분의 국가에서 사용할 수 있습니다. 스프레드와 수수료는 다양합니다.",
"default_buy_provider": "기본 구매 제공자",
"ask_each_time": "매번 물어보십시오",
"buy_provider_unavailable": "제공자는 현재 사용할 수 없습니다."
}

View file

@ -684,6 +684,11 @@
"support_title_other_links": "အခြားအထောက်အပံ့လင့်များ", "support_title_other_links": "အခြားအထောက်အပံ့လင့်များ",
"support_description_other_links": "ကျွန်ုပ်တို့၏လူမှုအသိုင်းအဝိုင်းများသို့ 0 င်ရောက်ပါ", "support_description_other_links": "ကျွန်ုပ်တို့၏လူမှုအသိုင်းအဝိုင်းများသို့ 0 င်ရောက်ပါ",
"select_destination": "အရန်ဖိုင်အတွက် ဦးတည်ရာကို ရွေးပါ။", "select_destination": "အရန်ဖိုင်အတွက် ဦးတည်ရာကို ရွေးပါ။",
"auto_generate_subaddresses": "အော်တို Generate Subaddresses",
"save_to_downloads": "ဒေါင်းလုဒ်များထံ သိမ်းဆည်းပါ။", "save_to_downloads": "ဒေါင်းလုဒ်များထံ သိမ်းဆည်းပါ။",
"auto_generate_subaddresses": "အော်တို Generate Subaddresses" "select_buy_provider_notice": "အပေါ်ကဝယ်သူတစ် ဦး ကိုရွေးချယ်ပါ။ သင်၏ default 0 ယ်သူအား app settings တွင် setting လုပ်ခြင်းဖြင့်ဤ screen ကိုကျော်သွားနိုင်သည်။",
} "onramper_option_description": "ငွေပေးချေမှုနည်းလမ်းများစွာဖြင့် Crypto ကိုလျင်မြန်စွာ 0 ယ်ပါ။ နိုင်ငံအများစုတွင်ရရှိနိုင်ပါသည်။ ဖြန့်ဖြူးနှင့်အခကြေးငွေကွဲပြားခြားနားသည်။",
"default_buy_provider": "Default Provider ကိုဝယ်ပါ",
"ask_each_time": "တစ်ခုချင်းစီကိုအချိန်မေးပါ",
"buy_provider_unavailable": "လက်ရှိတွင်လက်ရှိမရနိုင်ပါ။"
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "Andere ondersteuningslinks", "support_title_other_links": "Andere ondersteuningslinks",
"support_description_other_links": "Word lid van onze gemeenschappen of bereik ons onze partners via andere methoden", "support_description_other_links": "Word lid van onze gemeenschappen of bereik ons onze partners via andere methoden",
"select_destination": "Selecteer de bestemming voor het back-upbestand.", "select_destination": "Selecteer de bestemming voor het back-upbestand.",
"save_to_downloads": "Opslaan in downloads" "save_to_downloads": "Opslaan in downloads",
} "select_buy_provider_notice": "Selecteer hierboven een koopprovider. U kunt dit scherm overslaan door uw standaard kopenprovider in te stellen in app -instellingen.",
"onramper_option_description": "Koop snel crypto met veel betaalmethoden. Beschikbaar in de meeste landen. Spreads en vergoedingen variëren.",
"default_buy_provider": "Standaard Koopprovider",
"ask_each_time": "Vraag het elke keer",
"buy_provider_unavailable": "Provider momenteel niet beschikbaar."
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "Inne linki wsparcia", "support_title_other_links": "Inne linki wsparcia",
"support_description_other_links": "Dołącz do naszych społeczności lub skontaktuj się z nami naszymi partnerami za pomocą innych metod", "support_description_other_links": "Dołącz do naszych społeczności lub skontaktuj się z nami naszymi partnerami za pomocą innych metod",
"select_destination": "Wybierz miejsce docelowe dla pliku kopii zapasowej.", "select_destination": "Wybierz miejsce docelowe dla pliku kopii zapasowej.",
"save_to_downloads": "Zapisz w Pobranych" "save_to_downloads": "Zapisz w Pobranych",
} "select_buy_provider_notice": "Wybierz powyższe dostawcę zakupu. Możesz pominąć ten ekran, ustawiając domyślnego dostawcę zakupu w ustawieniach aplikacji.",
"onramper_option_description": "Szybko kup kryptowaluty z wieloma metodami płatności. Dostępne w większości krajów. Spready i opłaty różnią się.",
"default_buy_provider": "Domyślny dostawca zakupu",
"ask_each_time": "Zapytaj za każdym razem",
"buy_provider_unavailable": "Dostawca obecnie niedostępny."
}

View file

@ -686,5 +686,10 @@
"support_title_other_links": "Outros links de suporte", "support_title_other_links": "Outros links de suporte",
"support_description_other_links": "Junte -se às nossas comunidades ou chegue a nós nossos parceiros por meio de outros métodos", "support_description_other_links": "Junte -se às nossas comunidades ou chegue a nós nossos parceiros por meio de outros métodos",
"select_destination": "Selecione o destino para o arquivo de backup.", "select_destination": "Selecione o destino para o arquivo de backup.",
"save_to_downloads": "Salvar em Downloads" "save_to_downloads": "Salvar em Downloads",
} "select_buy_provider_notice": "Selecione um provedor de compra acima. Você pode pular esta tela definindo seu provedor de compra padrão nas configurações de aplicativos.",
"onramper_option_description": "Compre rapidamente criptografia com muitos métodos de pagamento. Disponível na maioria dos países. Os spreads e taxas variam.",
"default_buy_provider": "Provedor de compra padrão",
"ask_each_time": "Pergunte cada vez",
"buy_provider_unavailable": "Provedor atualmente indisponível."
}

View file

@ -686,6 +686,11 @@
"support_title_other_links": "Другие ссылки на поддержку", "support_title_other_links": "Другие ссылки на поддержку",
"support_description_other_links": "Присоединяйтесь к нашим сообществам или охватите нас наших партнеров с помощью других методов", "support_description_other_links": "Присоединяйтесь к нашим сообществам или охватите нас наших партнеров с помощью других методов",
"select_destination": "Пожалуйста, выберите место для файла резервной копии.", "select_destination": "Пожалуйста, выберите место для файла резервной копии.",
"auto_generate_subaddresses": "Авто генерируйте Subaddresses",
"save_to_downloads": "Сохранить в загрузках", "save_to_downloads": "Сохранить в загрузках",
"auto_generate_subaddresses": "Авто генерируйте Subaddresses" "select_buy_provider_notice": "Выберите поставщика покупки выше. Вы можете пропустить этот экран, установив поставщика покупки по умолчанию в настройках приложения.",
} "onramper_option_description": "Быстро купите крипто со многими способами оплаты. Доступно в большинстве стран. Спреды и сборы различаются.",
"default_buy_provider": "По умолчанию поставщик покупки",
"ask_each_time": "Спросите каждый раз",
"buy_provider_unavailable": "Поставщик в настоящее время недоступен."
}

View file

@ -684,6 +684,11 @@
"support_title_other_links": "ลิงค์สนับสนุนอื่น ๆ", "support_title_other_links": "ลิงค์สนับสนุนอื่น ๆ",
"support_description_other_links": "เข้าร่วมชุมชนของเราหรือเข้าถึงเราพันธมิตรของเราผ่านวิธีการอื่น ๆ", "support_description_other_links": "เข้าร่วมชุมชนของเราหรือเข้าถึงเราพันธมิตรของเราผ่านวิธีการอื่น ๆ",
"select_destination": "โปรดเลือกปลายทางสำหรับไฟล์สำรอง", "select_destination": "โปรดเลือกปลายทางสำหรับไฟล์สำรอง",
"auto_generate_subaddresses": "Auto สร้าง subaddresses",
"save_to_downloads": "บันทึกลงดาวน์โหลด", "save_to_downloads": "บันทึกลงดาวน์โหลด",
"auto_generate_subaddresses": "Auto สร้าง subaddresses" "select_buy_provider_notice": "เลือกผู้ให้บริการซื้อด้านบน คุณสามารถข้ามหน้าจอนี้ได้โดยการตั้งค่าผู้ให้บริการซื้อเริ่มต้นในการตั้งค่าแอป",
} "onramper_option_description": "ซื้อ crypto อย่างรวดเร็วด้วยวิธีการชำระเงินจำนวนมาก มีให้บริการในประเทศส่วนใหญ่ สเปรดและค่าธรรมเนียมแตกต่างกันไป",
"default_buy_provider": "ผู้ให้บริการซื้อเริ่มต้น",
"ask_each_time": "ถามทุกครั้ง",
"buy_provider_unavailable": "ผู้ให้บริการไม่สามารถใช้งานได้ในปัจจุบัน"
}

View file

@ -685,5 +685,10 @@
"support_title_other_links": "Diğer destek bağlantıları", "support_title_other_links": "Diğer destek bağlantıları",
"support_description_other_links": "Topluluklarımıza katılın veya ortaklarımıza diğer yöntemlerle bize ulaşın", "support_description_other_links": "Topluluklarımıza katılın veya ortaklarımıza diğer yöntemlerle bize ulaşın",
"select_destination": "Lütfen yedekleme dosyası için hedef seçin.", "select_destination": "Lütfen yedekleme dosyası için hedef seçin.",
"save_to_downloads": "İndirilenlere Kaydet" "save_to_downloads": "İndirilenlere Kaydet",
} "select_buy_provider_notice": "Yukarıda bir satın alma sağlayıcısı seçin. App ayarlarında varsayılan satın alma sağlayıcınızı ayarlayarak bu ekranı atlayabilirsiniz.",
"onramper_option_description": "Birçok ödeme yöntemi ile hızlı bir şekilde kripto satın alın. Çoğu ülkede mevcuttur. Forma ve ücretler değişir.",
"default_buy_provider": "Varsayılan Satın Alma Sağlayıcısı",
"ask_each_time": "Her seferinde sor",
"buy_provider_unavailable": "Sağlayıcı şu anda kullanılamıyor."
}

View file

@ -687,5 +687,10 @@
"support_title_other_links": "Інші посилання на підтримку", "support_title_other_links": "Інші посилання на підтримку",
"support_description_other_links": "Приєднуйтесь до наших спільнот або досягайте нас нашими партнерами іншими методами", "support_description_other_links": "Приєднуйтесь до наших спільнот або досягайте нас нашими партнерами іншими методами",
"select_destination": "Виберіть місце призначення для файлу резервної копії.", "select_destination": "Виберіть місце призначення для файлу резервної копії.",
"save_to_downloads": "Зберегти до завантажень" "save_to_downloads": "Зберегти до завантажень",
} "select_buy_provider_notice": "Виберіть постачальника купівлі вище. Ви можете пропустити цей екран, встановивши свого постачальника купівлі за замовчуванням у налаштуваннях додатків.",
"onramper_option_description": "Швидко купуйте криптовалюту з багатьма методами оплати. Доступний у більшості країн. Поширення та збори різняться.",
"default_buy_provider": "Постачальник покупки за замовчуванням",
"ask_each_time": "Запитайте кожен раз",
"buy_provider_unavailable": "В даний час постачальник недоступний."
}

View file

@ -678,6 +678,11 @@
"support_title_other_links": "دوسرے سپورٹ لنکس", "support_title_other_links": "دوسرے سپورٹ لنکس",
"support_description_other_links": "ہماری برادریوں میں شامل ہوں یا دوسرے طریقوں سے ہمارے شراکت داروں تک پہنچیں", "support_description_other_links": "ہماری برادریوں میں شامل ہوں یا دوسرے طریقوں سے ہمارے شراکت داروں تک پہنچیں",
"select_destination": "۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﻝﺰﻨﻣ ﮯﯿﻟ ﮯﮐ ﻞﺋﺎﻓ ﭖﺍ ﮏﯿﺑ ﻡﺮﮐ ﮦﺍﺮﺑ", "select_destination": "۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﻝﺰﻨﻣ ﮯﯿﻟ ﮯﮐ ﻞﺋﺎﻓ ﭖﺍ ﮏﯿﺑ ﻡﺮﮐ ﮦﺍﺮﺑ",
"auto_generate_subaddresses": "آٹو سب ایڈریس تیار کرتا ہے",
"save_to_downloads": "۔ﮟﯾﺮﮐ ﻅﻮﻔﺤﻣ ﮟﯿﻣ ﺯﮈﻮﻟ ﻥﺅﺍﮈ", "save_to_downloads": "۔ﮟﯾﺮﮐ ﻅﻮﻔﺤﻣ ﮟﯿﻣ ﺯﮈﻮﻟ ﻥﺅﺍﮈ",
"auto_generate_subaddresses": "آٹو سب ایڈریس تیار کرتا ہے" "select_buy_provider_notice": "اوپر خریدنے والا خریدنے والا منتخب کریں۔ آپ ایپ کی ترتیبات میں اپنے پہلے سے طے شدہ خریدنے والے کو ترتیب دے کر اس اسکرین کو چھوڑ سکتے ہیں۔",
} "onramper_option_description": "ادائیگی کے بہت سے طریقوں سے جلدی سے کرپٹو خریدیں۔ زیادہ تر ممالک میں دستیاب ہے۔ پھیلاؤ اور فیس مختلف ہوتی ہے۔",
"default_buy_provider": "پہلے سے طے شدہ خریدنے والا",
"ask_each_time": "ہر بار پوچھیں",
"buy_provider_unavailable": "فراہم کنندہ فی الحال دستیاب نہیں ہے۔"
}

View file

@ -680,6 +680,11 @@
"matrix_green_dark_theme": "Matrix Green Dark Akori", "matrix_green_dark_theme": "Matrix Green Dark Akori",
"monero_light_theme": "Monero Light Akori", "monero_light_theme": "Monero Light Akori",
"select_destination": "Jọwọ yan ibi ti o nlo fun faili afẹyinti.", "select_destination": "Jọwọ yan ibi ti o nlo fun faili afẹyinti.",
"auto_generate_subaddresses": "Aṣiṣe Ibi-Afọwọkọ",
"save_to_downloads": "Fipamọ si Awọn igbasilẹ", "save_to_downloads": "Fipamọ si Awọn igbasilẹ",
"auto_generate_subaddresses": "Aṣiṣe Ibi-Afọwọkọ" "select_buy_provider_notice": "Yan olupese Ra loke. O le skii iboju yii nipa ṣiṣeto olupese rẹ ni awọn eto App.",
} "onramper_option_description": "Ni kiakia Ra Crypto pẹlu ọpọlọpọ awọn ọna isanwo. Wa ni ọpọlọpọ awọn orilẹ-ede. Itankale ati awọn idiyele yatọ.",
"default_buy_provider": "Aiyipada Ra Olupese",
"ask_each_time": "Beere lọwọ kọọkan",
"buy_provider_unavailable": "Olupese lọwọlọwọ ko si."
}

View file

@ -685,6 +685,11 @@
"matrix_green_dark_theme": "矩阵绿暗主题", "matrix_green_dark_theme": "矩阵绿暗主题",
"monero_light_theme": "门罗币浅色主题", "monero_light_theme": "门罗币浅色主题",
"select_destination": "请选择备份文件的目的地。", "select_destination": "请选择备份文件的目的地。",
"auto_generate_subaddresses": "自动生成子辅助",
"save_to_downloads": "保存到下载", "save_to_downloads": "保存到下载",
"auto_generate_subaddresses": "自动生成子辅助" "select_buy_provider_notice": "在上面选择买入提供商。您可以通过在应用程序设置中设置默认的购买提供商来跳过此屏幕。",
} "onramper_option_description": "快速使用许多付款方式购买加密货币。在大多数国家 /地区可用。利差和费用各不相同。",
"default_buy_provider": "默认购买提供商",
"ask_each_time": "每次问",
"buy_provider_unavailable": "提供者目前不可用。"
}

View file

@ -32,6 +32,8 @@ class SecretKey {
SecretKey('fiatApiKey', () => ''), SecretKey('fiatApiKey', () => ''),
SecretKey('payfuraApiKey', () => ''), SecretKey('payfuraApiKey', () => ''),
SecretKey('chatwootWebsiteToken', () => ''), SecretKey('chatwootWebsiteToken', () => ''),
SecretKey('robinhoodApplicationId', () => ''),
SecretKey('robinhoodCIdApiSecret', () => ''),
]; ];
static final ethereumSecrets = [ static final ethereumSecrets = [