mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 20:39:51 +00:00
Merge branch 'main' into xelis
This commit is contained in:
commit
75e2c67752
65 changed files with 2276 additions and 149 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
121
cw_ethereum/lib/deuro/deuro_savings.dart
Normal file
121
cw_ethereum/lib/deuro/deuro_savings.dart
Normal 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;
|
||||
}
|
543
cw_ethereum/lib/deuro/deuro_savings_contract.dart
Normal file
543
cw_ethereum/lib/deuro/deuro_savings_contract.dart
Normal file
File diff suppressed because one or more lines are too long
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(),
|
||||
|
|
197
lib/src/screens/integrations/deuro/savings_page.dart
Normal file
197
lib/src/screens/integrations/deuro/savings_page.dart
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
107
lib/src/screens/integrations/deuro/widgets/numpad.dart
Normal file
107
lib/src/screens/integrations/deuro/widgets/numpad.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
]),
|
||||
);
|
||||
}
|
|
@ -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!
|
||||
],
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
119
lib/view_model/integrations/deuro_view_model.dart
Normal file
119
lib/view_model/integrations/deuro_view_model.dart
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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':
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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": "فشل المعاملة في البث ، يرجى المحاولة مرة أخرى في ثانية أو نحو ذلك",
|
||||
|
|
|
@ -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": "Сделката не успя да излъчи, моля, опитайте отново след секунда или така",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "लेन -देन प्रसारित करने में विफल रहा, कृपया एक या दो सेकंड में पुनः प्रयास करें",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "Գործարքը չի հաջողվել հեռարձակել, խնդրում ենք կրկին փորձել մեկ վայրկյանում",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "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": "トランザクションはブロードキャストに失敗しました。一瞬かそこらで再試行してください",
|
||||
|
|
|
@ -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": "트랜잭션 전파 실패. 잠시 후 다시 시도하세요.",
|
||||
|
|
|
@ -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": "ငွေပေးငွေယူထုတ်လွှင့်ရန်ပျက်ကွက်ပါက ကျေးဇူးပြု. ဒုတိယသို့မဟုတ်ထိုအတိုင်းထပ်မံကြိုးစားပါ",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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ę",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "Транзакция не смогла передать, попробуйте еще раз через секунду или около того",
|
||||
|
|
|
@ -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": "การทำธุรกรรมล้มเหลวในการออกอากาศโปรดลองอีกครั้งในวินาทีหรือมากกว่านั้น",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": "Транзакція не вдалося транслювати, спробуйте ще раз за секунду або близько того",
|
||||
|
|
|
@ -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": "ٹرانزیکشن نشر کرنے میں ناکام ، براہ کرم ایک سیکنڈ یا اس میں دوبارہ کوشش کریں",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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ẹẹ",
|
||||
|
|
|
@ -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": "用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": "交易无法广播,请在一秒钟左右的时间内重试",
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue