mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
CW-1069-implement-deuro-dapp-support (#2304)
* feat: started dEuro Savings integration * fix: merge conflict regarding theming * feat: Add dEuro Savings Screen * feat: Change DEuro Savings UI * feat: Complete DEuro Savings integration with UI enhancements and transaction support * style: remove forgotten print statements * feat: localize dEuro subtitle * feat: add approval flow and priority handling to DEuro Savings integration - Introduced approval flow for DEuro Savings to enable token approvals. - Added priority handling for deposit and withdrawal operations. - Updated UI to support approval state and interactions. - Localized new strings for multiple languages. - Enhanced transaction handling with separate approval and commit actions. * feat: add support for ERC20 token approval transactions - Introduced `signApprovalTransaction` and `createApprovalTransaction` methods. - Added handling for infinite approvals. - Implemented encoding for approval transaction data. - Enhanced transaction creation flow with approval-specific functionality. * Update UI * feat: enhance DEuro Savings logic and UI with computed property and fix gradient background * feat: localize transaction confirmation content for DEuro Savings * feat: enable interest collection for DEuro Savings with localized support * fix reformatting [skip ci] --------- Co-authored-by: tuxsudo <tuxsudo@tux.pizza> Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
150becb679
commit
edaf485993
49 changed files with 2081 additions and 66 deletions
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));
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
@ -1511,5 +1513,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();
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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,45 @@
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/bottom_sheet/base_bottom_sheet_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/view_model/integrations/deuro_view_model.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EditSavingsBottomSheet extends BaseBottomSheet {
|
||||
EditSavingsBottomSheet(this.dEuroViewModel, {required super.titleText});
|
||||
|
||||
final _amountController = TextEditingController();
|
||||
final DEuroViewModel dEuroViewModel;
|
||||
|
||||
@override
|
||||
Widget contentWidget(BuildContext context) => Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: CurrencyAmountTextField(
|
||||
hasUnderlineBorder: true,
|
||||
borderWidth: 1.0,
|
||||
selectedCurrency: CryptoCurrency.deuro.name.toUpperCase(),
|
||||
amountFocusNode: null,
|
||||
amountController: _amountController,
|
||||
tag: CryptoCurrency.deuro.tag,
|
||||
isAmountEditable: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@override
|
||||
Widget footerWidget(BuildContext context) => Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 34),
|
||||
child: LoadingPrimaryButton(
|
||||
onPressed: () => dEuroViewModel.prepareSavingsEdit(_amountController.text, true),
|
||||
text: S.of(context).confirm,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||
isLoading: false,
|
||||
isDisabled: false,
|
||||
),
|
||||
);
|
||||
}
|
|
@ -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!
|
||||
],
|
||||
|
|
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();
|
||||
}
|
||||
}
|
|
@ -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": "لم تحصل على رمز؟",
|
||||
|
|
|
@ -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": "Не получихте код?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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",
|
||||
|
@ -244,6 +245,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?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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 ?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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": "कोड नहीं मिला?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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": "Չեք ստացել կոդը?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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": "コードを取得しませんか?",
|
||||
|
|
|
@ -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": "코드를 받지 못했나요?",
|
||||
|
|
|
@ -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": "ကုဒ်ကို မရဘူးလား?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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": "Не получить код?",
|
||||
|
|
|
@ -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": "ไม่ได้รับรหัส?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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": "Не отримали код?",
|
||||
|
|
|
@ -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": "کوڈ نہیں ملتا؟",
|
||||
|
|
|
@ -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",
|
||||
|
@ -243,6 +244,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ã?",
|
||||
|
|
|
@ -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?",
|
||||
|
|
|
@ -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": "没有获取代码?",
|
||||
|
|
|
@ -670,6 +670,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';
|
||||
|
@ -697,6 +698,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';
|
||||
|
||||
|
@ -745,6 +747,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();
|
||||
|
@ -777,6 +789,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';
|
||||
|
@ -847,6 +860,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