Merge branch 'main' into xelis

This commit is contained in:
Anthony Tritonn 2025-06-19 20:41:39 -07:00 committed by GitHub
commit 75e2c67752
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 2276 additions and 149 deletions

View file

@ -266,6 +266,12 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
derivationPath: walletInfo.derivationInfo!.derivationPath!);
}
@override
Future<void> close({bool shouldCleanup = false}) async {
payjoinManager.cleanupSessions();
super.close(shouldCleanup: shouldCleanup);
}
late final PayjoinManager payjoinManager;
bool get isPayjoinAvailable => unspentCoinsInfo.values

View file

@ -59,19 +59,26 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
@action
Future<void> initPayjoin() async {
try {
await payjoinManager.initPayjoin();
currentPayjoinReceiver = await payjoinManager.initReceiver(primaryAddress);
currentPayjoinReceiver = await payjoinManager.getUnusedReceiver(primaryAddress);
payjoinEndpoint = (await currentPayjoinReceiver?.pjUri())?.pjEndpoint();
payjoinManager.resumeSessions();
} catch (e) {
printV(e);
}
}
@action
Future<void> newPayjoinReceiver() async {
currentPayjoinReceiver = await payjoinManager.initReceiver(primaryAddress);
try {
currentPayjoinReceiver = await payjoinManager.getUnusedReceiver(primaryAddress);
payjoinEndpoint = (await currentPayjoinReceiver?.pjUri())?.pjEndpoint();
printV("Initializing new Payjoin Receiver");
payjoinManager.spawnNewReceiver(receiver: currentPayjoinReceiver!);
payjoinManager.spawnReceiver(receiver: currentPayjoinReceiver!);
} catch (e) {
printV(e);
}
}
}

View file

@ -53,7 +53,7 @@ class PayjoinManager {
}
final receiver = Receiver.fromJson(json: session.receiver!);
printV("Resuming Payjoin Receiver Session ${receiver.id()}");
return _spawnReceiver(receiver: receiver);
return spawnReceiver(receiver: receiver);
});
printV("Resumed ${spawnedSessions.length} Payjoin Sessions");
@ -121,15 +121,13 @@ class PayjoinManager {
}
} catch (e) {
_cleanupSession(pjUri);
printV(e);
await _payjoinStorage.markSenderSessionUnrecoverable(pjUri);
completer.completeError(e);
await _payjoinStorage.markSenderSessionUnrecoverable(pjUri, e.toString());
completer.complete();
}
} else if (message is PayjoinSessionError) {
_cleanupSession(pjUri);
if (message is UnrecoverableError) {
printV(message.message);
await _payjoinStorage.markSenderSessionUnrecoverable(pjUri);
await _payjoinStorage.markSenderSessionUnrecoverable(pjUri, message.message);
completer.complete();
} else if (message is RecoverableError) {
completer.complete();
@ -149,9 +147,20 @@ class PayjoinManager {
return completer.future;
}
Future<Receiver> initReceiver(String address,
Future<Receiver> getUnusedReceiver(String address,
[bool isTestnet = false]) async {
try {
final session = _payjoinStorage.getUnusedActiveReceiverSession(_wallet.id);
if (session != null) {
await PayjoinUri.Url.fromStr(payjoinDirectoryUrl);
return Receiver.fromJson(json: session.receiver!);
}
return initReceiver(address);
}
Future<Receiver> initReceiver(String address, [bool isTestnet = false]) async {
final ohttpKeys = await PayjoinUri.fetchOhttpKeys(
ohttpRelay: await randomOhttpRelayUrl(),
payjoinDirectory: payjoinDirectoryUrl,
@ -165,26 +174,14 @@ class PayjoinManager {
);
final persister = PayjoinReceiverPersister.impl();
final receiverToken = await newReceiver.persist(persister: persister);
final receiver =
await Receiver.load(persister: persister, token: receiverToken);
final receiver = await Receiver.load(persister: persister, token: receiverToken);
await _payjoinStorage.insertReceiverSession(receiver, _wallet.id);
return receiver;
} catch (e) {
throw Exception('Error initializing Payjoin Receiver: $e');
}
}
Future<void> spawnNewReceiver({
required Receiver receiver,
bool isTestnet = false,
}) async {
await _payjoinStorage.insertReceiverSession(receiver, _wallet.id);
return _spawnReceiver(isTestnet: isTestnet, receiver: receiver);
}
Future<void> _spawnReceiver({
Future<void> spawnReceiver({
required Receiver receiver,
bool isTestnet = false,
}) async {
@ -229,6 +226,10 @@ class PayjoinManager {
case PayjoinReceiverRequestTypes.getCandidateInputs:
utxos = _wallet.getUtxoWithPrivateKeys();
if (utxos.isEmpty) {
await _wallet.updateAllUnspents();
utxos = _wallet.getUtxoWithPrivateKeys();
}
mainToIsolateSendPort?.send({
'requestId': message['requestId'],
'result': utxos,

View file

@ -174,7 +174,7 @@ class PayjoinReceiverWorker {
final listUnspent =
await _sendRequest(PayjoinReceiverRequestTypes.getCandidateInputs);
final unspent = listUnspent as List<UtxoWithPrivateKey>;
if (unspent.isEmpty) throw Exception('No unspent outputs available');
if (unspent.isEmpty) throw RecoverableError('No unspent outputs available');
final selectedUtxo = await _inputPairFromUtxo(unspent[0]);
final pj6 = await pj5.contributeInputs(replacementInputs: [selectedUtxo]);

View file

@ -23,6 +23,14 @@ class PayjoinStorage {
),
);
PayjoinSession? getUnusedActiveReceiverSession(String walletId) =>
_payjoinSessionSources.values
.where((session) =>
session.walletId == walletId &&
session.status == PayjoinSessionStatus.created.name &&
!session.isSenderSession)
.firstOrNull;
Future<void> markReceiverSessionComplete(
String sessionId, String txId, String amount) async {
final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!;
@ -76,10 +84,11 @@ class PayjoinStorage {
await session.save();
}
Future<void> markSenderSessionUnrecoverable(String pjUrl) async {
Future<void> markSenderSessionUnrecoverable(String pjUrl, String reason) async {
final session = _payjoinSessionSources.get("$_senderPrefix$pjUrl")!;
session.status = PayjoinSessionStatus.unrecoverable.name;
session.error = reason;
await session.save();
}

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
environment:
sdk: '>=2.18.2 <3.0.0'
sdk: ^3.5.0
flutter: ">=1.17.0"
dependencies:

View file

@ -101,6 +101,7 @@ abstract class EVMChainClient {
String? contractAddress,
EtherAmount? gasPrice,
EtherAmount? maxFeePerGas,
Uint8List? data,
}) async {
try {
if (contractAddress == null) {
@ -124,7 +125,7 @@ abstract class EVMChainClient {
final gasEstimate = await _client!.estimateGas(
sender: senderAddress,
to: EthereumAddress.fromHex(contractAddress),
data: transfer.encodeCall([
data: data ?? transfer.encodeCall([
toAddress,
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({
required Credentials privateKey,
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({
required EthereumAddress from,
required EthereumAddress to,

View file

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:bip32/bip32.dart' as bip32;
import 'package:bip39/bip39.dart' as bip39;
@ -255,6 +256,7 @@ abstract class EVMChainWalletBase
required String? contractAddress,
required String receivingAddressHex,
required TransactionPriority priority,
Uint8List? data,
}) async {
try {
if (priority is EVMChainTransactionPriority) {
@ -276,6 +278,7 @@ abstract class EVMChainWalletBase
gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice),
toAddress: EthereumAddress.fromHex(receivingAddressHex),
maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas),
data: data,
);
final totalGasFee = estimatedGas * maxFeePerGas;
@ -478,6 +481,43 @@ abstract class EVMChainWalletBase
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 {
try {
if (_isTransactionUpdating) {

View file

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

View file

@ -30,6 +30,7 @@ dependencies:
git:
url: https://github.com/cake-tech/ledger-flutter-plus-plugins
path: packages/ledger-ethereum
ref: f4761cd5171d4c1e2e42fd3298261650539fb2db
dependency_overrides:
web3dart:

View file

@ -74,8 +74,11 @@ class WalletLoadingService {
return wallet;
} catch (error, stack) {
await ExceptionHandler.resetLastPopupDate();
final isLedgerError = await ExceptionHandler.isLedgerError(error);
if (isLedgerError) rethrow;
await ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack));
// try fetching the seeds of the corrupted wallet to show it to the user
String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):";
try {

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/secure_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/wallet_connect/services/bottom_sheet_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/secure_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/tron/tron.dart';
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
@ -1514,5 +1516,9 @@ Future<void> setup({
getIt.registerFactory(() => DevBackgroundSyncLogsPage(getIt.get<BackgroundSyncLogsViewModel>()));
getIt.registerFactory(() => DEuroViewModel(getIt<AppStore>()));
getIt.registerFactory(() => DEuroSavingsPage(getIt<DEuroViewModel>()));
_isSetupFinished = true;
}

View file

@ -67,8 +67,7 @@ class CWEthereum extends Ethereum {
@override
String getPublicKey(WalletBase wallet) {
final privateKeyInUnitInt = (wallet as EthereumWallet).evmChainPrivateKey;
final publicKey = privateKeyInUnitInt.address.hex;
return publicKey;
return privateKeyInUnitInt.address.hex;
}
@override
@ -138,29 +137,24 @@ class CWEthereum extends Ethereum {
}
@override
List<Erc20Token> getERC20Currencies(WalletBase wallet) {
final ethereumWallet = wallet as EthereumWallet;
return ethereumWallet.erc20Currencies;
}
List<Erc20Token> getERC20Currencies(WalletBase wallet) =>
(wallet as EthereumWallet).erc20Currencies;
@override
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) async {
await (wallet as EthereumWallet).addErc20Token(token as Erc20Token);
}
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) =>
(wallet as EthereumWallet).addErc20Token(token as Erc20Token);
@override
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as EthereumWallet).deleteErc20Token(token as Erc20Token);
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) =>
(wallet as EthereumWallet).deleteErc20Token(token as Erc20Token);
@override
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as EthereumWallet).removeTokenTransactionsInHistory(token as Erc20Token);
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token) =>
(wallet as EthereumWallet).removeTokenTransactionsInHistory(token as Erc20Token);
@override
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) async {
final ethereumWallet = wallet as EthereumWallet;
return await ethereumWallet.getErc20Token(contractAddress, 'eth');
}
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) =>
(wallet as EthereumWallet).getErc20Token(contractAddress, 'eth');
@override
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
@ -177,23 +171,19 @@ class CWEthereum extends Ethereum {
}
@override
void updateEtherscanUsageState(WalletBase wallet, bool isEnabled) {
void updateEtherscanUsageState(WalletBase wallet, bool isEnabled) =>
(wallet as EthereumWallet).updateScanProviderUsageState(isEnabled);
}
@override
Web3Client? getWeb3Client(WalletBase wallet) {
return (wallet as EthereumWallet).getWeb3Client();
}
Web3Client? getWeb3Client(WalletBase wallet) => (wallet as EthereumWallet).getWeb3Client();
@override
String getTokenAddress(CryptoCurrency asset) => (asset as Erc20Token).contractAddress;
@override
void setLedgerConnection(
WalletBase wallet, ledger.LedgerConnection connection) {
void setLedgerConnection(WalletBase wallet, ledger.LedgerConnection connection) {
((wallet as EVMChainWallet).evmChainPrivateKey as EvmLedgerCredentials)
.setLedgerConnection(
connection, wallet.walletInfo.derivationInfo?.derivationPath);
.setLedgerConnection(connection, wallet.walletInfo.derivationInfo?.derivationPath);
}
@override
@ -209,7 +199,44 @@ class CWEthereum extends Ethereum {
}
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultEthereumErc20Tokens().initialErc20Tokens.map((e) => e.contractAddress).toList();
}
List<String> getDefaultTokenContractAddresses() =>
DefaultEthereumErc20Tokens().initialErc20Tokens.map((e) => e.contractAddress).toList();
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
String getPublicKey(WalletBase wallet) {
final privateKeyInUnitInt = (wallet as PolygonWallet).evmChainPrivateKey;
final publicKey = privateKeyInUnitInt.address.hex;
return publicKey;
return privateKeyInUnitInt.address.hex;
}
@override
@ -137,28 +136,27 @@ class CWPolygon extends Polygon {
}
@override
List<Erc20Token> getERC20Currencies(WalletBase wallet) {
final polygonWallet = wallet as PolygonWallet;
return polygonWallet.erc20Currencies;
}
List<Erc20Token> getERC20Currencies(WalletBase wallet) =>
(wallet as PolygonWallet).erc20Currencies;
@override
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as PolygonWallet).addErc20Token(token as Erc20Token);
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token) =>
(wallet as PolygonWallet).addErc20Token(token as Erc20Token);
@override
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as PolygonWallet).deleteErc20Token(token as Erc20Token);
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token) =>
(wallet as PolygonWallet).deleteErc20Token(token as Erc20Token);
@override
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as PolygonWallet).removeTokenTransactionsInHistory(token as Erc20Token);
Future<void> removeTokenTransactionsInHistory(
WalletBase wallet, CryptoCurrency token) =>
(wallet as PolygonWallet)
.removeTokenTransactionsInHistory(token as Erc20Token);
@override
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) async {
final polygonWallet = wallet as PolygonWallet;
return await polygonWallet.getErc20Token(contractAddress, 'polygon');
}
Future<Erc20Token?> getErc20Token(
WalletBase wallet, String contractAddress) =>
(wallet as PolygonWallet).getErc20Token(contractAddress, 'polygon');
@override
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
@ -176,16 +174,22 @@ class CWPolygon extends Polygon {
}
@override
void updatePolygonScanUsageState(WalletBase wallet, bool isEnabled) {
void updatePolygonScanUsageState(WalletBase wallet, bool isEnabled) =>
(wallet as PolygonWallet).updateScanProviderUsageState(isEnabled);
}
@override
Web3Client? getWeb3Client(WalletBase wallet) {
return (wallet as PolygonWallet).getWeb3Client();
}
Web3Client? getWeb3Client(WalletBase wallet) =>
(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
void setLedgerConnection(
@ -208,7 +212,8 @@ class CWPolygon extends Polygon {
}
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultPolygonErc20Tokens().initialPolygonErc20Tokens.map((e) => e.contractAddress).toList();
}
List<String> getDefaultTokenContractAddresses() => DefaultPolygonErc20Tokens()
.initialPolygonErc20Tokens
.map((e) => e.contractAddress)
.toList();
}

View file

@ -9,6 +9,7 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
@ -63,14 +64,49 @@ void startAuthenticationStateChange(
monero!.setGlobalLedgerConnection(ledgerVM.connection);
showPopUp<void>(
context: context,
builder: (BuildContext context) => AlertWithOneAction(
builder: (context) => AlertWithOneAction(
alertTitle: S.of(context).proceed_on_device,
alertContent: S.of(context).proceed_on_device_description,
buttonText: S.of(context).cancel,
alertBarrierDismissible: false,
buttonAction: () => Navigator.of(context).pop()),
buttonAction: () => Navigator.of(context).pop(),
),
);
bool tryOpening = true;
while (tryOpening) {
try {
await loadCurrentWallet();
tryOpening = false;
} on Exception catch (e) {
final errorCode = RegExp(r'0x\S*?(?= )').firstMatch(
e.toString());
final errorMessage = ledgerVM.interpretErrorCode(
errorCode?.group(0).toString().replaceAll("0x", "") ??
"");
if (errorMessage != null) {
await showPopUp<void>(
context: context,
builder: (context) => AlertWithTwoActions(
alertTitle: "Ledger Error",
alertContent: errorMessage,
leftButtonText: S.of(context).try_again,
alertBarrierDismissible: false,
actionLeftButton: () => Navigator.of(context).pop(),
rightButtonText: S.of(context).cancel,
actionRightButton: () {
tryOpening = false;
Navigator.of(context).pop();
},
),
);
} else {
tryOpening = false;
rethrow;
}
}
}
getIt.get<BottomSheetService>().showNext();
await navigatorKey.currentState!
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);

View file

@ -66,7 +66,7 @@ void startCurrentWalletChangeReaction(
final node = settingsStore.getCurrentNode(wallet.type);
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
startWalletSyncStatusChangeReaction(wallet, settingsStore);
startCheckConnectionReaction(wallet, settingsStore);
await Future.delayed(Duration.zero);

View file

@ -1,5 +1,7 @@
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/wallet_base.dart';
@ -12,7 +14,7 @@ ReactionDisposer? _onWalletSyncStatusChangeReaction;
void startWalletSyncStatusChangeReaction(
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet,
FiatConversionStore fiatConversionStore) {
SettingsStore settingsStore) {
_onWalletSyncStatusChangeReaction?.reaction.dispose();
_onWalletSyncStatusChangeReaction = reaction((_) => wallet.syncStatus, (SyncStatus status) async {
try {
@ -25,6 +27,12 @@ void startWalletSyncStatusChangeReaction(
if (status is SyncedSyncStatus || status is FailedSyncStatus) {
await WakelockPlus.disable();
}
if (status is SyncedSyncStatus &&
wallet.type == WalletType.bitcoin &&
settingsStore.usePayjoin) {
bitcoin!.resumePayjoinSessions(wallet);
}
} catch (e) {
printV(e.toString());
}

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_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/nano/nano_change_rep_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>(),
);
case Routes.dEuroSavings:
return MaterialPageRoute<void>(
builder: (_) => getIt.get<DEuroSavingsPage>(),
);
default:
return MaterialPageRoute<void>(
builder: (_) => Scaffold(

View file

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

View file

@ -165,8 +165,9 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
}
Future<void> _connectToDevice(LedgerDevice device) async {
final isConnected =
await widget.ledgerVM.connectLedger(device, widget.walletType);
widget.onConnectDevice(context, widget.ledgerVM);
if (isConnected) widget.onConnectDevice(context, widget.ledgerVM);
}
String _getDeviceTileLeading(LedgerDeviceType deviceInfo) {

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/dashboard_card_widget.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:cw_core/utils/print_verbose.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:url_launcher/url_launcher.dart';
class CakeFeaturesPage extends StatelessWidget {
CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel});
CakeFeaturesPage(
{required this.dashboardViewModel, required this.cakeFeaturesViewModel});
final DashboardViewModel dashboardViewModel;
final CakeFeaturesViewModel cakeFeaturesViewModel;
@ -58,6 +59,23 @@ class CakeFeaturesPage extends StatelessWidget {
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(
isDarkTheme: dashboardViewModel.isDarkTheme,
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 (icon != null) icon!
],

View file

@ -4,8 +4,10 @@ import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/utils/package_info.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/root_dir.dart';
@ -15,7 +17,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mailer/flutter_mailer.dart';
import 'package:cake_wallet/utils/package_info.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ExceptionHandler {
@ -113,6 +114,8 @@ class ExceptionHandler {
}
static Future<void> onError(FlutterErrorDetails errorDetails) async {
if (await onLedgerError(errorDetails)) return;
if (kDebugMode || kProfileMode) {
FlutterError.presentError(errorDetails);
printV(errorDetails.toString());
@ -183,6 +186,57 @@ class ExceptionHandler {
_hasError = false;
}
static const List<String> _ledgerErrors = [
'Wrong Device Status',
'PlatformException(133, Failed to write: (Unknown Error: 133), null, null)',
'PlatformException(IllegalArgument, Unknown deviceId:',
'ServiceNotSupportedException(ConnectionType.ble, Required service not supported. Write characteristic: false, Notify characteristic: false)',
'Exception: 6e01', // Wrong App
'Exception: 6d02',
'Exception: 6511',
'Exception: 6e00',
'Exception: 6985',
'Exception: 5515',
];
static bool isLedgerError(Object exception) =>
_ledgerErrors.any((element) => exception.toString().contains(element));
static Future<bool> onLedgerError(FlutterErrorDetails errorDetails) async {
if (!isLedgerError(errorDetails.exception)) return false;
String? interpretErrorCode(String errorCode) {
if (errorCode.contains("6985")) {
return S.current.ledger_error_tx_rejected_by_user;
} else if (errorCode.contains("5515")) {
return S.current.ledger_error_device_locked;
} else
if (["6e01", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
return S.current.ledger_error_wrong_app;
}
return null;
}
printV(errorDetails.exception);
if (navigatorKey.currentContext != null) {
await showPopUp<void>(
context: navigatorKey.currentContext!,
builder: (context) => AlertWithOneAction(
alertTitle: "Ledger Error",
alertContent:
interpretErrorCode(errorDetails.exception.toString()) ??
S.of(context).ledger_connection_error,
buttonText: S.of(context).close,
buttonAction: () => Navigator.of(context).pop(),
),
);
}
_hasError = false;
return true;
}
/// Ignore User related errors or system errors
static bool _ignoreError(String error) =>
_ignoredErrors.any((element) => error.contains(element));
@ -227,6 +281,7 @@ class ExceptionHandler {
"core/auth_service.dart:64",
"core/key_service.dart:14",
"core/wallet_loading_service.dart:139",
"Wrong Device Status: 0x5515 (UNKNOWN)",
];
static Future<void> _addDeviceInfo(File file) async {

View file

@ -20,9 +20,8 @@ class PayjoinTransactionListItem extends ActionListItem {
String get status {
switch (session.status) {
case 'success':
if (transaction?.isPending == true)
if (transaction?.isPending == false) return S.current.successful;
return S.current.payjoin_request_awaiting_tx;
return S.current.successful;
case 'inProgress':
return S.current.payjoin_request_in_progress;
case 'unrecoverable':

View file

@ -96,7 +96,8 @@ abstract class LedgerViewModelBase with Store {
if (!Platform.isIOS) await ledgerPlusUSB.stopScanning();
}
Future<void> connectLedger(sdk.LedgerDevice device, WalletType type) async {
Future<bool> connectLedger(sdk.LedgerDevice device, WalletType type) async {
if (_isConnecting) return false;
_isConnecting = true;
_connectingWalletType = type;
if (isConnected) {
@ -110,17 +111,25 @@ abstract class LedgerViewModelBase with Store {
: ledgerPlusUSB;
if (_connectionChangeSubscription == null) {
_connectionChangeSubscription =
ledger.deviceStateChanges.listen(_connectionChangeListener);
_connectionChangeSubscription = ledger
.deviceStateChanges(device.id)
.listen(_connectionChangeListener);
}
try {
_connection = await ledger.connect(device);
_isConnecting = false;
return true;
} catch (e) {
printV(e);
}
_isConnecting = false;
return false;
}
StreamSubscription<sdk.BleConnectionState>? _connectionChangeSubscription;
sdk.LedgerConnection? _connection;
bool _isConnecting = true;
bool _isConnecting = false;
WalletType? _connectingWalletType;
void _connectionChangeListener(sdk.BleConnectionState event) {
@ -168,17 +177,14 @@ abstract class LedgerViewModelBase with Store {
}
String? interpretErrorCode(String errorCode) {
switch (errorCode) {
case "6985":
if (errorCode.contains("6985")) {
return S.current.ledger_error_tx_rejected_by_user;
case "5515":
} else if (errorCode.contains("5515")) {
return S.current.ledger_error_device_locked;
case "6d02": // UNKNOWN_APDU
case "6511":
case "6e00":
} else
if (["6e01", "6a87", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
return S.current.ledger_error_wrong_app;
default:
}
return null;
}
}
}

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

@ -69,7 +69,7 @@ abstract class PayjoinDetailsViewModelBase with Store {
title: S.current.error,
value: payjoinSession.error!,
),
if (payjoinSession.txId?.isNotEmpty == true)
if (payjoinSession.txId?.isNotEmpty == true && transactionInfo != null)
StandartListItem(
title: S.current.transaction_details_transaction_id,
value: payjoinSession.txId!,
@ -107,9 +107,8 @@ abstract class PayjoinDetailsViewModelBase with Store {
String _getStatusString() {
switch (payjoinSession.status) {
case 'success':
if (transactionInfo?.isPending == true)
if (transactionInfo?.isPending == false) return S.current.successful;
return S.current.payjoin_request_awaiting_tx;
return S.current.successful;
case 'inProgress':
return S.current.payjoin_request_in_progress;
case 'unrecoverable':

View file

@ -80,11 +80,9 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
availableAccounts.addAll(accounts);
_nextIndex += limit;
// } on LedgerException catch (e) {
// error = ledgerViewModel.interpretErrorCode(e.errorCode.toRadixString(16));
} catch (e) {
printV(e);
error = S.current.ledger_connection_error;
error = ledgerViewModel.interpretErrorCode(e.toString()) ?? S.current.ledger_connection_error;
}
isLoadingMoreAccounts = false;

View file

@ -110,7 +110,7 @@ dependencies:
ledger_flutter_plus:
git:
url: https://github.com/vespr-wallet/ledger-flutter-plus
ref: c2e341d8038f1108690ad6f80f7b4b7156aacc76
ref: 60817d4b20144f9da9029f5034790272795b9d38
hashlib: ^1.19.2
on_chain:
git:

View file

@ -56,6 +56,7 @@
"apk_update": "تحديث APK",
"approve": "ﺪﻤﺘﻌﻳ",
"approve_request": "الموافقة على الطلب",
"approve_tokens": "الموافقة على الرموز",
"arrive_in_this_address": "سيصل ${currency} ${tag}إلى هذا العنوان",
"ascending": "تصاعدي",
"ask_each_time": "اسأل في كل مرة",
@ -244,6 +245,15 @@
"descending": "النزول",
"description": "ﻒﺻﻭ",
"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": "الجهاز يوقع",
"dfx_option_description": "شراء التشفير مع EUR & CHF. لعملاء البيع بالتجزئة والشركات في أوروبا",
"didnt_get_code": "لم تحصل على رمز؟",
@ -973,6 +983,7 @@
"transport_type": "نوع النقل",
"trongrid_history": "تاريخ ترونغريد",
"trusted": "موثوق به",
"try_again": "حاول ثانية",
"tx_commit_exception_no_dust_on_change": "يتم رفض المعاملة مع هذا المبلغ. باستخدام هذه العملات المعدنية ، يمكنك إرسال ${min} دون تغيير أو ${max} الذي يعيد التغيير.",
"tx_commit_failed": "فشل ارتكاب المعاملة. يرجى الاتصال بالدعم.",
"tx_commit_failed_no_peers": "فشل المعاملة في البث ، يرجى المحاولة مرة أخرى في ثانية أو نحو ذلك",

View file

@ -56,6 +56,7 @@
"apk_update": "APK ъпдейт",
"approve": "Одобряване",
"approve_request": "Одобрете искане",
"approve_tokens": "Одобрете жетоните",
"arrive_in_this_address": "${currency} ${tag}ще отидат на този адрес",
"ascending": "Възходящ",
"ask_each_time": "Питайте всеки път",
@ -244,6 +245,15 @@
"descending": "Низходящ",
"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 Holdings",
"deuro_tx_commited_content": "Може да отнеме няколко секунди, за да може транзакцията да се потвърди и да бъде отразена на екрана",
"device_is_signing": "Устройството подписва",
"dfx_option_description": "Купете криптовалута с Eur & CHF. За търговски и корпоративни клиенти в Европа",
"didnt_get_code": "Не получихте код?",
@ -973,6 +983,7 @@
"transport_type": "Тип транспорт",
"trongrid_history": "Trongrid History",
"trusted": "Надежден",
"try_again": "Опитайте отново",
"tx_commit_exception_no_dust_on_change": "Сделката се отхвърля с тази сума. С тези монети можете да изпратите ${min} без промяна или ${max}, която връща промяна.",
"tx_commit_failed": "Компетацията на транзакцията не успя. Моля, свържете се с поддръжката.",
"tx_commit_failed_no_peers": "Сделката не успя да излъчи, моля, опитайте отново след секунда или така",

View file

@ -56,6 +56,7 @@
"apk_update": "aktualizace APK",
"approve": "Schvalovat",
"approve_request": "Schválit žádost",
"approve_tokens": "Schválit tokeny",
"arrive_in_this_address": "${currency} ${tag}přijde na tuto adresu",
"ascending": "Vzestupné",
"ask_each_time": "Zeptejte se pokaždé",
@ -244,6 +245,15 @@
"descending": "Klesající",
"description": "Popis",
"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",
"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?",
@ -973,6 +983,7 @@
"transport_type": "Typ transportu",
"trongrid_history": "Trongridní historie",
"trusted": "Důvěřovat",
"try_again": "Zkuste to znovu",
"tx_commit_exception_no_dust_on_change": "Transakce je zamítnuta s touto částkou. S těmito mincemi můžete odeslat ${min} bez změny nebo ${max}, které se vrátí změna.",
"tx_commit_failed": "Transakce COMPORT selhala. Kontaktujte prosím podporu.",
"tx_commit_failed_no_peers": "Transakce se nepodařilo vysílat, zkuste to prosím znovu za vteřinu",

View file

@ -56,6 +56,7 @@
"apk_update": "APK-Update",
"approve": "Genehmigen",
"approve_request": "Anfrage genehmigen",
"approve_tokens": "Token genehmigen",
"arrive_in_this_address": "${currency} ${tag} wird an dieser Adresse ankommen",
"ascending": "Aufsteigend",
"ask_each_time": "Jedes Mal fragen",
@ -244,6 +245,15 @@
"descending": "Absteigend",
"description": "Beschreibung",
"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",
"dfx_option_description": "Kaufen Sie Krypto mit EUR & CHF. Für Einzelhandel und Unternehmenskunden in Europa",
"didnt_get_code": "Kein Code?",
@ -974,6 +984,7 @@
"transport_type": "Transporttyp",
"trongrid_history": "Trongrid-Historie",
"trusted": "Vertrauenswürdige",
"try_again": "Erneut versuchen",
"tx_commit_exception_no_dust_on_change": "Die Transaktion wird diesen Betrag abgelehnt. Mit diesen Münzen können Sie ${min} ohne Veränderung oder ${max} senden, die Änderungen zurückgeben.",
"tx_commit_failed": "Transaktionsausschüsse ist fehlgeschlagen. Bitte wenden Sie sich an Support.",
"tx_commit_failed_no_peers": "Transaktion konnte nicht übertragen werden. Bitte versuchen Sie es in einer Sekunde oder so erneut",

View file

@ -56,6 +56,7 @@
"apk_update": "APK update",
"approve": "Approve",
"approve_request": "Approve Request",
"approve_tokens": "Approve tokens",
"arrive_in_this_address": "${currency} ${tag}will arrive in this address",
"ascending": "Ascending",
"ask_each_time": "Ask each time",
@ -245,6 +246,15 @@
"descending": "Descending",
"description": "Description",
"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",
"dfx_option_description": "Buy crypto with EUR & CHF. For retail and corporate customers in Europe",
"didnt_get_code": "Didn't get code?",
@ -973,6 +983,7 @@
"transport_type": "Transport Type",
"trongrid_history": "TronGrid history",
"trusted": "Trusted",
"try_again": "Try again",
"tx_commit_exception_no_dust_on_change": "The transaction is rejected with this amount. With these coins you can send ${min} without change or ${max} that returns change.",
"tx_commit_failed": "Transaction commit failed. Please contact support.",
"tx_commit_failed_no_peers": "Transaction failed to broadcast, please try again in a second or so",

View file

@ -56,6 +56,7 @@
"apk_update": "Actualización de APK",
"approve": "Aprobar",
"approve_request": "Aprobar la solicitud",
"approve_tokens": "Aprobar tokens",
"arrive_in_this_address": "${currency} ${tag}llegará a esta dirección",
"ascending": "Ascendente",
"ask_each_time": "Pregunta cada vez",
@ -244,6 +245,15 @@
"descending": "Descendente",
"description": "Descripción",
"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",
"dfx_option_description": "Compre cripto con EUR y CHF. Para clientes minoristas y corporativos en Europa",
"didnt_get_code": "¿No recibiste el código?",
@ -974,6 +984,7 @@
"transport_type": "Tipo de transporte",
"trongrid_history": "Historia trongrid",
"trusted": "de confianza",
"try_again": "Intentar otra vez",
"tx_commit_exception_no_dust_on_change": "La transacción se rechaza con esta cantidad. Con estas monedas puede enviar ${min} sin cambios o ${max} que devuelve el cambio.",
"tx_commit_failed": "La confirmación de transacción falló. Ponte en contacto con el soporte.",
"tx_commit_failed_no_peers": "La transacción no se transmitió, intenta nuevamente en un segundo más o menos",

View file

@ -56,6 +56,7 @@
"apk_update": "Mise à jour d'APK",
"approve": "Approuver",
"approve_request": "Approuver la demande",
"approve_tokens": "Approuver les jetons",
"arrive_in_this_address": "${currency} ${tag}arrivera à cette adresse",
"ascending": "Ascendant",
"ask_each_time": "Demander à chaque fois",
@ -244,6 +245,15 @@
"descending": "Descendant",
"description": "Description",
"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",
"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 ?",
@ -973,6 +983,7 @@
"transport_type": "Type de transport",
"trongrid_history": "Histoire de la trongride",
"trusted": "de confiance",
"try_again": "Essayer à nouveau",
"tx_commit_exception_no_dust_on_change": "La transaction est rejetée avec ce montant. Avec ces pièces, vous pouvez envoyer ${min} sans changement ou ${max} qui renvoie le changement.",
"tx_commit_failed": "La validation de la transaction a échoué. Veuillez contacter l'assistance.",
"tx_commit_failed_no_peers": "La transaction n'a pas été diffusée, veuillez réessayer dans une seconde environ",

View file

@ -56,6 +56,7 @@
"apk_update": "apk sabunta",
"approve": "Amincewa",
"approve_request": "Amince da bukata",
"approve_tokens": "Amince da Alamu",
"arrive_in_this_address": "${currency} ${tag} zai je wurin wannan adireshi",
"ascending": "Hau",
"ask_each_time": "Tambaya kowane lokaci",
@ -244,6 +245,15 @@
"descending": "Saukowa",
"description": "Bayani",
"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",
"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?",
@ -975,6 +985,7 @@
"transport_type": "Nau'in sufuri",
"trongrid_history": "Tarihin Trongrid",
"trusted": "Amintacce",
"try_again": "Gwada kuma",
"tx_commit_exception_no_dust_on_change": "An ƙi ma'amala da wannan adadin. Tare da waɗannan tsabar kudi Zaka iya aika ${min}, ba tare da canji ba ko ${max} wanda ya dawo canzawa.",
"tx_commit_failed": "Ma'amala ya kasa. Da fatan za a tuntuɓi goyan baya.",
"tx_commit_failed_no_peers": "Kasuwanci ya kasa watsa, don Allah sake gwadawa a cikin na biyu ko",

View file

@ -56,6 +56,7 @@
"apk_update": "APK अद्यतन",
"approve": "मंज़ूरी देना",
"approve_request": "अनुरोध को स्वीकृत करें",
"approve_tokens": "टोकन को मंजूरी देना",
"arrive_in_this_address": "${currency} ${tag}इस पते पर पहुंचेंगे",
"ascending": "आरोही",
"ask_each_time": "हर बार पूछें",
@ -244,6 +245,15 @@
"descending": "अवरोही",
"description": "विवरण",
"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": "उपकरण हस्ताक्षर कर रहा है",
"dfx_option_description": "EUR और CHF के साथ क्रिप्टो खरीदें। यूरोप में खुदरा और कॉर्पोरेट ग्राहकों के लिए",
"didnt_get_code": "कोड नहीं मिला?",
@ -975,6 +985,7 @@
"transport_type": "परिवहन प्रकार",
"trongrid_history": "ट्रॉन्ग्रिड का इतिहास",
"trusted": "भरोसा",
"try_again": "पुनः प्रयास करें",
"tx_commit_exception_no_dust_on_change": "लेनदेन को इस राशि से खारिज कर दिया जाता है। इन सिक्कों के साथ आप चेंज या ${min} के बिना ${max} को भेज सकते हैं जो परिवर्तन लौटाता है।",
"tx_commit_failed": "लेन -देन प्रतिबद्ध विफल। कृपया संपर्क समर्थन करें।",
"tx_commit_failed_no_peers": "लेन -देन प्रसारित करने में विफल रहा, कृपया एक या दो सेकंड में पुनः प्रयास करें",

View file

@ -56,6 +56,7 @@
"apk_update": "APK ažuriranje",
"approve": "Odobriti",
"approve_request": "Odobriti zahtjev",
"approve_tokens": "Odobriti tokene",
"arrive_in_this_address": "${currency} ${tag}će stići na ovu adresu",
"ascending": "Uzlazni",
"ask_each_time": "Pitajte svaki put",
@ -244,6 +245,15 @@
"descending": "Silazni",
"description": "Opis",
"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",
"dfx_option_description": "Kupite kriptovalute s Eur & CHF. Za maloprodajne i korporativne kupce u Europi",
"didnt_get_code": "Ne dobivate kod?",
@ -973,6 +983,7 @@
"transport_type": "Transportni tip",
"trongrid_history": "Povijest Trongrida",
"trusted": "vjerovao",
"try_again": "Pokušajte ponovo",
"tx_commit_exception_no_dust_on_change": "Transakcija se odbija s tim iznosom. Pomoću ovih kovanica možete poslati ${min} bez promjene ili ${max} koja vraća promjenu.",
"tx_commit_failed": "Obveza transakcije nije uspjela. Molimo kontaktirajte podršku.",
"tx_commit_failed_no_peers": "Transakcija nije uspjela emitirati, pokušajte ponovo u sekundi ili tako",

View file

@ -56,6 +56,7 @@
"apk_update": "APK թարմացում",
"approve": "Հաստատել",
"approve_request": "Հաստատում է հայցը",
"approve_tokens": "Հաստատում է նշանները",
"arrive_in_this_address": "${currency} ${tag}կժամանի այս հասցեում",
"ascending": "Աճող",
"ask_each_time": "Հարցնել ամեն անգամ",
@ -244,6 +245,15 @@
"descending": "Նվազող",
"description": "Նկարագրություն",
"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": "Սարքը ստորագրում է",
"dfx_option_description": "Գնեք կրիպտոարժույթ EUR և CHF: Կորպորատիվ և մանրածախ հաճախորդների համար Եվրոպայում",
"didnt_get_code": "Չեք ստացել կոդը?",
@ -973,6 +983,7 @@
"transport_type": "Տրանսպորտի տեսակը",
"trongrid_history": "TronGrid պատմություն",
"trusted": "Վստահելի",
"try_again": "Կրկին փորձեք",
"tx_commit_exception_no_dust_on_change": "Փոխանցումը մերժվել է այս գումարով: Այս արժույթներով կարող եք ուղարկել ${min} առանց փոփոխության կամ ${max} որը վերադարձնում է փոփոխությունը",
"tx_commit_failed": "Փոխանցումը ձախողվել է: Խնդրում ենք դիմել աջակցությանը",
"tx_commit_failed_no_peers": "Գործարքը չի հաջողվել հեռարձակել, խնդրում ենք կրկին փորձել մեկ վայրկյանում",

View file

@ -56,6 +56,7 @@
"apk_update": "Pembaruan APK",
"approve": "Menyetujui",
"approve_request": "Menyetujui permintaan",
"approve_tokens": "Menyetujui token",
"arrive_in_this_address": "${currency} ${tag} akan tiba di alamat ini",
"ascending": "Naik",
"ask_each_time": "Tanyakan setiap kali",
@ -244,6 +245,15 @@
"descending": "Menurun",
"description": "Keterangan",
"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",
"dfx_option_description": "Beli crypto dengan EUR & CHF. Untuk pelanggan ritel dan perusahaan di Eropa",
"didnt_get_code": "Tidak mendapatkan kode?",
@ -976,6 +986,7 @@
"transport_type": "Jenis transportasi",
"trongrid_history": "Sejarah Trongrid",
"trusted": "Dipercayai",
"try_again": "Coba lagi",
"tx_commit_exception_no_dust_on_change": "Transaksi ditolak dengan jumlah ini. Dengan koin ini Anda dapat mengirim ${min} tanpa perubahan atau ${max} yang mengembalikan perubahan.",
"tx_commit_failed": "Transaksi Gagal. Silakan hubungi Dukungan.",
"tx_commit_failed_no_peers": "Transaksi gagal untuk disiarkan, silakan coba lagi sebentar lagi",

View file

@ -56,6 +56,7 @@
"apk_update": "Aggiornamento APK",
"approve": "Approvare",
"approve_request": "Approvare la richiesta",
"approve_tokens": "Approvare i token",
"arrive_in_this_address": "${currency} ${tag}arriverà a questo indirizzo",
"ascending": "Ascendente",
"ask_each_time": "Chiedi ogni volta",
@ -244,6 +245,15 @@
"descending": "Discendente",
"description": "Descrizione",
"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",
"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?",
@ -974,6 +984,7 @@
"transport_type": "Tipo di trasporto",
"trongrid_history": "Cronologia TronGrid",
"trusted": "Fidato",
"try_again": "Riprova",
"tx_commit_exception_no_dust_on_change": "La transazione viene respinta con questo importo. Con queste monete è possibile inviare ${min} senza modifiche o ${max} che restituisce il cambiamento.",
"tx_commit_failed": "Commit di transazione non riuscita. Si prega di contattare il supporto.",
"tx_commit_failed_no_peers": "Errore nella trasmissione della transazione, si prega di provare nuovamente",

View file

@ -56,6 +56,7 @@
"apk_update": "APKアップデート",
"approve": "承認する",
"approve_request": "リクエストを承認します",
"approve_tokens": "トークンを承認します",
"arrive_in_this_address": "${currency} ${tag}はこの住所に到着します",
"ascending": "上昇",
"ask_each_time": "毎回尋ねてください",
@ -244,6 +245,15 @@
"descending": "下降",
"description": "説明",
"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": "デバイスが署名しています",
"dfx_option_description": "EURCHFで暗号を購入します。ヨーロッパの小売および企業の顧客向け",
"didnt_get_code": "コードを取得しませんか?",
@ -974,6 +984,7 @@
"transport_type": "輸送タイプ",
"trongrid_history": "トロンリッドの歴史",
"trusted": "信頼できる",
"try_again": "もう一度やり直してください",
"tx_commit_exception_no_dust_on_change": "この金額ではトランザクションは拒否されます。 これらのコインを使用すると、おつりなしの ${min} またはおつりを返す ${max} を送信できます。",
"tx_commit_failed": "トランザクションコミットは失敗しました。サポートに連絡してください。",
"tx_commit_failed_no_peers": "トランザクションはブロードキャストに失敗しました。一瞬かそこらで再試行してください",

View file

@ -56,6 +56,7 @@
"apk_update": "APK 업데이트",
"approve": "승인",
"approve_request": "요청 승인",
"approve_tokens": "토큰을 승인합니다",
"arrive_in_this_address": "${currency} ${tag}이(가) 이 주소로 도착합니다",
"ascending": "오름차순",
"ask_each_time": "매번 묻기",
@ -244,6 +245,15 @@
"descending": "내림차순",
"description": "설명",
"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": "장치가 서명 중입니다",
"dfx_option_description": "EUR 및 CHF로 암호화폐 구매. 유럽의 개인 및 기업 고객 대상",
"didnt_get_code": "코드를 받지 못했나요?",
@ -972,6 +982,7 @@
"transport_type": "전송 유형",
"trongrid_history": "TronGrid 내역",
"trusted": "신뢰됨",
"try_again": "다시 시도하십시오",
"tx_commit_exception_no_dust_on_change": "이 금액으로는 트랜잭션이 거부됩니다. 이 코인으로는 잔돈 없이 ${min}을(를) 보내거나 잔돈이 반환되는 ${max}을(를) 보낼 수 있습니다.",
"tx_commit_failed": "트랜잭션 커밋 실패. 지원팀에 문의하세요.",
"tx_commit_failed_no_peers": "트랜잭션 전파 실패. 잠시 후 다시 시도하세요.",

View file

@ -56,6 +56,7 @@
"apk_update": "APK အပ်ဒိတ်",
"approve": "လက်မခံပါ။",
"approve_request": "တောင်းဆိုမှုကိုအတည်ပြု",
"approve_tokens": "တိုကင်အတည်ပြု",
"arrive_in_this_address": "${currency} ${tag}ဤလိပ်စာသို့ ရောက်ရှိပါမည်။",
"ascending": "တက်",
"ask_each_time": "တစ်ခုချင်းစီကိုအချိန်မေးပါ",
@ -244,6 +245,15 @@
"descending": "ဆင်း",
"description": "ဖော်ပြချက်",
"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": "ကိရိယာလက်မှတ်ထိုးနေသည်",
"dfx_option_description": "Crypto ကို EUR & CHF ဖြင့် 0 ယ်ပါ။ လက်လီရောင်းဝယ်မှုနှင့်ဥရောပရှိကော်ပိုရိတ်ဖောက်သည်များအတွက်",
"didnt_get_code": "ကုဒ်ကို မရဘူးလား?",
@ -973,6 +983,7 @@
"transport_type": "သယ်ယူပို့ဆောင်ရေးအမျိုးအစား",
"trongrid_history": "Trongrid သမိုင်း",
"trusted": "ယုံတယ်။",
"try_again": "ထပ်ကြိုးစားပါ",
"tx_commit_exception_no_dust_on_change": "အဆိုပါငွေပေးငွေယူကဒီပမာဏနှင့်အတူပယ်ချခံရသည်။ ဤဒင်္ဂါးပြားများနှင့်အတူပြောင်းလဲမှုကိုပြန်လည်ပြောင်းလဲခြင်းသို့မဟုတ် ${min} မပါဘဲ ${max} ပေးပို့နိုင်သည်။",
"tx_commit_failed": "ငွေပေးငွေယူကျူးလွန်မှုပျက်ကွက်။ ကျေးဇူးပြုပြီးပံ့ပိုးမှုဆက်သွယ်ပါ။",
"tx_commit_failed_no_peers": "ငွေပေးငွေယူထုတ်လွှင့်ရန်ပျက်ကွက်ပါက ကျေးဇူးပြု. ဒုတိယသို့မဟုတ်ထိုအတိုင်းထပ်မံကြိုးစားပါ",

View file

@ -56,6 +56,7 @@
"apk_update": "APK-update",
"approve": "Goedkeuren",
"approve_request": "Het verzoek goedkeuren",
"approve_tokens": "Tokens goedkeuren",
"arrive_in_this_address": "${currency} ${tag}komt aan op dit adres",
"ascending": "Stijgend",
"ask_each_time": "Vraag het elke keer",
@ -244,6 +245,15 @@
"descending": "Aflopend",
"description": "Beschrijving",
"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",
"dfx_option_description": "Koop crypto met EUR & CHF. Voor retail- en zakelijke klanten in Europa",
"didnt_get_code": "Geen code?",
@ -973,6 +983,7 @@
"transport_type": "Transporttype",
"trongrid_history": "Trongrid geschiedenis",
"trusted": "vertrouwd",
"try_again": "Probeer het opnieuw",
"tx_commit_exception_no_dust_on_change": "De transactie wordt afgewezen met dit bedrag. Met deze munten kunt u ${min} verzenden zonder verandering of ${max} die wijziging retourneert.",
"tx_commit_failed": "Transactiebewissing is mislukt. Neem contact op met de ondersteuning.",
"tx_commit_failed_no_peers": "De transactie is niet uitgezonden, probeer het opnieuw binnen een seconde of zo",

View file

@ -56,6 +56,7 @@
"apk_update": "Aktualizacja APK",
"approve": "Zatwierdzić",
"approve_request": "Zatwierdzić żądanie",
"approve_tokens": "Zatwierdzić tokeny",
"arrive_in_this_address": "${currency} ${tag}dotrze na ten adres",
"ascending": "Wznoszący się",
"ask_each_time": "Zapytaj za każdym razem",
@ -244,6 +245,15 @@
"descending": "Malejąco",
"description": "Opis",
"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",
"dfx_option_description": "Kup krypto za EUR & CHF. Dla klientów prywatnych i korporacyjnych w Europie",
"didnt_get_code": "Nie dostałeś kodu?",
@ -973,6 +983,7 @@
"transport_type": "Typ transportu",
"trongrid_history": "Historia Trongrida",
"trusted": "Zaufany",
"try_again": "Spróbuj ponownie",
"tx_commit_exception_no_dust_on_change": "Transakcja została odrzucana z tą kwotą. Za pomocą tych monet możesz wysłać ${min} bez reszty lub ${max}, które zwrócą resztę.",
"tx_commit_failed": "Zatwierdzenie transakcji nie powiodło się. Skontaktuj się z obsługą.",
"tx_commit_failed_no_peers": "Transakcja nie była transmitowana, spróbuj ponownie za około sekundę",

View file

@ -56,6 +56,7 @@
"apk_update": "Atualização de APK",
"approve": "Aprovar",
"approve_request": "Aprovar solicitação",
"approve_tokens": "Aprovar tokens",
"arrive_in_this_address": "${currency} ${tag}chegará neste endereço",
"ascending": "Ascendente",
"ask_each_time": "Pergunte cada vez",
@ -244,6 +245,15 @@
"descending": "descendente",
"description": "Descrição",
"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",
"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?",
@ -975,6 +985,7 @@
"transport_type": "Tipo de transporte",
"trongrid_history": "História de Trongrid",
"trusted": "confiável",
"try_again": "Tente novamente",
"tx_commit_exception_no_dust_on_change": "A transação é rejeitada com esse valor. Com essas moedas, você pode enviar ${min} sem alteração ou ${max} que retorna alterações.",
"tx_commit_failed": "A confirmação da transação falhou. Entre em contato com o suporte.",
"tx_commit_failed_no_peers": "A transação não foi transmitida, tente novamente em um segundo",

View file

@ -56,6 +56,7 @@
"apk_update": "Обновление APK",
"approve": "Утвердить",
"approve_request": "Утвердить запрос",
"approve_tokens": "Одобрить токены",
"arrive_in_this_address": "${currency} ${tag}придет на этот адрес",
"ascending": "Восходящий",
"ask_each_time": "Спросите каждый раз",
@ -244,6 +245,15 @@
"descending": "Нисходящий",
"description": "Описание",
"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": "Устройство подписывает",
"dfx_option_description": "Купить крипто с Eur & CHF. Для розничных и корпоративных клиентов в Европе",
"didnt_get_code": "Не получить код?",
@ -974,6 +984,7 @@
"transport_type": "Транспортный тип",
"trongrid_history": "История Тронгрида",
"trusted": "доверенный",
"try_again": "Попробуйте еще раз",
"tx_commit_exception_no_dust_on_change": "Транзакция отклоняется с этой суммой. С этими монетами вы можете отправлять ${min} без изменения или ${max}, которые возвращают изменение.",
"tx_commit_failed": "Комплект транзакции не удался. Пожалуйста, свяжитесь с поддержкой.",
"tx_commit_failed_no_peers": "Транзакция не смогла передать, попробуйте еще раз через секунду или около того",

View file

@ -56,6 +56,7 @@
"apk_update": "ปรับปรุง APK",
"approve": "อนุมัติ",
"approve_request": "อนุมัติคำขอ",
"approve_tokens": "อนุมัติโทเค็น",
"arrive_in_this_address": "${currency} ${tag}จะมาถึงที่อยู่นี้",
"ascending": "จากน้อยไปมาก",
"ask_each_time": "ถามทุกครั้ง",
@ -244,6 +245,15 @@
"descending": "ลงมา",
"description": "คำอธิบาย",
"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": "อุปกรณ์กำลังลงนาม",
"dfx_option_description": "ซื้อ crypto ด้วย Eur & CHF สำหรับลูกค้ารายย่อยและลูกค้าในยุโรป",
"didnt_get_code": "ไม่ได้รับรหัส?",
@ -973,6 +983,7 @@
"transport_type": "ประเภทการขนส่ง",
"trongrid_history": "ประวัติศาสตร์ Trongrid",
"trusted": "มั่นคง",
"try_again": "ลองอีกครั้ง",
"tx_commit_exception_no_dust_on_change": "ธุรกรรมถูกปฏิเสธด้วยจำนวนเงินนี้ ด้วยเหรียญเหล่านี้คุณสามารถส่ง ${min} โดยไม่ต้องเปลี่ยนแปลงหรือ ${max} ที่ส่งคืนการเปลี่ยนแปลง",
"tx_commit_failed": "การทำธุรกรรมล้มเหลว กรุณาติดต่อฝ่ายสนับสนุน",
"tx_commit_failed_no_peers": "การทำธุรกรรมล้มเหลวในการออกอากาศโปรดลองอีกครั้งในวินาทีหรือมากกว่านั้น",

View file

@ -56,6 +56,7 @@
"apk_update": "APK update",
"approve": "Aprubahan",
"approve_request": "Aprubahan ang kahilingan",
"approve_tokens": "Aprubahan ang mga token",
"arrive_in_this_address": "Ang ${currency} ${tag} ay darating sa address na ito",
"ascending": "Umakyat",
"ask_each_time": "Magtanong sa tuwing",
@ -244,6 +245,15 @@
"descending": "Pababang",
"description": "Paglalarawan",
"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",
"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?",
@ -973,6 +983,7 @@
"transport_type": "Uri ng transportasyon",
"trongrid_history": "Kasaysayan ng TronGrid",
"trusted": "Pinagkakatiwalaan",
"try_again": "Subukang muli",
"tx_commit_exception_no_dust_on_change": "Ang transaksyon ay tinanggihan sa halagang ito. Sa mga barya na ito maaari kang magpadala ng ${min} nang walang sukli o ${max} na nagbabalik ng sukli.",
"tx_commit_failed": "Nabigo ang transaksyon. Mangyaring makipag-ugnay sa suporta.",
"tx_commit_failed_no_peers": "Nabigo ang transaksyon na mag -broadcast, mangyaring subukang muli sa isang segundo o higit pa",

View file

@ -56,6 +56,7 @@
"apk_update": "APK güncellemesi",
"approve": "Onaylamak",
"approve_request": "Talebi Onaylama",
"approve_tokens": "Jetonları onaylayın",
"arrive_in_this_address": "${currency} ${tag}bu adrese ulaşacak",
"ascending": "Yükselen",
"ask_each_time": "Her seferinde sor",
@ -244,6 +245,15 @@
"descending": "Azalan",
"description": "Tanım",
"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",
"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?",
@ -973,6 +983,7 @@
"transport_type": "Taşıma tipi",
"trongrid_history": "Trongrid tarihi",
"trusted": "Güvenilir",
"try_again": "Tekrar deneyin",
"tx_commit_exception_no_dust_on_change": "İşlem bu miktarla reddedilir. Bu madeni paralarla değişiklik yapmadan ${min} veya değişikliği döndüren ${max} gönderebilirsiniz.",
"tx_commit_failed": "İşlem taahhüdü başarısız oldu. Lütfen Destek ile iletişime geçin.",
"tx_commit_failed_no_peers": "İşlem yayın yapamadı, lütfen bir saniye içinde tekrar deneyin",

View file

@ -56,6 +56,7 @@
"apk_update": "Оновлення APK",
"approve": "Затвердити",
"approve_request": "Запитайте запит",
"approve_tokens": "Затвердити токени",
"arrive_in_this_address": "${currency} ${tag}надійде на цю адресу",
"ascending": "Висхід",
"ask_each_time": "Запитайте кожен раз",
@ -244,6 +245,15 @@
"descending": "Низхідний",
"description": "опис",
"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": "Пристрій підписується",
"dfx_option_description": "Купуйте криптовалюту з EUR & CHF. Для роздрібних та корпоративних клієнтів у Європі",
"didnt_get_code": "Не отримали код?",
@ -974,6 +984,7 @@
"transport_type": "Транспортний тип",
"trongrid_history": "Тронгрідська історія",
"trusted": "довіряють",
"try_again": "Спробуйте ще раз",
"tx_commit_exception_no_dust_on_change": "Транзакція відхилена цією сумою. За допомогою цих монет ви можете надіслати ${min} без змін або ${max}, що повертає зміни.",
"tx_commit_failed": "Транзакційна комісія не вдалося. Будь ласка, зв'яжіться з підтримкою.",
"tx_commit_failed_no_peers": "Транзакція не вдалося транслювати, спробуйте ще раз за секунду або близько того",

View file

@ -56,6 +56,7 @@
"apk_update": "APK اپ ڈیٹ",
"approve": "ﻭﺮﮐ ﺭﻮﻈﻨﻣ",
"approve_request": "درخواست کو منظور کریں",
"approve_tokens": "ٹوکن کو منظور کریں",
"arrive_in_this_address": "${currency} ${tag}اس پتے پر پہنچے گا۔",
"ascending": "چڑھنے",
"ask_each_time": "ہر بار پوچھیں",
@ -244,6 +245,15 @@
"descending": "اترتے ہوئے",
"description": "ﻞﯿﺼﻔﺗ",
"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": "ڈیوائس پر دستخط کر رہے ہیں",
"dfx_option_description": "یورو اور سی ایچ ایف کے ساتھ کرپٹو خریدیں۔ یورپ میں خوردہ اور کارپوریٹ صارفین کے لئے",
"didnt_get_code": "کوڈ نہیں ملتا؟",
@ -975,6 +985,7 @@
"transport_type": "ٹرانسپورٹ کی قسم",
"trongrid_history": "ٹرانگریڈ ہسٹری",
"trusted": "قابل اعتماد",
"try_again": "دوبارہ کوشش کریں",
"tx_commit_exception_no_dust_on_change": "اس رقم سے لین دین کو مسترد کردیا گیا ہے۔ ان سککوں کے ذریعہ آپ بغیر کسی تبدیلی کے ${min} یا ${max} بھیج سکتے ہیں جو لوٹتے ہیں۔",
"tx_commit_failed": "ٹرانزیکشن کمٹ ناکام ہوگیا۔ براہ کرم سپورٹ سے رابطہ کریں۔",
"tx_commit_failed_no_peers": "ٹرانزیکشن نشر کرنے میں ناکام ، براہ کرم ایک سیکنڈ یا اس میں دوبارہ کوشش کریں",

View file

@ -56,6 +56,7 @@
"apk_update": "Cập nhật APK",
"approve": "Phê duyệt",
"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",
"ascending": "Tăng dần",
"ask_each_time": "Hỏi mỗi lần",
@ -245,6 +246,15 @@
"descending": "Giảm dần",
"description": "Mô tả",
"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ý",
"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ã?",
@ -974,6 +984,7 @@
"transport_type": "Loại vận chuyển",
"trongrid_history": "Lịch sử TronGrid",
"trusted": "Đã tin cậy",
"try_again": "Hãy thử lại",
"tx_commit_exception_no_dust_on_change": "Giao dịch bị từ chối với số tiền này. Với số tiền này bạn có thể gửi ${min} mà không cần đổi tiền lẻ hoặc ${max} trả lại tiền lẻ.",
"tx_commit_failed": "Giao dịch không thành công. Vui lòng liên hệ với hỗ trợ.",
"tx_commit_failed_no_peers": "Giao dịch không phát sóng, vui lòng thử lại trong một giây hoặc lâu hơn",

View file

@ -56,6 +56,7 @@
"apk_update": "Àtúnse áàpù títun wà",
"approve": "Fi ọwọ si",
"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ìí",
"ascending": "Goke",
"ask_each_time": "Beere lọwọ kọọkan",
@ -244,6 +245,15 @@
"descending": "Sọkalẹ",
"description": "Apejuwe",
"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ẹ",
"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?",
@ -974,6 +984,7 @@
"transport_type": "Iru irinna",
"trongrid_history": "Itan Trongrid",
"trusted": "A ti fọkàn ẹ̀ tán",
"try_again": "Gbiyanju lẹẹkansi",
"tx_commit_exception_no_dust_on_change": "Iṣowo naa ti kọ pẹlu iye yii. Pẹlu awọn owó wọnyi o le firanṣẹ ${min} laisi ayipada tabi ${max} ni iyipada iyipada.",
"tx_commit_failed": "Idunadura iṣowo kuna. Jọwọ kan si atilẹyin.",
"tx_commit_failed_no_peers": "Idunadura kuna lati wa igbohungbe, jọwọ gbiyanju lẹẹkansi ni iṣẹju keji tabi bẹẹ",

View file

@ -56,6 +56,7 @@
"apk_update": "APK更新",
"approve": "批准",
"approve_request": "批准请求",
"approve_tokens": "批准令牌",
"arrive_in_this_address": "${currency} ${tag}将到达此地址",
"ascending": "上升",
"ask_each_time": "每次问",
@ -244,6 +245,15 @@
"descending": "下降",
"description": "描述",
"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": "设备正在签名",
"dfx_option_description": "用EurChf购买加密货币。对于欧洲的零售和企业客户",
"didnt_get_code": "没有获取代码?",
@ -973,6 +983,7 @@
"transport_type": "运输类型",
"trongrid_history": "Trongrid历史",
"trusted": "值得信赖",
"try_again": "再试一次",
"tx_commit_exception_no_dust_on_change": "交易被此金额拒绝。使用这些硬币,您可以发送${min}无需更改或返回${max}的变化。",
"tx_commit_failed": "交易承诺失败。请联系支持。",
"tx_commit_failed_no_peers": "交易无法广播,请在一秒钟左右的时间内重试",

View file

@ -679,6 +679,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/hardware/hardware_account_data.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_priority.dart';
import 'package:cw_core/wallet_base.dart';
@ -706,6 +707,7 @@ import 'package:cw_ethereum/ethereum_client.dart';
import 'package:cw_ethereum/ethereum_wallet.dart';
import 'package:cw_ethereum/ethereum_wallet_service.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';
@ -754,6 +756,16 @@ abstract class Ethereum {
Web3Client? getWeb3Client(WalletBase wallet);
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);
Future<List<HardwareAccountData>> getHardwareWalletAccounts(LedgerViewModel ledgerVM, {int index = 0, int limit = 5});
List<String> getDefaultTokenContractAddresses();
@ -786,6 +798,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/hardware/hardware_account_data.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_priority.dart';
import 'package:cw_core/wallet_base.dart';
@ -856,6 +869,8 @@ abstract class Polygon {
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token);
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);
void updatePolygonScanUsageState(WalletBase wallet, bool isEnabled);
Web3Client? getWeb3Client(WalletBase wallet);