Merge branch 'main' into CW-1103-Token-Validation-Issues

This commit is contained in:
Omar Hatem 2025-06-19 05:52:05 +03:00 committed by GitHub
commit 4418a3d542
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 2034 additions and 63 deletions

View file

@ -0,0 +1,121 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_ethereum/deuro/deuro_savings_contract.dart';
import 'package:cw_ethereum/ethereum_wallet.dart';
import 'package:cw_evm/contract/erc20.dart';
import 'package:cw_evm/evm_chain_transaction_priority.dart';
import 'package:cw_evm/pending_evm_chain_transaction.dart';
import 'package:web3dart/web3dart.dart';
const String savingsGatewayAddress =
"0x073493d73258C4BEb6542e8dd3e1b2891C972303";
const String dEuroAddress = "0xbA3f535bbCcCcA2A154b573Ca6c5A49BAAE0a3ea";
class DEuro {
final SavingsGateway _savingsGateway;
final ERC20 _dEuro;
final EthereumWallet _wallet;
DEuro(EthereumWallet wallet)
: _wallet = wallet,
_savingsGateway = _getSavingsGateway(wallet.getWeb3Client()!),
_dEuro = _getDEuroToken(wallet.getWeb3Client()!);
static SavingsGateway _getSavingsGateway(Web3Client client) => SavingsGateway(
address: EthereumAddress.fromHex(savingsGatewayAddress),
client: client,
);
static ERC20 _getDEuroToken(Web3Client client) => ERC20(
address: EthereumAddress.fromHex(dEuroAddress),
client: client,
);
final frontendCode =
Uint8List.fromList(sha256.convert(utf8.encode("wallet")).bytes);
EthereumAddress get _address =>
EthereumAddress.fromHex(_wallet.walletAddresses.primaryAddress);
Future<BigInt> get savingsBalance async =>
(await _savingsGateway.savings(accountOwner: _address)).saved;
Future<BigInt> get accruedInterest =>
_savingsGateway.accruedInterest(accountOwner: _address);
Future<BigInt> get interestRate => _savingsGateway.currentRatePPM();
Future<BigInt> get approvedBalance =>
_dEuro.allowance(_address, _savingsGateway.self.address);
Future<PendingEVMChainTransaction> depositSavings(
BigInt amount, EVMChainTransactionPriority priority) async {
final signedTransaction = await _savingsGateway.save(
(amount: amount, frontendCode: frontendCode),
credentials: _wallet.evmChainPrivateKey,
);
final fee = await _wallet.calculateActualEstimatedFeeForCreateTransaction(
amount: amount,
contractAddress: _savingsGateway.self.address.hexEip55,
receivingAddressHex: _savingsGateway.self.address.hexEip55,
priority: priority,
data: _savingsGateway.self.abi.functions[17]
.encodeCall([amount, frontendCode]),
);
final sendTransaction =
() => _wallet.getWeb3Client()!.sendRawTransaction(signedTransaction);
return PendingEVMChainTransaction(
sendTransaction: sendTransaction,
signedTransaction: signedTransaction,
fee: BigInt.from(fee.estimatedGasFee),
amount: amount.toString(),
exponent: 18);
}
Future<PendingEVMChainTransaction> withdrawSavings(
BigInt amount, EVMChainTransactionPriority priority) async {
final signedTransaction = await _savingsGateway.withdraw(
(target: _address, amount: amount, frontendCode: frontendCode),
credentials: _wallet.evmChainPrivateKey,
);
final fee = await _wallet.calculateActualEstimatedFeeForCreateTransaction(
amount: amount,
contractAddress: _savingsGateway.self.address.hexEip55,
receivingAddressHex: _savingsGateway.self.address.hexEip55,
priority: priority,
data: _savingsGateway.self.abi.functions[17]
.encodeCall([amount, frontendCode]),
);
final sendTransaction =
() => _wallet.getWeb3Client()!.sendRawTransaction(signedTransaction);
return PendingEVMChainTransaction(
sendTransaction: sendTransaction,
signedTransaction: signedTransaction,
fee: BigInt.from(fee.estimatedGasFee),
amount: amount.toString(),
exponent: 18);
}
// Set an infinite approval to save gas in the future
Future<PendingEVMChainTransaction> enableSavings(
EVMChainTransactionPriority priority) async =>
(await _wallet.createApprovalTransaction(
BigInt.parse(
'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
radix: 16,
),
_savingsGateway.self.address.hexEip55,
CryptoCurrency.deuro,
priority,
)) as PendingEVMChainTransaction;
}

File diff suppressed because one or more lines are too long

View file

@ -6,7 +6,7 @@ author: Cake Wallet
homepage: https://cakewallet.com homepage: https://cakewallet.com
environment: environment:
sdk: '>=2.18.2 <3.0.0' sdk: ^3.5.0
flutter: ">=1.17.0" flutter: ">=1.17.0"
dependencies: dependencies:

View file

@ -76,7 +76,7 @@ abstract class EVMChainClient {
Future<int> getGasUnitPrice() async { Future<int> getGasUnitPrice() async {
try { try {
final gasPrice = await _client!.getGasPrice(); final gasPrice = await _client!.getGasPrice();
return gasPrice.getInWei.toInt(); return gasPrice.getInWei.toInt();
} catch (_) { } catch (_) {
return 0; return 0;
@ -101,6 +101,7 @@ abstract class EVMChainClient {
String? contractAddress, String? contractAddress,
EtherAmount? gasPrice, EtherAmount? gasPrice,
EtherAmount? maxFeePerGas, EtherAmount? maxFeePerGas,
Uint8List? data,
}) async { }) async {
try { try {
if (contractAddress == null) { if (contractAddress == null) {
@ -124,7 +125,7 @@ abstract class EVMChainClient {
final gasEstimate = await _client!.estimateGas( final gasEstimate = await _client!.estimateGas(
sender: senderAddress, sender: senderAddress,
to: EthereumAddress.fromHex(contractAddress), to: EthereumAddress.fromHex(contractAddress),
data: transfer.encodeCall([ data: data ?? transfer.encodeCall([
toAddress, toAddress,
value.getInWei, value.getInWei,
]), ]),
@ -137,6 +138,21 @@ abstract class EVMChainClient {
} }
} }
Uint8List getEncodedDataForApprovalTransaction({
required EthereumAddress toAddress,
required EtherAmount value,
required EthereumAddress contractAddress,
}) {
final contract = DeployedContract(ethereumContractAbi, contractAddress);
final approve = contract.function('approve');
return approve.encodeCall([
toAddress,
value.getInWei,
]);
}
Future<PendingEVMChainTransaction> signTransaction({ Future<PendingEVMChainTransaction> signTransaction({
required Credentials privateKey, required Credentials privateKey,
required String toAddress, required String toAddress,
@ -198,6 +214,50 @@ abstract class EVMChainClient {
); );
} }
Future<PendingEVMChainTransaction> signApprovalTransaction({
required Credentials privateKey,
required String spender,
required BigInt amount,
required BigInt gasFee,
required int estimatedGasUnits,
required int maxFeePerGas,
required EVMChainTransactionPriority priority,
required int exponent,
required String contractAddress,
}) async {
final Transaction transaction = createTransaction(
from: privateKey.address,
to: EthereumAddress.fromHex(contractAddress),
maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
amount: EtherAmount.zero(),
maxGas: estimatedGasUnits,
maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas),
);
final erc20 = ERC20(
client: _client!,
address: EthereumAddress.fromHex(contractAddress),
chainId: chainId,
);
final signedTransaction = await erc20.approve(
EthereumAddress.fromHex(spender),
amount,
credentials: privateKey,
transaction: transaction,
);
return PendingEVMChainTransaction(
signedTransaction: prepareSignedTransactionForSending(signedTransaction),
amount: amount.toString(),
fee: gasFee,
sendTransaction: () => sendTransaction(signedTransaction),
exponent: exponent,
isInfiniteApproval: amount.toRadixString(16) == 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
);
}
Transaction createTransaction({ Transaction createTransaction({
required EthereumAddress from, required EthereumAddress from,
required EthereumAddress to, required EthereumAddress to,

View file

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data';
import 'package:bip32/bip32.dart' as bip32; import 'package:bip32/bip32.dart' as bip32;
import 'package:bip39/bip39.dart' as bip39; import 'package:bip39/bip39.dart' as bip39;
@ -265,6 +266,7 @@ abstract class EVMChainWalletBase
required String? contractAddress, required String? contractAddress,
required String receivingAddressHex, required String receivingAddressHex,
required TransactionPriority priority, required TransactionPriority priority,
Uint8List? data,
}) async { }) async {
try { try {
if (priority is EVMChainTransactionPriority) { if (priority is EVMChainTransactionPriority) {
@ -286,6 +288,7 @@ abstract class EVMChainWalletBase
gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice), gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice),
toAddress: EthereumAddress.fromHex(receivingAddressHex), toAddress: EthereumAddress.fromHex(receivingAddressHex),
maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas), maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas),
data: data,
); );
final totalGasFee = estimatedGas * maxFeePerGas; final totalGasFee = estimatedGas * maxFeePerGas;
@ -488,6 +491,43 @@ abstract class EVMChainWalletBase
return pendingEVMChainTransaction; return pendingEVMChainTransaction;
} }
Future<PendingTransaction> createApprovalTransaction(
BigInt amount,
String spender,
CryptoCurrency token,
EVMChainTransactionPriority priority) async {
final CryptoCurrency transactionCurrency =
balance.keys.firstWhere((element) => element.title == token.title);
assert(transactionCurrency is Erc20Token);
final data = _client.getEncodedDataForApprovalTransaction(
contractAddress: EthereumAddress.fromHex(
(transactionCurrency as Erc20Token).contractAddress),
value: EtherAmount.fromBigInt(EtherUnit.wei, amount),
toAddress: EthereumAddress.fromHex(spender),
);
final gasFeesModel = await calculateActualEstimatedFeeForCreateTransaction(
amount: amount,
receivingAddressHex: spender,
priority: priority,
contractAddress: transactionCurrency.contractAddress,
data: data,
);
return _client.signApprovalTransaction(
privateKey: _evmChainPrivateKey,
spender: spender,
amount: amount,
priority: priority,
gasFee: BigInt.from(gasFeesModel.estimatedGasFee),
maxFeePerGas: gasFeesModel.maxFeePerGas,
estimatedGasUnits: gasFeesModel.estimatedGasUnits,
exponent: transactionCurrency.decimal,
contractAddress: transactionCurrency.contractAddress,
);
}
Future<void> _updateTransactions() async { Future<void> _updateTransactions() async {
try { try {
if (_isTransactionUpdating) { if (_isTransactionUpdating) {

View file

@ -11,6 +11,7 @@ class PendingEVMChainTransaction with PendingTransaction {
final BigInt fee; final BigInt fee;
final String amount; final String amount;
final int exponent; final int exponent;
final bool isInfiniteApproval;
PendingEVMChainTransaction({ PendingEVMChainTransaction({
required this.sendTransaction, required this.sendTransaction,
@ -18,10 +19,12 @@ class PendingEVMChainTransaction with PendingTransaction {
required this.fee, required this.fee,
required this.amount, required this.amount,
required this.exponent, required this.exponent,
this.isInfiniteApproval = false,
}); });
@override @override
String get amountFormatted { String get amountFormatted {
if (isInfiniteApproval) return "";
final _amount = (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString(); final _amount = (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString();
return _amount.substring(0, min(10, _amount.length)); return _amount.substring(0, min(10, _amount.length));
} }

View file

@ -35,6 +35,7 @@ import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart'; import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
import 'package:cake_wallet/src/screens/dev/secure_preferences_page.dart'; import 'package:cake_wallet/src/screens/dev/secure_preferences_page.dart';
import 'package:cake_wallet/src/screens/dev/shared_preferences_page.dart'; import 'package:cake_wallet/src/screens/dev/shared_preferences_page.dart';
import 'package:cake_wallet/src/screens/integrations/deuro/savings_page.dart';
import 'package:cake_wallet/src/screens/settings/background_sync_page.dart'; import 'package:cake_wallet/src/screens/settings/background_sync_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart'; import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart';
import 'package:cake_wallet/src/screens/wallet_connect/services/key_service/wallet_connect_key_service.dart'; import 'package:cake_wallet/src/screens/wallet_connect/services/key_service/wallet_connect_key_service.dart';
@ -43,6 +44,7 @@ import 'package:cake_wallet/themes/core/theme_store.dart';
import 'package:cake_wallet/view_model/dev/monero_background_sync.dart'; import 'package:cake_wallet/view_model/dev/monero_background_sync.dart';
import 'package:cake_wallet/view_model/dev/secure_preferences.dart'; import 'package:cake_wallet/view_model/dev/secure_preferences.dart';
import 'package:cake_wallet/view_model/dev/shared_preferences.dart'; import 'package:cake_wallet/view_model/dev/shared_preferences.dart';
import 'package:cake_wallet/view_model/integrations/deuro_view_model.dart';
import 'package:cake_wallet/view_model/link_view_model.dart'; import 'package:cake_wallet/view_model/link_view_model.dart';
import 'package:cake_wallet/tron/tron.dart'; import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart'; import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
@ -1510,6 +1512,10 @@ Future<void> setup({
getIt.registerFactory(() => BackgroundSyncLogsViewModel()); getIt.registerFactory(() => BackgroundSyncLogsViewModel());
getIt.registerFactory(() => DevBackgroundSyncLogsPage(getIt.get<BackgroundSyncLogsViewModel>())); getIt.registerFactory(() => DevBackgroundSyncLogsPage(getIt.get<BackgroundSyncLogsViewModel>()));
getIt.registerFactory(() => DEuroViewModel(getIt<AppStore>()));
getIt.registerFactory(() => DEuroSavingsPage(getIt<DEuroViewModel>()));
_isSetupFinished = true; _isSetupFinished = true;
} }

View file

@ -67,8 +67,7 @@ class CWEthereum extends Ethereum {
@override @override
String getPublicKey(WalletBase wallet) { String getPublicKey(WalletBase wallet) {
final privateKeyInUnitInt = (wallet as EthereumWallet).evmChainPrivateKey; final privateKeyInUnitInt = (wallet as EthereumWallet).evmChainPrivateKey;
final publicKey = privateKeyInUnitInt.address.hex; return privateKeyInUnitInt.address.hex;
return publicKey;
} }
@override @override
@ -138,29 +137,24 @@ class CWEthereum extends Ethereum {
} }
@override @override
List<Erc20Token> getERC20Currencies(WalletBase wallet) { List<Erc20Token> getERC20Currencies(WalletBase wallet) =>
final ethereumWallet = wallet as EthereumWallet; (wallet as EthereumWallet).erc20Currencies;
return ethereumWallet.erc20Currencies;
}
@override @override
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) async { Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) =>
await (wallet as EthereumWallet).addErc20Token(token as Erc20Token); (wallet as EthereumWallet).addErc20Token(token as Erc20Token);
}
@override @override
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) async => Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) =>
await (wallet as EthereumWallet).deleteErc20Token(token as Erc20Token); (wallet as EthereumWallet).deleteErc20Token(token as Erc20Token);
@override @override
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token) async => Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token) =>
await (wallet as EthereumWallet).removeTokenTransactionsInHistory(token as Erc20Token); (wallet as EthereumWallet).removeTokenTransactionsInHistory(token as Erc20Token);
@override @override
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) async { Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) =>
final ethereumWallet = wallet as EthereumWallet; (wallet as EthereumWallet).getErc20Token(contractAddress, 'eth');
return await ethereumWallet.getErc20Token(contractAddress, 'eth');
}
@override @override
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) { CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
@ -177,23 +171,19 @@ class CWEthereum extends Ethereum {
} }
@override @override
void updateEtherscanUsageState(WalletBase wallet, bool isEnabled) { void updateEtherscanUsageState(WalletBase wallet, bool isEnabled) =>
(wallet as EthereumWallet).updateScanProviderUsageState(isEnabled); (wallet as EthereumWallet).updateScanProviderUsageState(isEnabled);
}
@override @override
Web3Client? getWeb3Client(WalletBase wallet) { Web3Client? getWeb3Client(WalletBase wallet) => (wallet as EthereumWallet).getWeb3Client();
return (wallet as EthereumWallet).getWeb3Client();
}
@override
String getTokenAddress(CryptoCurrency asset) => (asset as Erc20Token).contractAddress; String getTokenAddress(CryptoCurrency asset) => (asset as Erc20Token).contractAddress;
@override @override
void setLedgerConnection( void setLedgerConnection(WalletBase wallet, ledger.LedgerConnection connection) {
WalletBase wallet, ledger.LedgerConnection connection) {
((wallet as EVMChainWallet).evmChainPrivateKey as EvmLedgerCredentials) ((wallet as EVMChainWallet).evmChainPrivateKey as EvmLedgerCredentials)
.setLedgerConnection( .setLedgerConnection(connection, wallet.walletInfo.derivationInfo?.derivationPath);
connection, wallet.walletInfo.derivationInfo?.derivationPath);
} }
@override @override
@ -219,4 +209,42 @@ class CWEthereum extends Ethereum {
final ethereumWallet = wallet as EthereumWallet; final ethereumWallet = wallet as EthereumWallet;
return ethereumWallet.erc20Currencies.any((element) => element.contractAddress.toLowerCase() == contractAddress.toLowerCase()); return ethereumWallet.erc20Currencies.any((element) => element.contractAddress.toLowerCase() == contractAddress.toLowerCase());
} }
Future<PendingTransaction> createTokenApproval(WalletBase wallet, BigInt amount, String spender,
CryptoCurrency token, TransactionPriority priority) =>
(wallet as EVMChainWallet).createApprovalTransaction(
amount, spender, token, priority as EVMChainTransactionPriority);
// Integrations
@override
Future<BigInt> getDEuroSavingsBalance(WalletBase wallet) =>
DEuro(wallet as EthereumWallet).savingsBalance;
@override
Future<BigInt> getDEuroAccruedInterest(WalletBase wallet) =>
DEuro(wallet as EthereumWallet).accruedInterest;
@override
Future<BigInt> getDEuroInterestRate(WalletBase wallet) =>
DEuro(wallet as EthereumWallet).interestRate;
@override
Future<BigInt> getDEuroSavingsApproved(WalletBase wallet) =>
DEuro(wallet as EthereumWallet).approvedBalance;
@override
Future<PendingTransaction> addDEuroSaving(
WalletBase wallet, BigInt amount, TransactionPriority priority) =>
DEuro(wallet as EthereumWallet)
.depositSavings(amount, priority as EVMChainTransactionPriority);
@override
Future<PendingTransaction> removeDEuroSaving(
WalletBase wallet, BigInt amount, TransactionPriority priority) =>
DEuro(wallet as EthereumWallet)
.withdrawSavings(amount, priority as EVMChainTransactionPriority);
@override
Future<PendingTransaction> enableDEuroSaving(WalletBase wallet, TransactionPriority priority) =>
DEuro(wallet as EthereumWallet).enableSavings(priority as EVMChainTransactionPriority);
} }

View file

@ -67,8 +67,7 @@ class CWPolygon extends Polygon {
@override @override
String getPublicKey(WalletBase wallet) { String getPublicKey(WalletBase wallet) {
final privateKeyInUnitInt = (wallet as PolygonWallet).evmChainPrivateKey; final privateKeyInUnitInt = (wallet as PolygonWallet).evmChainPrivateKey;
final publicKey = privateKeyInUnitInt.address.hex; return privateKeyInUnitInt.address.hex;
return publicKey;
} }
@override @override
@ -137,28 +136,27 @@ class CWPolygon extends Polygon {
} }
@override @override
List<Erc20Token> getERC20Currencies(WalletBase wallet) { List<Erc20Token> getERC20Currencies(WalletBase wallet) =>
final polygonWallet = wallet as PolygonWallet; (wallet as PolygonWallet).erc20Currencies;
return polygonWallet.erc20Currencies;
}
@override @override
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) async => Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) =>
await (wallet as PolygonWallet).addErc20Token(token as Erc20Token); (wallet as PolygonWallet).addErc20Token(token as Erc20Token);
@override @override
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) async => Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) =>
await (wallet as PolygonWallet).deleteErc20Token(token as Erc20Token); (wallet as PolygonWallet).deleteErc20Token(token as Erc20Token);
@override @override
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token) async => Future<void> removeTokenTransactionsInHistory(
await (wallet as PolygonWallet).removeTokenTransactionsInHistory(token as Erc20Token); WalletBase wallet, CryptoCurrency token) =>
(wallet as PolygonWallet)
.removeTokenTransactionsInHistory(token as Erc20Token);
@override @override
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) async { Future<Erc20Token?> getErc20Token(
final polygonWallet = wallet as PolygonWallet; WalletBase wallet, String contractAddress) =>
return await polygonWallet.getErc20Token(contractAddress, 'polygon'); (wallet as PolygonWallet).getErc20Token(contractAddress, 'polygon');
}
@override @override
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) { CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
@ -176,23 +174,29 @@ class CWPolygon extends Polygon {
} }
@override @override
void updatePolygonScanUsageState(WalletBase wallet, bool isEnabled) { void updatePolygonScanUsageState(WalletBase wallet, bool isEnabled) =>
(wallet as PolygonWallet).updateScanProviderUsageState(isEnabled); (wallet as PolygonWallet).updateScanProviderUsageState(isEnabled);
}
@override @override
Web3Client? getWeb3Client(WalletBase wallet) { Web3Client? getWeb3Client(WalletBase wallet) =>
return (wallet as PolygonWallet).getWeb3Client(); (wallet as PolygonWallet).getWeb3Client();
}
String getTokenAddress(CryptoCurrency asset) => (asset as Erc20Token).contractAddress; @override
String getTokenAddress(CryptoCurrency asset) =>
(asset as Erc20Token).contractAddress;
@override
Future<PendingTransaction> createTokenApproval(WalletBase wallet,
BigInt amount, String spender, CryptoCurrency token, TransactionPriority priority) =>
(wallet as EVMChainWallet)
.createApprovalTransaction(amount, spender, token, priority as EVMChainTransactionPriority);
@override @override
void setLedgerConnection( void setLedgerConnection(
WalletBase wallet, ledger.LedgerConnection connection) { WalletBase wallet, ledger.LedgerConnection connection) {
((wallet as EVMChainWallet).evmChainPrivateKey as EvmLedgerCredentials) ((wallet as EVMChainWallet).evmChainPrivateKey as EvmLedgerCredentials)
.setLedgerConnection( .setLedgerConnection(
connection, wallet.walletInfo.derivationInfo?.derivationPath); connection, wallet.walletInfo.derivationInfo?.derivationPath);
} }
@override @override
@ -206,11 +210,12 @@ class CWPolygon extends Polygon {
throw err; throw err;
} }
} }
@override @override
List<String> getDefaultTokenContractAddresses() { List<String> getDefaultTokenContractAddresses() => DefaultPolygonErc20Tokens()
return DefaultPolygonErc20Tokens().initialPolygonErc20Tokens.map((e) => e.contractAddress).toList(); .initialPolygonErc20Tokens
} .map((e) => e.contractAddress)
.toList();
@override @override
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress) { bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress) {

View file

@ -48,6 +48,7 @@ import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dar
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_external_send_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_external_send_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart';
import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/faq/faq_page.dart';
import 'package:cake_wallet/src/screens/integrations/deuro/savings_page.dart';
import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart'; import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart';
@ -920,6 +921,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => getIt.get<DevSecurePreferencesPage>(), builder: (_) => getIt.get<DevSecurePreferencesPage>(),
); );
case Routes.dEuroSavings:
return MaterialPageRoute<void>(
builder: (_) => getIt.get<DEuroSavingsPage>(),
);
default: default:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => Scaffold( builder: (_) => Scaffold(

View file

@ -127,4 +127,6 @@ class Routes {
static const walletGroupExistingSeedDescriptionPage = '/wallet_group_existing_seed_description_page'; static const walletGroupExistingSeedDescriptionPage = '/wallet_group_existing_seed_description_page';
static const walletSeedVerificationPage = '/wallet_seed_verification_page'; static const walletSeedVerificationPage = '/wallet_seed_verification_page';
static const exchangeTradeExternalSendPage = '/exchange_trade_external_send_page'; static const exchangeTradeExternalSendPage = '/exchange_trade_external_send_page';
static const dEuroSavings = '/integration/dEuro/savings';
} }

View file

@ -5,15 +5,16 @@ 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';
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class CakeFeaturesPage extends StatelessWidget { class CakeFeaturesPage extends StatelessWidget {
CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel}); CakeFeaturesPage(
{required this.dashboardViewModel, required this.cakeFeaturesViewModel});
final DashboardViewModel dashboardViewModel; final DashboardViewModel dashboardViewModel;
final CakeFeaturesViewModel cakeFeaturesViewModel; final CakeFeaturesViewModel cakeFeaturesViewModel;
@ -58,6 +59,23 @@ class CakeFeaturesPage extends StatelessWidget {
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
if (dashboardViewModel.type == WalletType.ethereum) ...[
DashBoardRoundedCardWidget(
isDarkTheme: dashboardViewModel.isDarkTheme,
shadowBlur: dashboardViewModel.getShadowBlur(),
shadowSpread: dashboardViewModel.getShadowSpread(),
onTap: () =>
Navigator.of(context).pushNamed(Routes.dEuroSavings),
title: S.of(context).deuro_savings,
subTitle: S.of(context).deuro_savings_subtitle,
image: Image.asset(
'assets/images/deuro_icon.png',
height: 80,
width: 80,
fit: BoxFit.cover,
),
),
],
DashBoardRoundedCardWidget( DashBoardRoundedCardWidget(
isDarkTheme: dashboardViewModel.isDarkTheme, isDarkTheme: dashboardViewModel.isDarkTheme,
shadowBlur: dashboardViewModel.getShadowBlur(), shadowBlur: dashboardViewModel.getShadowBlur(),

View file

@ -0,0 +1,197 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/interest_card_widget.dart';
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_card_widget.dart';
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_edit_sheet.dart';
import 'package:cake_wallet/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart';
import 'package:cake_wallet/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/view_model/integrations/deuro_view_model.dart';
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class DEuroSavingsPage extends BasePage {
final DEuroViewModel _dEuroViewModel;
DEuroSavingsPage(this._dEuroViewModel);
@override
bool get gradientBackground => true;
@override
Widget Function(BuildContext, Widget) get rootWrapper =>
(context, scaffold) => GradientBackground(scaffold: scaffold);
@override
String get title => S.current.deuro_savings;
Widget trailing(BuildContext context) => MergeSemantics(
child: SizedBox(
height: 37,
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: Semantics(
label: "Refresh",
child: TextButton(
style: TextButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.onSurface,
overlayColor: WidgetStateColor.resolveWith(
(states) => Colors.transparent),
),
onPressed: _dEuroViewModel.reloadSavingsUserData,
child: Icon(
Icons.refresh,
color: pageIconColor(context),
size: 20,
),
),
),
),
),
);
@override
Widget body(BuildContext context) {
WidgetsBinding.instance
.addPostFrameCallback((_) => _setReactions(context, _dEuroViewModel));
return Container(
width: double.infinity,
child: Column(
children: <Widget>[
Observer(
builder: (_) => SavingsCard(
isDarkTheme: currentTheme.isDark,
interestRate: "${_dEuroViewModel.interestRate}%",
savingsBalance: _dEuroViewModel.savingsBalance,
currency: CryptoCurrency.deuro,
onAddSavingsPressed: () => _onSavingsAdd(context),
onRemoveSavingsPressed: () => _onSavingsRemove(context),
onApproveSavingsPressed: _dEuroViewModel.prepareApproval,
isEnabled: _dEuroViewModel.isEnabled,
),
),
Observer(
builder: (_) => InterestCardWidget(
isDarkTheme: currentTheme.isDark,
title: S.of(context).deuro_savings_collect_interest,
collectedInterest: _dEuroViewModel.accruedInterest,
onCollectInterest: _dEuroViewModel.prepareCollectInterest,
),
),
],
),
);
}
Future<void> _onSavingsAdd(BuildContext context) async {
final amount = await Navigator.of(context).push(MaterialPageRoute<String>(
builder: (BuildContext context) => SavingEditPage(isAdding: true)));
if (amount != null) _dEuroViewModel.prepareSavingsEdit(amount, true);
}
Future<void> _onSavingsRemove(BuildContext context) async {
final amount = await Navigator.of(context).push(MaterialPageRoute<String>(
builder: (BuildContext context) => SavingEditPage(isAdding: false)));
if (amount != null) _dEuroViewModel.prepareSavingsEdit(amount, false);
}
bool _isReactionsSet = false;
void _setReactions(BuildContext context, DEuroViewModel dEuroViewModel) {
if (_isReactionsSet) return;
reaction((_) => dEuroViewModel.transaction, (PendingTransaction? tx) async {
if (tx == null) return;
final result = await showModalBottomSheet<bool>(
context: context,
isDismissible: false,
isScrollControlled: true,
builder: (BuildContext bottomSheetContext) => ConfirmSendingBottomSheet(
key: ValueKey('savings_page_confirm_sending_dialog_key'),
titleText: S.of(bottomSheetContext).confirm_transaction,
currentTheme: currentTheme,
walletType: WalletType.ethereum,
titleIconPath: CryptoCurrency.deuro.iconPath,
currency: CryptoCurrency.deuro,
amount: S.of(bottomSheetContext).send_amount,
amountValue: tx.amountFormatted,
fiatAmountValue: "",
fee: S.of(bottomSheetContext).send_estimated_fee,
feeValue: tx.feeFormatted,
feeFiatAmount: "",
outputs: [],
onSlideComplete: () async {
Navigator.of(bottomSheetContext).pop(true);
dEuroViewModel.commitTransaction();
},
change: tx.change,
),
);
if (result == null) dEuroViewModel.dismissTransaction();
});
reaction((_) => dEuroViewModel.approvalTransaction, (PendingTransaction? tx) async {
if (tx == null) return;
final result = await showModalBottomSheet<bool>(
context: context,
isDismissible: false,
isScrollControlled: true,
builder: (BuildContext bottomSheetContext) => ConfirmSendingBottomSheet(
key: ValueKey('savings_page_confirm_approval_dialog_key'),
titleText: S.of(bottomSheetContext).approve_tokens,
currentTheme: currentTheme,
walletType: WalletType.ethereum,
titleIconPath: CryptoCurrency.deuro.iconPath,
currency: CryptoCurrency.deuro,
amount: S.of(bottomSheetContext).send_amount,
amountValue: tx.amountFormatted,
fiatAmountValue: "",
fee: S.of(bottomSheetContext).send_estimated_fee,
feeValue: tx.feeFormatted,
feeFiatAmount: "",
outputs: [],
onSlideComplete: () {
Navigator.of(bottomSheetContext).pop(true);
dEuroViewModel.commitApprovalTransaction();
},
change: tx.change,
),
);
if (result == null) dEuroViewModel.dismissTransaction();
});
reaction((_) => dEuroViewModel.state, (ExecutionState state) async {
if (state is TransactionCommitted) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (!context.mounted) return;
await showModalBottomSheet<void>(
context: context,
isDismissible: false,
builder: (BuildContext bottomSheetContext) => InfoBottomSheet(
currentTheme: currentTheme,
titleText: S.of(bottomSheetContext).transaction_sent,
contentImage: 'assets/images/birthday_cake.png',
content: S.of(bottomSheetContext).deuro_tx_commited_content,
actionButtonText: S.of(bottomSheetContext).close,
actionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'),
actionButton: () => Navigator.of(bottomSheetContext).pop(),
),
);
});
}
});
_isReactionsSet = true;
}
}

View file

@ -0,0 +1,67 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_card_widget.dart';
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:flutter/material.dart';
class InterestCardWidget extends StatelessWidget {
InterestCardWidget({
required this.title,
required this.collectedInterest,
super.key,
required this.isDarkTheme,
required this.onCollectInterest,
});
final String title;
final String collectedInterest;
final bool isDarkTheme;
final VoidCallback onCollectInterest;
@override
Widget build(BuildContext context) {
return Stack(children: [
Container(
margin: EdgeInsets.symmetric(horizontal: 16),
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [
isDarkTheme
? CustomThemeColors.cardGradientColorPrimaryDark
: CustomThemeColors.cardGradientColorPrimaryLight,
isDarkTheme
? CustomThemeColors.cardGradientColorSecondaryDark
: CustomThemeColors.cardGradientColorSecondaryLight,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
SavingsCard.getAssetBalanceRow(
context,
title: title,
subtitle: collectedInterest,
currency: CryptoCurrency.deuro,
hideSymbol: true,
),
SizedBox(height: 10),
SavingsCard.getButton(
context,
label: S.of(context).deuro_collect_interest,
onPressed: onCollectInterest,
backgroundColor: Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.onPrimary,
),
],
),
),
),
]);
}
}

View file

@ -0,0 +1,107 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class NumberPad extends StatelessWidget {
final VoidCallback? onDecimalPressed;
final VoidCallback onDeletePressed;
final void Function(int index) onNumberPressed;
final FocusNode focusNode;
const NumberPad({
super.key,
required this.onNumberPressed,
required this.onDeletePressed,
required this.focusNode,
this.onDecimalPressed,
});
@override
Widget build(BuildContext context) => KeyboardListener(
focusNode: focusNode,
onKeyEvent: (keyEvent) {
if (keyEvent is KeyDownEvent) {
if (keyEvent.logicalKey.keyLabel == "Backspace") {
return onDeletePressed();
}
if ([".", ","].contains(keyEvent.logicalKey.keyLabel) &&
onDecimalPressed != null) {
return onDecimalPressed!();
}
int? number = int.tryParse(keyEvent.character ?? '');
if (number != null) return onNumberPressed(number);
}
},
child: SizedBox(
height: 300,
child: GridView.count(
childAspectRatio: 2,
shrinkWrap: true,
crossAxisCount: 3,
physics: const NeverScrollableScrollPhysics(),
children: List.generate(12, (index) {
if (index == 9) {
if (onDecimalPressed == null) return Container();
return InkWell(
onTap: onDecimalPressed,
child: Center(
child: Text(
'.',
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 30,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
textAlign: TextAlign.center,
),
),
);
} else if (index == 10) {
index = 0;
} else if (index == 11) {
return MergeSemantics(
child: Container(
child: Semantics(
label: S.of(context).delete,
button: true,
onTap: onDeletePressed,
child: TextButton(
onPressed: onDeletePressed,
style: TextButton.styleFrom(
backgroundColor:
Colors.transparent,
shape: CircleBorder(),
),
child: Image.asset(
'assets/images/delete_icon.png',
color: Theme.of(context).colorScheme.primary,
),
),
),
),
);
} else {
index++;
}
return InkWell(
onTap: () => onNumberPressed(index),
child: Center(
child: Text(
'$index',
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 30,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
textAlign: TextAlign.center,
),
),
);
}),
),
),
);
}

View file

@ -0,0 +1,263 @@
import 'dart:math';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:flutter/material.dart';
class SavingsCard extends StatelessWidget {
final bool isDarkTheme;
final bool isEnabled;
final String interestRate;
final String savingsBalance;
final CryptoCurrency currency;
final VoidCallback onAddSavingsPressed;
final VoidCallback onRemoveSavingsPressed;
final VoidCallback onApproveSavingsPressed;
const SavingsCard({
super.key,
required this.isDarkTheme,
required this.interestRate,
required this.savingsBalance,
required this.currency,
required this.onAddSavingsPressed,
required this.onRemoveSavingsPressed,
required this.onApproveSavingsPressed,
this.isEnabled = true,
});
@override
Widget build(BuildContext context) => Container(
margin: const EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [
isDarkTheme
? CustomThemeColors.cardGradientColorPrimaryDark
: CustomThemeColors.cardGradientColorPrimaryLight,
isDarkTheme
? CustomThemeColors.cardGradientColorSecondaryDark
: CustomThemeColors.cardGradientColorSecondaryLight,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
getAssetBalanceRow(context,
title: S.of(context).deuro_savings_balance,
subtitle: savingsBalance,
currency: currency),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
children: [
Expanded(
child: Text(
'Current APR',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color:
Theme.of(context).colorScheme.onSurfaceVariant,
fontWeight: FontWeight.w500,
),
softWrap: true,
),
),
Text(
interestRate,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontWeight: FontWeight.w500,
),
softWrap: true,
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: isEnabled
? [
Expanded(
child: getButton(
context,
label: S.of(context).deuro_savings_add,
imagePath: 'assets/images/received.png',
onPressed: onAddSavingsPressed,
backgroundColor:
Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.onPrimary,
),
),
SizedBox(width: 12),
Expanded(
child: getButton(
context,
label: S.of(context).deuro_savings_remove,
imagePath: 'assets/images/upload.png',
onPressed: onRemoveSavingsPressed,
backgroundColor:
Theme.of(context).colorScheme.surface,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
),
),
]
: [
Expanded(
child: getButton(
context,
label: S.of(context).deuro_savings_set_approval,
onPressed: onApproveSavingsPressed,
backgroundColor:
Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.onPrimary,
),
)
],
),
],
),
));
static Widget getButton(
BuildContext context, {
required String label,
String? imagePath,
required VoidCallback onPressed,
required Color backgroundColor,
required Color color,
}) =>
Semantics(
label: label,
child: OutlinedButton(
onPressed: onPressed,
style: OutlinedButton.styleFrom(
backgroundColor: backgroundColor,
side: BorderSide(
color: Theme.of(context).colorScheme.outlineVariant.withAlpha(0),
width: 0,
),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (imagePath != null) ...[
Image.asset(
imagePath,
height: 30,
width: 30,
color: color,
),
const SizedBox(width: 8),
],
Text(
label,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: color,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
);
static Widget getAssetBalanceRow(
BuildContext context, {
required String title,
required String subtitle,
required CryptoCurrency currency,
bool hideSymbol = true,
}) =>
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
height: 1,
),
),
SizedBox(height: 6),
AutoSizeText(
subtitle,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.w900,
fontSize: 24,
height: 1,
),
maxLines: 1,
textAlign: TextAlign.start,
),
],
),
SizedBox(
//width: min(MediaQuery.of(context).size.width * 0.2, 100),
child: Center(
child: Column(
children: [
CakeImageWidget(
imageUrl: currency.iconPath,
height: 40,
width: 40,
errorWidget: Container(
height: 30.0,
width: 30.0,
child: Center(
child: Text(
currency.title
.substring(0, min(currency.title.length, 2)),
style:
Theme.of(context).textTheme.bodySmall?.copyWith(
fontSize: 11,
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
),
),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).colorScheme.surfaceContainer,
),
),
),
if (!hideSymbol) ...[
const SizedBox(height: 10),
Text(
currency.title,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w700,
color: Theme.of(context).colorScheme.onSurface,
height: 1,
),
),
]
],
),
),
),
],
);
}

View file

@ -0,0 +1,90 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/numpad.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:flutter/material.dart';
class SavingEditPage extends BasePage {
final bool isAdding;
SavingEditPage({required this.isAdding});
String get title =>
isAdding ? S.current.deuro_savings_add : S.current.deuro_savings_remove;
@override
Widget body(BuildContext context) => _SavingsEditBody();
}
class _SavingsEditBody extends StatefulWidget {
const _SavingsEditBody();
@override
State<StatefulWidget> createState() => _SavingsEditBodyState();
}
class _SavingsEditBodyState extends State<_SavingsEditBody> {
@override
void initState() {
WidgetsBinding.instance
.addPostFrameCallback((_) => _numpadFocusNode.requestFocus());
super.initState();
}
@override
void dispose() {
_numpadFocusNode.dispose();
super.dispose();
}
String amount = '0';
final FocusNode _numpadFocusNode = FocusNode();
@override
Widget build(BuildContext context) => SafeArea(
child: Column(children: [
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.only(left: 26, right: 26, top: 10),
child: AutoSizeText(
"${amount.toString()} dEuro",
maxLines: 1,
maxFontSize: 60,
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 60,
color: Theme.of(context).colorScheme.onSurface,
),
textAlign: TextAlign.center,
),
),
)),
NumberPad(
focusNode: _numpadFocusNode,
onNumberPressed: (i) => setState(
() => amount = amount == '0' ? i.toString() : '${amount}${i}',
),
onDeletePressed: () => setState(
() => amount = amount.length > 1
? amount.substring(0, amount.length - 1)
: '0',
),
onDecimalPressed: () =>
setState(() => amount = '${amount.replaceAll('.', '')}.'),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 34),
child: LoadingPrimaryButton(
onPressed: () => Navigator.pop(context, amount),
text: S.of(context).confirm,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
isLoading: false,
isDisabled: false,
),
)
]),
);
}

View file

@ -109,6 +109,7 @@ class DashBoardRoundedCardWidget extends StatelessWidget {
], ],
), ),
), ),
Padding(padding: EdgeInsets.only(left: 10)),
if (image != null) image! else if (svgPicture != null) svgPicture!, if (image != null) image! else if (svgPicture != null) svgPicture!,
if (icon != null) icon! if (icon != null) icon!
], ],

View file

@ -0,0 +1,119 @@
import 'dart:math';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
part 'deuro_view_model.g.dart';
class DEuroViewModel = DEuroViewModelBase with _$DEuroViewModel;
abstract class DEuroViewModelBase with Store {
final AppStore _appStore;
DEuroViewModelBase(this._appStore) {
reloadInterestRate();
reloadSavingsUserData();
}
@observable
String savingsBalance = '0.00';
@observable
ExecutionState state = InitialExecutionState();
@observable
String interestRate = '0';
@observable
String accruedInterest = '0.00';
@observable
BigInt approvedTokens = BigInt.zero;
@computed
bool get isEnabled => approvedTokens > BigInt.zero;
@observable
PendingTransaction? transaction = null;
@observable
PendingTransaction? approvalTransaction = null;
@action
Future<void> reloadSavingsUserData() async {
final savingsBalanceRaw =
ethereum!.getDEuroSavingsBalance(_appStore.wallet!);
final accruedInterestRaw =
ethereum!.getDEuroAccruedInterest(_appStore.wallet!);
approvedTokens = await ethereum!.getDEuroSavingsApproved(_appStore.wallet!);
savingsBalance = ethereum!
.formatterEthereumAmountToDouble(amount: await savingsBalanceRaw)
.toStringAsFixed(6);
accruedInterest = ethereum!
.formatterEthereumAmountToDouble(amount: await accruedInterestRaw)
.toStringAsFixed(6);
}
@action
Future<void> reloadInterestRate() async {
final interestRateRaw =
await ethereum!.getDEuroInterestRate(_appStore.wallet!);
interestRate = (interestRateRaw / BigInt.from(10000)).toString();
}
@action
Future<void> prepareApproval() async {
final priority = _appStore.settingsStore.priority[WalletType.ethereum]!;
approvalTransaction =
await ethereum!.enableDEuroSaving(_appStore.wallet!, priority);
}
@action
Future<void> prepareSavingsEdit(String amountRaw, bool isAdding) async {
final amount = BigInt.from(num.parse(amountRaw) * pow(10, 18));
final priority = _appStore.settingsStore.priority[WalletType.ethereum]!;
transaction = await (isAdding
? ethereum!.addDEuroSaving(_appStore.wallet!, amount, priority)
: ethereum!.removeDEuroSaving(_appStore.wallet!, amount, priority));
}
Future<void> prepareCollectInterest() =>
prepareSavingsEdit(accruedInterest, false);
@action
Future<void> commitTransaction() async {
if (transaction != null) {
state = TransactionCommitting();
await transaction!.commit();
transaction = null;
reloadSavingsUserData();
state = TransactionCommitted();
}
}
@action
Future<void> commitApprovalTransaction() async {
if (approvalTransaction != null) {
state = TransactionCommitting();
await approvalTransaction!.commit();
approvalTransaction = null;
reloadSavingsUserData();
state = TransactionCommitted();
}
}
@action
void dismissTransaction() {
transaction == null;
approvalTransaction = null;
state = InitialExecutionState();
}
}

View file

@ -56,6 +56,7 @@
"apk_update": "تحديث APK", "apk_update": "تحديث APK",
"approve": "ﺪﻤﺘﻌﻳ", "approve": "ﺪﻤﺘﻌﻳ",
"approve_request": "الموافقة على الطلب", "approve_request": "الموافقة على الطلب",
"approve_tokens": "الموافقة على الرموز",
"arrive_in_this_address": "سيصل ${currency} ${tag}إلى هذا العنوان", "arrive_in_this_address": "سيصل ${currency} ${tag}إلى هذا العنوان",
"ascending": "تصاعدي", "ascending": "تصاعدي",
"ask_each_time": "اسأل في كل مرة", "ask_each_time": "اسأل في كل مرة",
@ -244,6 +245,15 @@
"descending": "النزول", "descending": "النزول",
"description": "ﻒﺻﻭ", "description": "ﻒﺻﻭ",
"destination_tag": "علامة الوجهة:", "destination_tag": "علامة الوجهة:",
"deuro_collect_interest": "يجمع",
"deuro_savings": "الادخار ديورو",
"deuro_savings_add": "إيداع",
"deuro_savings_balance": "توازن الادخار",
"deuro_savings_collect_interest": "جمع الاهتمام",
"deuro_savings_remove": "ينسحب",
"deuro_savings_set_approval": "تعيين الموافقة",
"deuro_savings_subtitle": "كسب ما يصل إلى 10 ٪ فائدة على مقتنيات Deuro Stablecoin",
"deuro_tx_commited_content": "قد يستغرق الأمر بضع ثوانٍ حتى يتم تأكيد المعاملة وينعكس على الشاشة",
"device_is_signing": "الجهاز يوقع", "device_is_signing": "الجهاز يوقع",
"dfx_option_description": "شراء التشفير مع EUR & CHF. لعملاء البيع بالتجزئة والشركات في أوروبا", "dfx_option_description": "شراء التشفير مع EUR & CHF. لعملاء البيع بالتجزئة والشركات في أوروبا",
"didnt_get_code": "لم تحصل على رمز؟", "didnt_get_code": "لم تحصل على رمز؟",

View file

@ -56,6 +56,7 @@
"apk_update": "APK ъпдейт", "apk_update": "APK ъпдейт",
"approve": "Одобряване", "approve": "Одобряване",
"approve_request": "Одобрете искане", "approve_request": "Одобрете искане",
"approve_tokens": "Одобрете жетоните",
"arrive_in_this_address": "${currency} ${tag}ще отидат на този адрес", "arrive_in_this_address": "${currency} ${tag}ще отидат на този адрес",
"ascending": "Възходящ", "ascending": "Възходящ",
"ask_each_time": "Питайте всеки път", "ask_each_time": "Питайте всеки път",
@ -244,6 +245,15 @@
"descending": "Низходящ", "descending": "Низходящ",
"description": "Описание", "description": "Описание",
"destination_tag": "Destination tag:", "destination_tag": "Destination tag:",
"deuro_collect_interest": "Събиране",
"deuro_savings": "Спестявания на Деуро",
"deuro_savings_add": "Депозит",
"deuro_savings_balance": "Спестотен баланс",
"deuro_savings_collect_interest": "Събиране на интерес",
"deuro_savings_remove": "Оттегляне",
"deuro_savings_set_approval": "Задайте одобрение",
"deuro_savings_subtitle": "Печелете до 10% лихва за вашите Deuro Stablecoin Holdings",
"deuro_tx_commited_content": "Може да отнеме няколко секунди, за да може транзакцията да се потвърди и да бъде отразена на екрана",
"device_is_signing": "Устройството подписва", "device_is_signing": "Устройството подписва",
"dfx_option_description": "Купете криптовалута с Eur & CHF. За търговски и корпоративни клиенти в Европа", "dfx_option_description": "Купете криптовалута с Eur & CHF. За търговски и корпоративни клиенти в Европа",
"didnt_get_code": "Не получихте код?", "didnt_get_code": "Не получихте код?",

View file

@ -56,6 +56,7 @@
"apk_update": "aktualizace APK", "apk_update": "aktualizace APK",
"approve": "Schvalovat", "approve": "Schvalovat",
"approve_request": "Schválit žádost", "approve_request": "Schválit žádost",
"approve_tokens": "Schválit tokeny",
"arrive_in_this_address": "${currency} ${tag}přijde na tuto adresu", "arrive_in_this_address": "${currency} ${tag}přijde na tuto adresu",
"ascending": "Vzestupné", "ascending": "Vzestupné",
"ask_each_time": "Zeptejte se pokaždé", "ask_each_time": "Zeptejte se pokaždé",
@ -244,6 +245,15 @@
"descending": "Klesající", "descending": "Klesající",
"description": "Popis", "description": "Popis",
"destination_tag": "Destination Tag:", "destination_tag": "Destination Tag:",
"deuro_collect_interest": "Sbírat",
"deuro_savings": "dEuro úspory",
"deuro_savings_add": "Vklad",
"deuro_savings_balance": "Úspora zůstatek",
"deuro_savings_collect_interest": "Sbírat zájem",
"deuro_savings_remove": "Odstoupit",
"deuro_savings_set_approval": "Stanovit schválení",
"deuro_savings_subtitle": "Získejte až 10% úrok z vašeho Deuro Stablecoin Holdings",
"deuro_tx_commited_content": "Transakce může trvat několik sekund, aby se potvrdila a odrážela se na obrazovce",
"device_is_signing": "Zařízení se podpisu", "device_is_signing": "Zařízení se podpisu",
"dfx_option_description": "Koupit krypto s EUR & CHF. Pro maloobchodní a firemní zákazníky v Evropě", "dfx_option_description": "Koupit krypto s EUR & CHF. Pro maloobchodní a firemní zákazníky v Evropě",
"didnt_get_code": "Nepřišel Vám kód?", "didnt_get_code": "Nepřišel Vám kód?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK-Update", "apk_update": "APK-Update",
"approve": "Genehmigen", "approve": "Genehmigen",
"approve_request": "Anfrage genehmigen", "approve_request": "Anfrage genehmigen",
"approve_tokens": "Token genehmigen",
"arrive_in_this_address": "${currency} ${tag} wird an dieser Adresse ankommen", "arrive_in_this_address": "${currency} ${tag} wird an dieser Adresse ankommen",
"ascending": "Aufsteigend", "ascending": "Aufsteigend",
"ask_each_time": "Jedes Mal fragen", "ask_each_time": "Jedes Mal fragen",
@ -206,7 +207,7 @@
"copy": "Kopieren", "copy": "Kopieren",
"copy_address": "Adresse kopieren", "copy_address": "Adresse kopieren",
"copy_id": "ID kopieren", "copy_id": "ID kopieren",
"copy_payjoin_address": "Kopieren Sie Payjoin -Adresse", "copy_payjoin_address": "Kopieren Sie Payjoin-Adresse",
"copy_payjoin_url": "Payjoin URL kopieren", "copy_payjoin_url": "Payjoin URL kopieren",
"copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein", "copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein",
"corrupted_seed_notice": "Die Dateien für diese Wallet sind beschädigt und können nicht geöffnet werden. Bitte sehen Sie sich die Seeds an, speichern Sie sie und stellen Sie die Wallet wieder her.\n\nWenn der Wert leer ist, konnte der Seed nicht korrekt wiederhergestellt werden.", "corrupted_seed_notice": "Die Dateien für diese Wallet sind beschädigt und können nicht geöffnet werden. Bitte sehen Sie sich die Seeds an, speichern Sie sie und stellen Sie die Wallet wieder her.\n\nWenn der Wert leer ist, konnte der Seed nicht korrekt wiederhergestellt werden.",
@ -244,6 +245,15 @@
"descending": "Absteigend", "descending": "Absteigend",
"description": "Beschreibung", "description": "Beschreibung",
"destination_tag": "Ziel-Tag:", "destination_tag": "Ziel-Tag:",
"deuro_collect_interest": "Auszahlen",
"deuro_savings": "dEuro-Savings",
"deuro_savings_add": "Einzahlen",
"deuro_savings_balance": "Sparguthaben",
"deuro_savings_collect_interest": "Interesse sammeln",
"deuro_savings_remove": "Auszahlen",
"deuro_savings_set_approval": "Genehmigung festlegen",
"deuro_savings_subtitle": "Verdienen Sie bis zu 10% Zinsen für Ihre dEuro Stablecoin Holdings",
"deuro_tx_commited_content": "Es kann ein paar Sekunden dauern, bis die Transaktion bestätigt und auf dem Bildschirm angezeigt",
"device_is_signing": "Das Gerät unterschreibt", "device_is_signing": "Das Gerät unterschreibt",
"dfx_option_description": "Kaufen Sie Krypto mit EUR & CHF. Für Einzelhandel und Unternehmenskunden in Europa", "dfx_option_description": "Kaufen Sie Krypto mit EUR & CHF. Für Einzelhandel und Unternehmenskunden in Europa",
"didnt_get_code": "Kein Code?", "didnt_get_code": "Kein Code?",
@ -1099,4 +1109,4 @@
"you_will_send": "Konvertieren von", "you_will_send": "Konvertieren von",
"youCanGoBackToYourDapp": "Sie können jetzt zu Ihrem Dapp zurückkehren", "youCanGoBackToYourDapp": "Sie können jetzt zu Ihrem Dapp zurückkehren",
"yy": "YY" "yy": "YY"
} }

View file

@ -56,6 +56,7 @@
"apk_update": "APK update", "apk_update": "APK update",
"approve": "Approve", "approve": "Approve",
"approve_request": "Approve Request", "approve_request": "Approve Request",
"approve_tokens": "Approve tokens",
"arrive_in_this_address": "${currency} ${tag}will arrive in this address", "arrive_in_this_address": "${currency} ${tag}will arrive in this address",
"ascending": "Ascending", "ascending": "Ascending",
"ask_each_time": "Ask each time", "ask_each_time": "Ask each time",
@ -244,6 +245,15 @@
"descending": "Descending", "descending": "Descending",
"description": "Description", "description": "Description",
"destination_tag": "Destination tag:", "destination_tag": "Destination tag:",
"deuro_collect_interest": "Collect",
"deuro_savings": "dEuro Savings",
"deuro_savings_add": "Deposit",
"deuro_savings_balance": "Savings Balance",
"deuro_savings_collect_interest": "Collect interest",
"deuro_savings_remove": "Withdraw",
"deuro_savings_set_approval": "Set approval",
"deuro_savings_subtitle": "Earn up to 10% interest on your dEuro Stablecoin holdings",
"deuro_tx_commited_content": "It might take a couple of seconds for the transaction to confirm and be reflected on screen",
"device_is_signing": "Device is signing", "device_is_signing": "Device is signing",
"dfx_option_description": "Buy crypto with EUR & CHF. For retail and corporate customers in Europe", "dfx_option_description": "Buy crypto with EUR & CHF. For retail and corporate customers in Europe",
"didnt_get_code": "Didn't get code?", "didnt_get_code": "Didn't get code?",

View file

@ -56,6 +56,7 @@
"apk_update": "Actualización de APK", "apk_update": "Actualización de APK",
"approve": "Aprobar", "approve": "Aprobar",
"approve_request": "Aprobar la solicitud", "approve_request": "Aprobar la solicitud",
"approve_tokens": "Aprobar tokens",
"arrive_in_this_address": "${currency} ${tag}llegará a esta dirección", "arrive_in_this_address": "${currency} ${tag}llegará a esta dirección",
"ascending": "Ascendente", "ascending": "Ascendente",
"ask_each_time": "Pregunta cada vez", "ask_each_time": "Pregunta cada vez",
@ -244,6 +245,15 @@
"descending": "Descendente", "descending": "Descendente",
"description": "Descripción", "description": "Descripción",
"destination_tag": "Etiqueta de destino:", "destination_tag": "Etiqueta de destino:",
"deuro_collect_interest": "Recolectar",
"deuro_savings": "ahorros de deuro",
"deuro_savings_add": "Depósito",
"deuro_savings_balance": "Saldo de ahorro",
"deuro_savings_collect_interest": "Cobrar interés",
"deuro_savings_remove": "Retirar",
"deuro_savings_set_approval": "Establecer aprobación",
"deuro_savings_subtitle": "Gane hasta un 10% de interés en sus Holdings de Deuro Stablecoin",
"deuro_tx_commited_content": "La transacción puede tardar un par de segundos en confirmar y reflejarse en la pantalla",
"device_is_signing": "El dispositivo está firmando", "device_is_signing": "El dispositivo está firmando",
"dfx_option_description": "Compre cripto con EUR y CHF. Para clientes minoristas y corporativos en Europa", "dfx_option_description": "Compre cripto con EUR y CHF. Para clientes minoristas y corporativos en Europa",
"didnt_get_code": "¿No recibiste el código?", "didnt_get_code": "¿No recibiste el código?",

View file

@ -56,6 +56,7 @@
"apk_update": "Mise à jour d'APK", "apk_update": "Mise à jour d'APK",
"approve": "Approuver", "approve": "Approuver",
"approve_request": "Approuver la demande", "approve_request": "Approuver la demande",
"approve_tokens": "Approuver les jetons",
"arrive_in_this_address": "${currency} ${tag}arrivera à cette adresse", "arrive_in_this_address": "${currency} ${tag}arrivera à cette adresse",
"ascending": "Ascendant", "ascending": "Ascendant",
"ask_each_time": "Demander à chaque fois", "ask_each_time": "Demander à chaque fois",
@ -244,6 +245,15 @@
"descending": "Descendant", "descending": "Descendant",
"description": "Description", "description": "Description",
"destination_tag": "Tag de destination :", "destination_tag": "Tag de destination :",
"deuro_collect_interest": "Collecter",
"deuro_savings": "Économies de deuro",
"deuro_savings_add": "Dépôt",
"deuro_savings_balance": "Solde d'épargne",
"deuro_savings_collect_interest": "Percevoir l'intérêt",
"deuro_savings_remove": "Retirer",
"deuro_savings_set_approval": "Établir l'approbation",
"deuro_savings_subtitle": "Gagnez jusqu'à 10% d'intérêt sur vos avoirs de Deuro Stablecoin",
"deuro_tx_commited_content": "Il pourrait prendre quelques secondes pour que la transaction confirme et soit reflétée à l'écran",
"device_is_signing": "L'appareil signale", "device_is_signing": "L'appareil signale",
"dfx_option_description": "Achetez de la crypto avec EUR & CHF. Pour les clients de la vente au détail et des entreprises en Europe", "dfx_option_description": "Achetez de la crypto avec EUR & CHF. Pour les clients de la vente au détail et des entreprises en Europe",
"didnt_get_code": "Vous n'avez pas reçu le code ?", "didnt_get_code": "Vous n'avez pas reçu le code ?",

View file

@ -56,6 +56,7 @@
"apk_update": "apk sabunta", "apk_update": "apk sabunta",
"approve": "Amincewa", "approve": "Amincewa",
"approve_request": "Amince da bukata", "approve_request": "Amince da bukata",
"approve_tokens": "Amince da Alamu",
"arrive_in_this_address": "${currency} ${tag} zai je wurin wannan adireshi", "arrive_in_this_address": "${currency} ${tag} zai je wurin wannan adireshi",
"ascending": "Hau", "ascending": "Hau",
"ask_each_time": "Tambaya kowane lokaci", "ask_each_time": "Tambaya kowane lokaci",
@ -244,6 +245,15 @@
"descending": "Saukowa", "descending": "Saukowa",
"description": "Bayani", "description": "Bayani",
"destination_tag": "Tambarin makoma:", "destination_tag": "Tambarin makoma:",
"deuro_collect_interest": "Tara",
"deuro_savings": "deuro tanadi",
"deuro_savings_add": "Yi ajiya",
"deuro_savings_balance": "Ma'auni",
"deuro_savings_collect_interest": "Tattara amfani da sha'awa",
"deuro_savings_remove": "Janye",
"deuro_savings_set_approval": "Saita yarda",
"deuro_savings_subtitle": "Sami har zuwa 10% sha'awa a kan Deuro Stovecoin Rike",
"deuro_tx_commited_content": "Yana iya ɗaukar wasu secondsan seconds don ma'amala don tabbatarwa kuma a nuna shi a allon",
"device_is_signing": "Na'urar tana shiga", "device_is_signing": "Na'urar tana shiga",
"dfx_option_description": "Buy crypto tare da Eur & Chf. Don Retail da abokan ciniki na kamfanoni a Turai", "dfx_option_description": "Buy crypto tare da Eur & Chf. Don Retail da abokan ciniki na kamfanoni a Turai",
"didnt_get_code": "Ba a samun code?", "didnt_get_code": "Ba a samun code?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK अद्यतन", "apk_update": "APK अद्यतन",
"approve": "मंज़ूरी देना", "approve": "मंज़ूरी देना",
"approve_request": "अनुरोध को स्वीकृत करें", "approve_request": "अनुरोध को स्वीकृत करें",
"approve_tokens": "टोकन को मंजूरी देना",
"arrive_in_this_address": "${currency} ${tag}इस पते पर पहुंचेंगे", "arrive_in_this_address": "${currency} ${tag}इस पते पर पहुंचेंगे",
"ascending": "आरोही", "ascending": "आरोही",
"ask_each_time": "हर बार पूछें", "ask_each_time": "हर बार पूछें",
@ -244,6 +245,15 @@
"descending": "अवरोही", "descending": "अवरोही",
"description": "विवरण", "description": "विवरण",
"destination_tag": "गंतव्य टैग:", "destination_tag": "गंतव्य टैग:",
"deuro_collect_interest": "इकट्ठा करना",
"deuro_savings": "देउरो बचत",
"deuro_savings_add": "जमा",
"deuro_savings_balance": "बचत शेष",
"deuro_savings_collect_interest": "ब्याज इकट्ठा करना",
"deuro_savings_remove": "निकालना",
"deuro_savings_set_approval": "अनुमोदन निर्धारित करना",
"deuro_savings_subtitle": "अपने Deuro Stablecoin होल्डिंग्स पर 10% ब्याज कमाएँ",
"deuro_tx_commited_content": "लेन -देन की पुष्टि करने और स्क्रीन पर प्रतिबिंबित होने के लिए कुछ सेकंड लग सकते हैं",
"device_is_signing": "उपकरण हस्ताक्षर कर रहा है", "device_is_signing": "उपकरण हस्ताक्षर कर रहा है",
"dfx_option_description": "EUR और CHF के साथ क्रिप्टो खरीदें। यूरोप में खुदरा और कॉर्पोरेट ग्राहकों के लिए", "dfx_option_description": "EUR और CHF के साथ क्रिप्टो खरीदें। यूरोप में खुदरा और कॉर्पोरेट ग्राहकों के लिए",
"didnt_get_code": "कोड नहीं मिला?", "didnt_get_code": "कोड नहीं मिला?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK ažuriranje", "apk_update": "APK ažuriranje",
"approve": "Odobriti", "approve": "Odobriti",
"approve_request": "Odobriti zahtjev", "approve_request": "Odobriti zahtjev",
"approve_tokens": "Odobriti tokene",
"arrive_in_this_address": "${currency} ${tag}će stići na ovu adresu", "arrive_in_this_address": "${currency} ${tag}će stići na ovu adresu",
"ascending": "Uzlazni", "ascending": "Uzlazni",
"ask_each_time": "Pitajte svaki put", "ask_each_time": "Pitajte svaki put",
@ -244,6 +245,15 @@
"descending": "Silazni", "descending": "Silazni",
"description": "Opis", "description": "Opis",
"destination_tag": "Odredišna oznaka:", "destination_tag": "Odredišna oznaka:",
"deuro_collect_interest": "Prikupiti",
"deuro_savings": "deuro ušteda",
"deuro_savings_add": "Depozit",
"deuro_savings_balance": "Ravnoteža uštede",
"deuro_savings_collect_interest": "Prikupiti interes",
"deuro_savings_remove": "Povući",
"deuro_savings_set_approval": "Odrediti odobrenje",
"deuro_savings_subtitle": "Zaradite do 10% kamate na svoje Deuro Stablecoin Holdings",
"deuro_tx_commited_content": "Možda će trebati nekoliko sekundi da se transakcija potvrdi i odrazi na zaslonu",
"device_is_signing": "Uređaj se potpisuje", "device_is_signing": "Uređaj se potpisuje",
"dfx_option_description": "Kupite kriptovalute s Eur & CHF. Za maloprodajne i korporativne kupce u Europi", "dfx_option_description": "Kupite kriptovalute s Eur & CHF. Za maloprodajne i korporativne kupce u Europi",
"didnt_get_code": "Ne dobivate kod?", "didnt_get_code": "Ne dobivate kod?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK թարմացում", "apk_update": "APK թարմացում",
"approve": "Հաստատել", "approve": "Հաստատել",
"approve_request": "Հաստատում է հայցը", "approve_request": "Հաստատում է հայցը",
"approve_tokens": "Հաստատում է նշանները",
"arrive_in_this_address": "${currency} ${tag}կժամանի այս հասցեում", "arrive_in_this_address": "${currency} ${tag}կժամանի այս հասցեում",
"ascending": "Աճող", "ascending": "Աճող",
"ask_each_time": "Հարցնել ամեն անգամ", "ask_each_time": "Հարցնել ամեն անգամ",
@ -244,6 +245,15 @@
"descending": "Նվազող", "descending": "Նվազող",
"description": "Նկարագրություն", "description": "Նկարագրություն",
"destination_tag": "Նպատակակետի պիտակ:", "destination_tag": "Նպատակակետի պիտակ:",
"deuro_collect_interest": "Հավաքել",
"deuro_savings": "dEuro խնայողություններ",
"deuro_savings_add": "Ավանդ",
"deuro_savings_balance": "Խնայողական հավասարակշռություն",
"deuro_savings_collect_interest": "Հավաքեք հետաքրքրություն",
"deuro_savings_remove": "Հեռացնել",
"deuro_savings_set_approval": "Սահմանել հաստատում",
"deuro_savings_subtitle": "Վաստակեք մինչեւ 10% տոկոսադրույքներ ձեր Deuro Stablecoin Holdings- ի համար",
"deuro_tx_commited_content": "Գործարքի հաստատման եւ արտացոլվելու համար գործարքի համար կարող է տեւել մի քանի վայրկյան",
"device_is_signing": "Սարքը ստորագրում է", "device_is_signing": "Սարքը ստորագրում է",
"dfx_option_description": "Գնեք կրիպտոարժույթ EUR և CHF: Կորպորատիվ և մանրածախ հաճախորդների համար Եվրոպայում", "dfx_option_description": "Գնեք կրիպտոարժույթ EUR և CHF: Կորպորատիվ և մանրածախ հաճախորդների համար Եվրոպայում",
"didnt_get_code": "Չեք ստացել կոդը?", "didnt_get_code": "Չեք ստացել կոդը?",

View file

@ -56,6 +56,7 @@
"apk_update": "Pembaruan APK", "apk_update": "Pembaruan APK",
"approve": "Menyetujui", "approve": "Menyetujui",
"approve_request": "Menyetujui permintaan", "approve_request": "Menyetujui permintaan",
"approve_tokens": "Menyetujui token",
"arrive_in_this_address": "${currency} ${tag} akan tiba di alamat ini", "arrive_in_this_address": "${currency} ${tag} akan tiba di alamat ini",
"ascending": "Naik", "ascending": "Naik",
"ask_each_time": "Tanyakan setiap kali", "ask_each_time": "Tanyakan setiap kali",
@ -244,6 +245,15 @@
"descending": "Menurun", "descending": "Menurun",
"description": "Keterangan", "description": "Keterangan",
"destination_tag": "Tag tujuan:", "destination_tag": "Tag tujuan:",
"deuro_collect_interest": "Mengumpulkan",
"deuro_savings": "Tabungan dEuro",
"deuro_savings_add": "Deposito",
"deuro_savings_balance": "Keseimbangan tabungan",
"deuro_savings_collect_interest": "Mengumpulkan minat",
"deuro_savings_remove": "Menarik",
"deuro_savings_set_approval": "Tetapkan persetujuan",
"deuro_savings_subtitle": "Hasilkan hingga 10% bunga di Deuro Stablecoin Holdings Anda",
"deuro_tx_commited_content": "Mungkin butuh beberapa detik untuk transaksi untuk mengkonfirmasi dan direfleksikan di layar",
"device_is_signing": "Perangkat sedang menandatangani", "device_is_signing": "Perangkat sedang menandatangani",
"dfx_option_description": "Beli crypto dengan EUR & CHF. Untuk pelanggan ritel dan perusahaan di Eropa", "dfx_option_description": "Beli crypto dengan EUR & CHF. Untuk pelanggan ritel dan perusahaan di Eropa",
"didnt_get_code": "Tidak mendapatkan kode?", "didnt_get_code": "Tidak mendapatkan kode?",

View file

@ -56,6 +56,7 @@
"apk_update": "Aggiornamento APK", "apk_update": "Aggiornamento APK",
"approve": "Approvare", "approve": "Approvare",
"approve_request": "Approvare la richiesta", "approve_request": "Approvare la richiesta",
"approve_tokens": "Approvare i token",
"arrive_in_this_address": "${currency} ${tag}arriverà a questo indirizzo", "arrive_in_this_address": "${currency} ${tag}arriverà a questo indirizzo",
"ascending": "Ascendente", "ascending": "Ascendente",
"ask_each_time": "Chiedi ogni volta", "ask_each_time": "Chiedi ogni volta",
@ -244,6 +245,15 @@
"descending": "Discendente", "descending": "Discendente",
"description": "Descrizione", "description": "Descrizione",
"destination_tag": "Tag destinazione:", "destination_tag": "Tag destinazione:",
"deuro_collect_interest": "Raccogliere",
"deuro_savings": "Risparmio di dEuro",
"deuro_savings_add": "Depositare",
"deuro_savings_balance": "Saldo di risparmio",
"deuro_savings_collect_interest": "Raccogliere interesse",
"deuro_savings_remove": "Ritirare",
"deuro_savings_set_approval": "Impostare l'approvazione",
"deuro_savings_subtitle": "Guadagna fino al 10% di interesse su Deuro StableCoin Holdings",
"deuro_tx_commited_content": "Potrebbero essere necessari un paio di secondi per confermare la transazione ed essere riflessa sullo schermo",
"device_is_signing": "Il dispositivo sta firmando", "device_is_signing": "Il dispositivo sta firmando",
"dfx_option_description": "Acquista Crypto con EUR & CHF. Per i clienti al dettaglio e aziendali in Europa", "dfx_option_description": "Acquista Crypto con EUR & CHF. Per i clienti al dettaglio e aziendali in Europa",
"didnt_get_code": "Non hai ricevuto il codice?", "didnt_get_code": "Non hai ricevuto il codice?",

View file

@ -56,6 +56,7 @@
"apk_update": "APKアップデート", "apk_update": "APKアップデート",
"approve": "承認する", "approve": "承認する",
"approve_request": "リクエストを承認します", "approve_request": "リクエストを承認します",
"approve_tokens": "トークンを承認します",
"arrive_in_this_address": "${currency} ${tag}はこの住所に到着します", "arrive_in_this_address": "${currency} ${tag}はこの住所に到着します",
"ascending": "上昇", "ascending": "上昇",
"ask_each_time": "毎回尋ねてください", "ask_each_time": "毎回尋ねてください",
@ -244,6 +245,15 @@
"descending": "下降", "descending": "下降",
"description": "説明", "description": "説明",
"destination_tag": "宛先タグ:", "destination_tag": "宛先タグ:",
"deuro_collect_interest": "集める",
"deuro_savings": "dEuro Savings",
"deuro_savings_add": "デポジット",
"deuro_savings_balance": "貯蓄バランス",
"deuro_savings_collect_interest": "興味を集めます",
"deuro_savings_remove": "撤回する",
"deuro_savings_set_approval": "承認を設定します",
"deuro_savings_subtitle": "Deuro Stablecoin Holdingsで最大10の利息を稼ぐ",
"deuro_tx_commited_content": "トランザクションが確認され、画面に反映されるまでに数秒かかる場合があります",
"device_is_signing": "デバイスが署名しています", "device_is_signing": "デバイスが署名しています",
"dfx_option_description": "EURCHFで暗号を購入します。ヨーロッパの小売および企業の顧客向け", "dfx_option_description": "EURCHFで暗号を購入します。ヨーロッパの小売および企業の顧客向け",
"didnt_get_code": "コードを取得しませんか?", "didnt_get_code": "コードを取得しませんか?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK 업데이트", "apk_update": "APK 업데이트",
"approve": "승인", "approve": "승인",
"approve_request": "요청 승인", "approve_request": "요청 승인",
"approve_tokens": "토큰을 승인합니다",
"arrive_in_this_address": "${currency} ${tag}이(가) 이 주소로 도착합니다", "arrive_in_this_address": "${currency} ${tag}이(가) 이 주소로 도착합니다",
"ascending": "오름차순", "ascending": "오름차순",
"ask_each_time": "매번 묻기", "ask_each_time": "매번 묻기",
@ -244,6 +245,15 @@
"descending": "내림차순", "descending": "내림차순",
"description": "설명", "description": "설명",
"destination_tag": "목적지 태그:", "destination_tag": "목적지 태그:",
"deuro_collect_interest": "모으다",
"deuro_savings": "도로 저축",
"deuro_savings_add": "보증금",
"deuro_savings_balance": "저축 잔고",
"deuro_savings_collect_interest": "관심을 모으십시오",
"deuro_savings_remove": "철회하다",
"deuro_savings_set_approval": "승인을 설정하십시오",
"deuro_savings_subtitle": "Deuro Stablecoin Holdings에 최대 10%의이자를 받으십시오.",
"deuro_tx_commited_content": "트랜잭션이 확인하고 화면에 반영되는 데 몇 초가 걸릴 수 있습니다.",
"device_is_signing": "장치가 서명 중입니다", "device_is_signing": "장치가 서명 중입니다",
"dfx_option_description": "EUR 및 CHF로 암호화폐 구매. 유럽의 개인 및 기업 고객 대상", "dfx_option_description": "EUR 및 CHF로 암호화폐 구매. 유럽의 개인 및 기업 고객 대상",
"didnt_get_code": "코드를 받지 못했나요?", "didnt_get_code": "코드를 받지 못했나요?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK အပ်ဒိတ်", "apk_update": "APK အပ်ဒိတ်",
"approve": "လက်မခံပါ။", "approve": "လက်မခံပါ။",
"approve_request": "တောင်းဆိုမှုကိုအတည်ပြု", "approve_request": "တောင်းဆိုမှုကိုအတည်ပြု",
"approve_tokens": "တိုကင်အတည်ပြု",
"arrive_in_this_address": "${currency} ${tag}ဤလိပ်စာသို့ ရောက်ရှိပါမည်။", "arrive_in_this_address": "${currency} ${tag}ဤလိပ်စာသို့ ရောက်ရှိပါမည်။",
"ascending": "တက်", "ascending": "တက်",
"ask_each_time": "တစ်ခုချင်းစီကိုအချိန်မေးပါ", "ask_each_time": "တစ်ခုချင်းစီကိုအချိန်မေးပါ",
@ -244,6 +245,15 @@
"descending": "ဆင်း", "descending": "ဆင်း",
"description": "ဖော်ပြချက်", "description": "ဖော်ပြချက်",
"destination_tag": "ခရီးဆုံးအမှတ်-", "destination_tag": "ခရီးဆုံးအမှတ်-",
"deuro_collect_interest": "စုဝေး",
"deuro_savings": "dEuro ငွေစု",
"deuro_savings_add": "အပ်ငေှ",
"deuro_savings_balance": "ငွေစုချိန်ခွင်လျှာ",
"deuro_savings_collect_interest": "အကျိုးစီးပွားစုဆောင်းပါ",
"deuro_savings_remove": "ဆုတ်ခွာ",
"deuro_savings_set_approval": "အတည်ပြုချက်ကိုသတ်မှတ်ပါ",
"deuro_savings_subtitle": "သင်၏ Deuro Stabloin Holdings တွင် 10% အထိစိတ်ဝင်စားပါ",
"deuro_tx_commited_content": "၎င်းသည်ငွေပေးငွေယူကိုအတည်ပြုရန်နှင့်မျက်နှာပြင်ပေါ်တွင်ထင်ဟပ်ရန်စက္ကန့်အနည်းငယ်ကြာနိုင်သည်",
"device_is_signing": "ကိရိယာလက်မှတ်ထိုးနေသည်", "device_is_signing": "ကိရိယာလက်မှတ်ထိုးနေသည်",
"dfx_option_description": "Crypto ကို EUR & CHF ဖြင့် 0 ယ်ပါ။ လက်လီရောင်းဝယ်မှုနှင့်ဥရောပရှိကော်ပိုရိတ်ဖောက်သည်များအတွက်", "dfx_option_description": "Crypto ကို EUR & CHF ဖြင့် 0 ယ်ပါ။ လက်လီရောင်းဝယ်မှုနှင့်ဥရောပရှိကော်ပိုရိတ်ဖောက်သည်များအတွက်",
"didnt_get_code": "ကုဒ်ကို မရဘူးလား?", "didnt_get_code": "ကုဒ်ကို မရဘူးလား?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK-update", "apk_update": "APK-update",
"approve": "Goedkeuren", "approve": "Goedkeuren",
"approve_request": "Het verzoek goedkeuren", "approve_request": "Het verzoek goedkeuren",
"approve_tokens": "Tokens goedkeuren",
"arrive_in_this_address": "${currency} ${tag}komt aan op dit adres", "arrive_in_this_address": "${currency} ${tag}komt aan op dit adres",
"ascending": "Stijgend", "ascending": "Stijgend",
"ask_each_time": "Vraag het elke keer", "ask_each_time": "Vraag het elke keer",
@ -244,6 +245,15 @@
"descending": "Aflopend", "descending": "Aflopend",
"description": "Beschrijving", "description": "Beschrijving",
"destination_tag": "Bestemmingstag:", "destination_tag": "Bestemmingstag:",
"deuro_collect_interest": "Verzamelen",
"deuro_savings": "dEuro -besparingen",
"deuro_savings_add": "Borg",
"deuro_savings_balance": "Spaarbalans",
"deuro_savings_collect_interest": "Verzamel interesse",
"deuro_savings_remove": "Terugtrekken",
"deuro_savings_set_approval": "Goedkeuring instellen",
"deuro_savings_subtitle": "Verdien tot 10% rente op uw Deuro Stablecoin Holdings",
"deuro_tx_commited_content": "Het kan een paar seconden duren voordat de transactie wordt bevestigd en weerspiegeld op het scherm",
"device_is_signing": "Apparaat ondertekent", "device_is_signing": "Apparaat ondertekent",
"dfx_option_description": "Koop crypto met EUR & CHF. Voor retail- en zakelijke klanten in Europa", "dfx_option_description": "Koop crypto met EUR & CHF. Voor retail- en zakelijke klanten in Europa",
"didnt_get_code": "Geen code?", "didnt_get_code": "Geen code?",

View file

@ -56,6 +56,7 @@
"apk_update": "Aktualizacja APK", "apk_update": "Aktualizacja APK",
"approve": "Zatwierdzić", "approve": "Zatwierdzić",
"approve_request": "Zatwierdzić żądanie", "approve_request": "Zatwierdzić żądanie",
"approve_tokens": "Zatwierdzić tokeny",
"arrive_in_this_address": "${currency} ${tag}dotrze na ten adres", "arrive_in_this_address": "${currency} ${tag}dotrze na ten adres",
"ascending": "Wznoszący się", "ascending": "Wznoszący się",
"ask_each_time": "Zapytaj za każdym razem", "ask_each_time": "Zapytaj za każdym razem",
@ -244,6 +245,15 @@
"descending": "Malejąco", "descending": "Malejąco",
"description": "Opis", "description": "Opis",
"destination_tag": "Tag docelowy:", "destination_tag": "Tag docelowy:",
"deuro_collect_interest": "Zbierać",
"deuro_savings": "dEuro oszczędności",
"deuro_savings_add": "Depozyt",
"deuro_savings_balance": "Równowaga oszczędności",
"deuro_savings_collect_interest": "Zbieraj zainteresowanie",
"deuro_savings_remove": "Wycofać",
"deuro_savings_set_approval": "Ustaw zatwierdzenie",
"deuro_savings_subtitle": "Zarabiaj do 10% odsetek od Deuro Stablecoin Holdings",
"deuro_tx_commited_content": "Potwierdzenie i odbicie na ekranie może potrwać kilka sekund",
"device_is_signing": "Urządzenie podpisuje", "device_is_signing": "Urządzenie podpisuje",
"dfx_option_description": "Kup krypto za EUR & CHF. Dla klientów prywatnych i korporacyjnych w Europie", "dfx_option_description": "Kup krypto za EUR & CHF. Dla klientów prywatnych i korporacyjnych w Europie",
"didnt_get_code": "Nie dostałeś kodu?", "didnt_get_code": "Nie dostałeś kodu?",

View file

@ -56,6 +56,7 @@
"apk_update": "Atualização de APK", "apk_update": "Atualização de APK",
"approve": "Aprovar", "approve": "Aprovar",
"approve_request": "Aprovar solicitação", "approve_request": "Aprovar solicitação",
"approve_tokens": "Aprovar tokens",
"arrive_in_this_address": "${currency} ${tag}chegará neste endereço", "arrive_in_this_address": "${currency} ${tag}chegará neste endereço",
"ascending": "Ascendente", "ascending": "Ascendente",
"ask_each_time": "Pergunte cada vez", "ask_each_time": "Pergunte cada vez",
@ -244,6 +245,15 @@
"descending": "descendente", "descending": "descendente",
"description": "Descrição", "description": "Descrição",
"destination_tag": "Tag de destino:", "destination_tag": "Tag de destino:",
"deuro_collect_interest": "Coletar",
"deuro_savings": "dEuro Savings",
"deuro_savings_add": "Depósito",
"deuro_savings_balance": "Balanço de poupança",
"deuro_savings_collect_interest": "Coletar juros",
"deuro_savings_remove": "Retirar",
"deuro_savings_set_approval": "Defina aprovação",
"deuro_savings_subtitle": "Ganhe até 10% de juros em sua Deuro Stablecoin Holdings",
"deuro_tx_commited_content": "Pode levar alguns segundos para a transação confirmar e se refletir na tela",
"device_is_signing": "O dispositivo está assinando", "device_is_signing": "O dispositivo está assinando",
"dfx_option_description": "Compre criptografia com EUR & CHF. Para clientes de varejo e corporativo na Europa", "dfx_option_description": "Compre criptografia com EUR & CHF. Para clientes de varejo e corporativo na Europa",
"didnt_get_code": "Não recebeu o código?", "didnt_get_code": "Não recebeu o código?",

View file

@ -56,6 +56,7 @@
"apk_update": "Обновление APK", "apk_update": "Обновление APK",
"approve": "Утвердить", "approve": "Утвердить",
"approve_request": "Утвердить запрос", "approve_request": "Утвердить запрос",
"approve_tokens": "Одобрить токены",
"arrive_in_this_address": "${currency} ${tag}придет на этот адрес", "arrive_in_this_address": "${currency} ${tag}придет на этот адрес",
"ascending": "Восходящий", "ascending": "Восходящий",
"ask_each_time": "Спросите каждый раз", "ask_each_time": "Спросите каждый раз",
@ -244,6 +245,15 @@
"descending": "Нисходящий", "descending": "Нисходящий",
"description": "Описание", "description": "Описание",
"destination_tag": "Целевой тег:", "destination_tag": "Целевой тег:",
"deuro_collect_interest": "Собирать",
"deuro_savings": "dEuro Savings",
"deuro_savings_add": "Депозитный",
"deuro_savings_balance": "Сберегательный баланс",
"deuro_savings_collect_interest": "Собирать интерес",
"deuro_savings_remove": "Отзывать",
"deuro_savings_set_approval": "Установить утверждение",
"deuro_savings_subtitle": "Заработайте до 10% процентов на ваших Deuro Stablecoin Holdings",
"deuro_tx_commited_content": "Чтобы подтвердить, может потребоваться пару секунд, чтобы подтвердить и быть отраженным на экране",
"device_is_signing": "Устройство подписывает", "device_is_signing": "Устройство подписывает",
"dfx_option_description": "Купить крипто с Eur & CHF. Для розничных и корпоративных клиентов в Европе", "dfx_option_description": "Купить крипто с Eur & CHF. Для розничных и корпоративных клиентов в Европе",
"didnt_get_code": "Не получить код?", "didnt_get_code": "Не получить код?",

View file

@ -56,6 +56,7 @@
"apk_update": "ปรับปรุง APK", "apk_update": "ปรับปรุง APK",
"approve": "อนุมัติ", "approve": "อนุมัติ",
"approve_request": "อนุมัติคำขอ", "approve_request": "อนุมัติคำขอ",
"approve_tokens": "อนุมัติโทเค็น",
"arrive_in_this_address": "${currency} ${tag}จะมาถึงที่อยู่นี้", "arrive_in_this_address": "${currency} ${tag}จะมาถึงที่อยู่นี้",
"ascending": "จากน้อยไปมาก", "ascending": "จากน้อยไปมาก",
"ask_each_time": "ถามทุกครั้ง", "ask_each_time": "ถามทุกครั้ง",
@ -244,6 +245,15 @@
"descending": "ลงมา", "descending": "ลงมา",
"description": "คำอธิบาย", "description": "คำอธิบาย",
"destination_tag": "แท็กปลายทาง:", "destination_tag": "แท็กปลายทาง:",
"deuro_collect_interest": "เก็บรวบรวม",
"deuro_savings": "การออมของ dEuro",
"deuro_savings_add": "เงินฝาก",
"deuro_savings_balance": "ยอดเงินออม",
"deuro_savings_collect_interest": "เก็บดอกเบี้ย",
"deuro_savings_remove": "ถอน",
"deuro_savings_set_approval": "ตั้งค่าการอนุมัติ",
"deuro_savings_subtitle": "รับดอกเบี้ยมากถึง 10% สำหรับ Deuro Stablecoin Holdings ของคุณ",
"deuro_tx_commited_content": "อาจใช้เวลาสองสามวินาทีในการทำธุรกรรมเพื่อยืนยันและสะท้อนบนหน้าจอ",
"device_is_signing": "อุปกรณ์กำลังลงนาม", "device_is_signing": "อุปกรณ์กำลังลงนาม",
"dfx_option_description": "ซื้อ crypto ด้วย Eur & CHF สำหรับลูกค้ารายย่อยและลูกค้าในยุโรป", "dfx_option_description": "ซื้อ crypto ด้วย Eur & CHF สำหรับลูกค้ารายย่อยและลูกค้าในยุโรป",
"didnt_get_code": "ไม่ได้รับรหัส?", "didnt_get_code": "ไม่ได้รับรหัส?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK update", "apk_update": "APK update",
"approve": "Aprubahan", "approve": "Aprubahan",
"approve_request": "Aprubahan ang kahilingan", "approve_request": "Aprubahan ang kahilingan",
"approve_tokens": "Aprubahan ang mga token",
"arrive_in_this_address": "Ang ${currency} ${tag} ay darating sa address na ito", "arrive_in_this_address": "Ang ${currency} ${tag} ay darating sa address na ito",
"ascending": "Umakyat", "ascending": "Umakyat",
"ask_each_time": "Magtanong sa tuwing", "ask_each_time": "Magtanong sa tuwing",
@ -244,6 +245,15 @@
"descending": "Pababang", "descending": "Pababang",
"description": "Paglalarawan", "description": "Paglalarawan",
"destination_tag": "Tag ng patutunguhan:", "destination_tag": "Tag ng patutunguhan:",
"deuro_collect_interest": "Mangolekta",
"deuro_savings": "Pagtipid ni dEuro",
"deuro_savings_add": "Deposito",
"deuro_savings_balance": "Balanse sa pagtitipid",
"deuro_savings_collect_interest": "Mangolekta ng interes",
"deuro_savings_remove": "Umatras",
"deuro_savings_set_approval": "Itakda ang pag -apruba",
"deuro_savings_subtitle": "Kumita ng hanggang sa 10% na interes sa iyong mga hawak na Deuro StableCoin",
"deuro_tx_commited_content": "Maaaring tumagal ng ilang segundo para sa transaksyon upang kumpirmahin at maipakita sa screen",
"device_is_signing": "Nag -sign ang aparato", "device_is_signing": "Nag -sign ang aparato",
"dfx_option_description": "Bumili ng crypto kasama ang EUR & CHF. Para sa mga retail customer at corporate customer sa Europe", "dfx_option_description": "Bumili ng crypto kasama ang EUR & CHF. Para sa mga retail customer at corporate customer sa Europe",
"didnt_get_code": "Hindi nakuha ang code?", "didnt_get_code": "Hindi nakuha ang code?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK güncellemesi", "apk_update": "APK güncellemesi",
"approve": "Onaylamak", "approve": "Onaylamak",
"approve_request": "Talebi Onaylama", "approve_request": "Talebi Onaylama",
"approve_tokens": "Jetonları onaylayın",
"arrive_in_this_address": "${currency} ${tag}bu adrese ulaşacak", "arrive_in_this_address": "${currency} ${tag}bu adrese ulaşacak",
"ascending": "Yükselen", "ascending": "Yükselen",
"ask_each_time": "Her seferinde sor", "ask_each_time": "Her seferinde sor",
@ -244,6 +245,15 @@
"descending": "Azalan", "descending": "Azalan",
"description": "Tanım", "description": "Tanım",
"destination_tag": "Hedef Etiketi:", "destination_tag": "Hedef Etiketi:",
"deuro_collect_interest": "TOPLAMAK",
"deuro_savings": "dEuro Tasarruf",
"deuro_savings_add": "Yatırmak",
"deuro_savings_balance": "Tasarruf Bakiyesi",
"deuro_savings_collect_interest": "İlgi toplamak",
"deuro_savings_remove": "Geri çekilmek",
"deuro_savings_set_approval": "Onay ayarlamak",
"deuro_savings_subtitle": "Deuro StableCoin Holdings'e% 10'a kadar faiz kazanın",
"deuro_tx_commited_content": "İşlemin onaylaması ve ekrana yansıtılması birkaç saniye sürebilir",
"device_is_signing": "Cihaz imzalıyor", "device_is_signing": "Cihaz imzalıyor",
"dfx_option_description": "Eur & chf ile kripto satın alın. Avrupa'daki perakende ve kurumsal müşteriler için", "dfx_option_description": "Eur & chf ile kripto satın alın. Avrupa'daki perakende ve kurumsal müşteriler için",
"didnt_get_code": "Kod gelmedi mi?", "didnt_get_code": "Kod gelmedi mi?",

View file

@ -56,6 +56,7 @@
"apk_update": "Оновлення APK", "apk_update": "Оновлення APK",
"approve": "Затвердити", "approve": "Затвердити",
"approve_request": "Запитайте запит", "approve_request": "Запитайте запит",
"approve_tokens": "Затвердити токени",
"arrive_in_this_address": "${currency} ${tag}надійде на цю адресу", "arrive_in_this_address": "${currency} ${tag}надійде на цю адресу",
"ascending": "Висхід", "ascending": "Висхід",
"ask_each_time": "Запитайте кожен раз", "ask_each_time": "Запитайте кожен раз",
@ -244,6 +245,15 @@
"descending": "Низхідний", "descending": "Низхідний",
"description": "опис", "description": "опис",
"destination_tag": "Тег призначення:", "destination_tag": "Тег призначення:",
"deuro_collect_interest": "Збирати",
"deuro_savings": "заощадження dEuro",
"deuro_savings_add": "Депозит",
"deuro_savings_balance": "Баланс заощаджень",
"deuro_savings_collect_interest": "Збирати інтерес",
"deuro_savings_remove": "Відступати",
"deuro_savings_set_approval": "Встановити схвалення",
"deuro_savings_subtitle": "Заробляйте до 10% відсотків на ваших Holdings Deuro StableCoin",
"deuro_tx_commited_content": "Це може знадобитися кілька секунд, щоб транзакція підтвердила та відображалася на екрані",
"device_is_signing": "Пристрій підписується", "device_is_signing": "Пристрій підписується",
"dfx_option_description": "Купуйте криптовалюту з EUR & CHF. Для роздрібних та корпоративних клієнтів у Європі", "dfx_option_description": "Купуйте криптовалюту з EUR & CHF. Для роздрібних та корпоративних клієнтів у Європі",
"didnt_get_code": "Не отримали код?", "didnt_get_code": "Не отримали код?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK اپ ڈیٹ", "apk_update": "APK اپ ڈیٹ",
"approve": "ﻭﺮﮐ ﺭﻮﻈﻨﻣ", "approve": "ﻭﺮﮐ ﺭﻮﻈﻨﻣ",
"approve_request": "درخواست کو منظور کریں", "approve_request": "درخواست کو منظور کریں",
"approve_tokens": "ٹوکن کو منظور کریں",
"arrive_in_this_address": "${currency} ${tag}اس پتے پر پہنچے گا۔", "arrive_in_this_address": "${currency} ${tag}اس پتے پر پہنچے گا۔",
"ascending": "چڑھنے", "ascending": "چڑھنے",
"ask_each_time": "ہر بار پوچھیں", "ask_each_time": "ہر بار پوچھیں",
@ -244,6 +245,15 @@
"descending": "اترتے ہوئے", "descending": "اترتے ہوئے",
"description": "ﻞﯿﺼﻔﺗ", "description": "ﻞﯿﺼﻔﺗ",
"destination_tag": "منزل کا ٹیگ:", "destination_tag": "منزل کا ٹیگ:",
"deuro_collect_interest": "جمع کریں",
"deuro_savings": "ڈیورو کی بچت",
"deuro_savings_add": "جمع کروائیں",
"deuro_savings_balance": "بچت کا توازن",
"deuro_savings_collect_interest": "دلچسپی جمع کریں",
"deuro_savings_remove": "واپس لے لو",
"deuro_savings_set_approval": "منظوری طے کریں",
"deuro_savings_subtitle": "اپنے ڈیورو اسٹبل کوئن ہولڈنگز پر 10 ٪ سود حاصل کریں",
"deuro_tx_commited_content": "لین دین کی تصدیق اور اسکرین پر عکاسی کرنے میں اس میں کچھ سیکنڈ لگ سکتے ہیں",
"device_is_signing": "ڈیوائس پر دستخط کر رہے ہیں", "device_is_signing": "ڈیوائس پر دستخط کر رہے ہیں",
"dfx_option_description": "یورو اور سی ایچ ایف کے ساتھ کرپٹو خریدیں۔ یورپ میں خوردہ اور کارپوریٹ صارفین کے لئے", "dfx_option_description": "یورو اور سی ایچ ایف کے ساتھ کرپٹو خریدیں۔ یورپ میں خوردہ اور کارپوریٹ صارفین کے لئے",
"didnt_get_code": "کوڈ نہیں ملتا؟", "didnt_get_code": "کوڈ نہیں ملتا؟",

View file

@ -56,6 +56,7 @@
"apk_update": "Cập nhật APK", "apk_update": "Cập nhật APK",
"approve": "Phê duyệt", "approve": "Phê duyệt",
"approve_request": "Phê duyệt yêu cầu", "approve_request": "Phê duyệt yêu cầu",
"approve_tokens": "Phê duyệt mã thông báo",
"arrive_in_this_address": "${currency} ${tag} sẽ đến địa chỉ này", "arrive_in_this_address": "${currency} ${tag} sẽ đến địa chỉ này",
"ascending": "Tăng dần", "ascending": "Tăng dần",
"ask_each_time": "Hỏi mỗi lần", "ask_each_time": "Hỏi mỗi lần",
@ -243,6 +244,15 @@
"descending": "Giảm dần", "descending": "Giảm dần",
"description": "Mô tả", "description": "Mô tả",
"destination_tag": "Thẻ đích:", "destination_tag": "Thẻ đích:",
"deuro_collect_interest": "Sưu tầm",
"deuro_savings": "Tiết kiệm dEuro",
"deuro_savings_add": "Tiền gửi",
"deuro_savings_balance": "Số dư tiết kiệm",
"deuro_savings_collect_interest": "Thu tiền lãi",
"deuro_savings_remove": "Rút",
"deuro_savings_set_approval": "Đặt phê duyệt",
"deuro_savings_subtitle": "Kiếm tới 10% tiền lãi cho Deuro Storcoin Holdings của bạn",
"deuro_tx_commited_content": "Có thể mất vài giây để giao dịch xác nhận và được phản ánh trên màn hình",
"device_is_signing": "Thiết bị đang ký", "device_is_signing": "Thiết bị đang ký",
"dfx_option_description": "Mua tiền điện tử bằng EUR & CHF. Dành cho khách hàng bán lẻ và doanh nghiệp tại Châu Âu", "dfx_option_description": "Mua tiền điện tử bằng EUR & CHF. Dành cho khách hàng bán lẻ và doanh nghiệp tại Châu Âu",
"didnt_get_code": "Không nhận được mã?", "didnt_get_code": "Không nhận được mã?",

View file

@ -56,6 +56,7 @@
"apk_update": "Àtúnse áàpù títun wà", "apk_update": "Àtúnse áàpù títun wà",
"approve": "Fi ọwọ si", "approve": "Fi ọwọ si",
"approve_request": "IKILỌ RẸ", "approve_request": "IKILỌ RẸ",
"approve_tokens": "Ṣe fọwọsi awọn àmi",
"arrive_in_this_address": "${currency} ${tag} máa dé sí àdírẹ́sì yìí", "arrive_in_this_address": "${currency} ${tag} máa dé sí àdírẹ́sì yìí",
"ascending": "Goke", "ascending": "Goke",
"ask_each_time": "Beere lọwọ kọọkan", "ask_each_time": "Beere lọwọ kọọkan",
@ -244,6 +245,15 @@
"descending": "Sọkalẹ", "descending": "Sọkalẹ",
"description": "Apejuwe", "description": "Apejuwe",
"destination_tag": "Orúkọ tí ìbí tó a ránṣẹ́ sí:", "destination_tag": "Orúkọ tí ìbí tó a ránṣẹ́ sí:",
"deuro_collect_interest": "Kojọ",
"deuro_savings": "dEuro Awọn ifowopamọ",
"deuro_savings_add": "Owo ifipamọ",
"deuro_savings_balance": "Iwontunws.funfun ifowopamọ",
"deuro_savings_collect_interest": "Gba iwulo",
"deuro_savings_remove": "Yọkuro",
"deuro_savings_set_approval": "Ṣeto ifọwọsi",
"deuro_savings_subtitle": "Jo'gun to 10% iwulo lori awọn idaduro Duroblockoin rẹ",
"deuro_tx_commited_content": "O le gba tọkọtaya kan ti awọn aaya fun idunadura lati jẹrisi ati ṣe afihan loju iboju",
"device_is_signing": "Ẹrọ n forukọsilẹ", "device_is_signing": "Ẹrọ n forukọsilẹ",
"dfx_option_description": "Ra Crypto pẹlu EUR & CHF. Fun soobu ati awọn alabara ile-iṣẹ ni Yuroopu", "dfx_option_description": "Ra Crypto pẹlu EUR & CHF. Fun soobu ati awọn alabara ile-iṣẹ ni Yuroopu",
"didnt_get_code": "Ko gba koodu?", "didnt_get_code": "Ko gba koodu?",

View file

@ -56,6 +56,7 @@
"apk_update": "APK更新", "apk_update": "APK更新",
"approve": "批准", "approve": "批准",
"approve_request": "批准请求", "approve_request": "批准请求",
"approve_tokens": "批准令牌",
"arrive_in_this_address": "${currency} ${tag}将到达此地址", "arrive_in_this_address": "${currency} ${tag}将到达此地址",
"ascending": "上升", "ascending": "上升",
"ask_each_time": "每次问", "ask_each_time": "每次问",
@ -244,6 +245,15 @@
"descending": "下降", "descending": "下降",
"description": "描述", "description": "描述",
"destination_tag": "目标Tag:", "destination_tag": "目标Tag:",
"deuro_collect_interest": "收集",
"deuro_savings": "dEuro储蓄",
"deuro_savings_add": "订金",
"deuro_savings_balance": "储蓄平衡",
"deuro_savings_collect_interest": "收集兴趣",
"deuro_savings_remove": "提取",
"deuro_savings_set_approval": "设定批准",
"deuro_savings_subtitle": "您的Deuro Stablecoin Holdings最多可赚取10的利息",
"deuro_tx_commited_content": "交易可能需要几秒钟才能确认并在屏幕上反射",
"device_is_signing": "设备正在签名", "device_is_signing": "设备正在签名",
"dfx_option_description": "用EurChf购买加密货币。对于欧洲的零售和企业客户", "dfx_option_description": "用EurChf购买加密货币。对于欧洲的零售和企业客户",
"didnt_get_code": "没有获取代码?", "didnt_get_code": "没有获取代码?",

View file

@ -670,6 +670,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart'; import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/hardware/hardware_account_data.dart'; import 'package:cw_core/hardware/hardware_account_data.dart';
import 'package:cw_core/output_info.dart'; import 'package:cw_core/output_info.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
@ -697,6 +698,7 @@ import 'package:cw_ethereum/ethereum_client.dart';
import 'package:cw_ethereum/ethereum_wallet.dart'; import 'package:cw_ethereum/ethereum_wallet.dart';
import 'package:cw_ethereum/ethereum_wallet_service.dart'; import 'package:cw_ethereum/ethereum_wallet_service.dart';
import 'package:cw_ethereum/default_ethereum_erc20_tokens.dart'; import 'package:cw_ethereum/default_ethereum_erc20_tokens.dart';
import 'package:cw_ethereum/deuro/deuro_savings.dart';
import 'package:eth_sig_util/util/utils.dart'; import 'package:eth_sig_util/util/utils.dart';
@ -744,6 +746,16 @@ abstract class Ethereum {
void updateEtherscanUsageState(WalletBase wallet, bool isEnabled); void updateEtherscanUsageState(WalletBase wallet, bool isEnabled);
Web3Client? getWeb3Client(WalletBase wallet); Web3Client? getWeb3Client(WalletBase wallet);
String getTokenAddress(CryptoCurrency asset); String getTokenAddress(CryptoCurrency asset);
Future<PendingTransaction> createTokenApproval(WalletBase wallet, BigInt amount, String spender, CryptoCurrency token, TransactionPriority priority);
Future<BigInt> getDEuroSavingsBalance(WalletBase wallet);
Future<BigInt> getDEuroAccruedInterest(WalletBase wallet);
Future<BigInt> getDEuroInterestRate(WalletBase wallet);
Future<BigInt> getDEuroSavingsApproved(WalletBase wallet);
Future<PendingTransaction> addDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority);
Future<PendingTransaction> removeDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority);
Future<PendingTransaction> enableDEuroSaving(WalletBase wallet, TransactionPriority priority);
void setLedgerConnection(WalletBase wallet, ledger.LedgerConnection connection); void setLedgerConnection(WalletBase wallet, ledger.LedgerConnection connection);
Future<List<HardwareAccountData>> getHardwareWalletAccounts(LedgerViewModel ledgerVM, {int index = 0, int limit = 5}); Future<List<HardwareAccountData>> getHardwareWalletAccounts(LedgerViewModel ledgerVM, {int index = 0, int limit = 5});
@ -778,6 +790,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart'; import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/hardware/hardware_account_data.dart'; import 'package:cw_core/hardware/hardware_account_data.dart';
import 'package:cw_core/output_info.dart'; import 'package:cw_core/output_info.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
@ -847,6 +860,8 @@ abstract class Polygon {
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token); Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token);
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token); Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token);
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress); Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress);
Future<PendingTransaction> createTokenApproval(WalletBase wallet, BigInt amount, String spender, CryptoCurrency token, TransactionPriority priority);
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction); CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction);
void updatePolygonScanUsageState(WalletBase wallet, bool isEnabled); void updatePolygonScanUsageState(WalletBase wallet, bool isEnabled);