Merge branch 'main' into CW-855-Transactions-not-cleared-correctly-when-switching-wallets

This commit is contained in:
Serhii 2025-03-05 17:13:55 +02:00
commit e3e0845d8e
70 changed files with 954 additions and 659 deletions

View file

@ -1,4 +1,3 @@
Added passphrase support
Added decentralized cross-chain exchange, Chainflip
Ledger fixes
UI enhancements
Bug fixes

View file

@ -1,5 +1,5 @@
Added Zano wallet support
Added Monero/Wownero passphrase support
Added decentralized cross-chain exchange, Chainflip
Zano enhancements
Ethereum enhancements
Ledger fixes
UI enhancements
Bug fixes

View file

@ -915,6 +915,10 @@ abstract class ElectrumWalletBase
}
}
// if the amount left for change is less than dust, but not less than 0
// then add it to the fees
fee += amountLeftForChange;
return EstimatedTxResult(
utxos: utxoDetails.utxos,
inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos,
@ -1366,7 +1370,7 @@ abstract class ElectrumWalletBase
List<BitcoinUnspent> updatedUnspentCoins = [];
final previousUnspentCoins = List<BitcoinUnspent>.from(unspentCoins.where((utxo) =>
utxo.bitcoinAddressRecord.type != SegwitAddresType.mweb &&
utxo.bitcoinAddressRecord.type != SegwitAddresType.mweb &&
utxo.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord));
if (hasSilentPaymentsScanning) {
@ -1424,7 +1428,6 @@ abstract class ElectrumWalletBase
required List<BitcoinUnspent> updatedUnspentCoins,
required List<List<BitcoinUnspent>?> results,
}) {
if (failedCount == results.length) {
printV("All UTXOs failed to fetch, falling back to previous UTXOs");
return previousUnspentCoins;

View file

@ -11,7 +11,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
this.iconPath,
this.tag,
this.enabled = false,
})
this.isPotentialScam = false,
})
: super(title: title, raw: raw);
final String name;
@ -20,6 +21,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
final String? iconPath;
final int decimals;
final bool enabled;
final bool isPotentialScam;
set enabled(bool value) => this.enabled = value;

View file

@ -16,8 +16,8 @@ class EVMChainTransactionCreationException implements Exception {
class EVMChainTransactionFeesException implements Exception {
final String exceptionMessage;
EVMChainTransactionFeesException()
: exceptionMessage = 'Current balance is less than the estimated fees for this transaction.';
EVMChainTransactionFeesException(String currency)
: exceptionMessage = 'Transaction failed due to insufficient $currency balance to cover the fees.';
@override
String toString() => exceptionMessage;

View file

@ -417,7 +417,7 @@ abstract class EVMChainWalletBase
// check the fees on the base currency (Eth/Polygon)
if (estimatedFeesForTransaction > balance[currency]!.balance) {
throw EVMChainTransactionFeesException();
throw EVMChainTransactionFeesException(currency.title);
}
if (currencyBalance.balance < totalAmount) {

View file

@ -310,7 +310,7 @@ class DFXBuyProvider extends BuyProvider {
final accessToken = await auth(cryptoCurrencyAddress);
final uri = Uri.https('services.dfx.swiss', actionType, {
final uri = Uri.https('app.dfx.swiss', actionType, {
'session': accessToken,
'lang': 'en',
'asset-out': isBuyAction ? quote.cryptoCurrency.toString() : quote.fiatCurrency.toString(),

View file

@ -59,7 +59,7 @@ class RobinhoodBuyProvider extends BuyProvider {
case WalletType.bitcoinCash:
return await wallet.signMessage(message, address: wallet.walletAddresses.address);
default:
throw Exception("WalletType is not available for Robinhood ${wallet.type}");
throw Exception("Wallet Type ${wallet.type.name} is not available for Robinhood");
}
}

View file

@ -281,6 +281,9 @@ class AddressValidator extends TextValidator {
}
}
static String get silentPaymentAddressPattern => SilentPaymentAddress.regex.pattern;
static String get mWebAddressPattern => MwebAddress.regex.pattern;
static String? getAddressFromStringPattern(CryptoCurrency type) {
String? pattern = null;

View file

@ -1256,7 +1256,7 @@ Future<void> setup({
getIt.registerFactoryParam<OrderDetailsPage, Order, void>(
(Order order, _) => OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
getIt.registerFactory(() => SupportViewModel());
getIt.registerFactory(() => SupportViewModel(getIt.get<SettingsStore>()));
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
@ -1418,4 +1418,4 @@ Future<void> setup({
getIt.registerFactory(() => SeedVerificationPage(getIt.get<WalletSeedViewModel>()));
_isSetupFinished = true;
}
}

View file

@ -1,5 +1,6 @@
import 'package:basic_utils/basic_utils.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/alert_with_picker_option.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/crypto_currency.dart';
@ -100,44 +101,41 @@ class Bip353Record {
Map<String, String> addressMap,
) async {
final entriesList = addressMap.entries.toList();
final displayItems = entriesList.map((e) {
final extendedKeyName = keyDisplayMap[e.key] ?? e.key;
final truncatedValue = _truncate(e.value, front: 6, back: 6);
return '$extendedKeyName : $truncatedValue';
final List<Map<String, String>> displayItems = entriesList.map((entry) {
final originalKey = entry.key;
final originalValue = entry.value;
final extendedKeyName = keyDisplayMap[originalKey] ?? originalKey;
final truncatedValue = _truncate(originalValue, front: 6, back: 6);
return {
'displayKey': extendedKeyName,
'displayValue': truncatedValue,
'originalKey': originalKey,
'originalValue': originalValue,
};
}).toList();
String? selectedDisplayItem;
String? selectedOriginalValue;
if (context.mounted) {
await showPopUp<void>(
context: context,
builder: (dialogContext) {
return Picker<String>(
selectedAtIndex: 0,
title:
'$bip353Name \n was successfully resolved to the following addresses, please choose one:',
items: displayItems,
onItemSelected: (String displayItem) {
selectedDisplayItem = displayItem;
return AlertWithPickerOption(
alertTitle: S.of(context).multiple_addresses_detected + '\n$bip353Name',
alertTitleTextSize: 14,
alertSubtitle: S.of(context).please_choose_one + ':',
options: displayItems,
onOptionSelected: (Map<String, String> chosenItem) {
selectedOriginalValue = chosenItem['originalValue'];
},
alertBarrierDismissible: true,
);
},
);
}
if (selectedDisplayItem == null) {
if (displayItems.isEmpty) {
return null;
}
selectedDisplayItem = displayItems[0];
}
final index = displayItems.indexOf(selectedDisplayItem!);
if (index < 0) {
return null;
}
return entriesList[index].value;
return selectedOriginalValue;
}
static String _truncate(String value, {int front = 6, int back = 6}) {

View file

@ -32,33 +32,56 @@ class AddressResolver {
static const unstoppableDomains = [
"888",
"academy",
"agency",
"altimist",
"anime",
"austin",
"bald",
"bay",
"benji",
"bet",
"binanceus",
"bitcoin",
"bitget",
"bitscrunch",
"blockchain",
"boomer",
"boston",
"ca",
"caw",
"cc",
"chat",
"chomp",
"clay",
"club",
"co",
"com",
"company",
"crypto",
"dao",
"design",
"dfz",
"digital",
"doga",
"donut",
"dream",
"email",
"emir",
"eth",
"ethermail",
"family",
"farms",
"finance",
"fun",
"fyi",
"games",
"global",
"go",
"group",
"guru",
"hi",
"hockey",
"host",
"info",
"io",
@ -68,43 +91,78 @@ class AddressResolver {
"lfg",
"life",
"live",
"llc",
"ltc",
"ltd",
"manga",
"me",
"media",
"metropolis",
"miami",
"miku",
"money",
"moon",
"mumu",
"net",
"network",
"news",
"nft",
"npc",
"onchain",
"online",
"org",
"podcast",
"pog",
"polygon",
"press",
"privacy",
"pro",
"propykeys",
"pudgy",
"pw",
"quantum",
"rad",
"raiin",
"retardio",
"rip",
"rocks",
"secret",
"services",
"site",
"smobler",
"social",
"solutions",
"space",
"stepn",
"store",
"studio",
"systems",
"tball",
"tea",
"team",
"tech",
"technology",
"today",
"tribe",
"u",
"ubu",
"uno",
"unstoppable",
"vip",
"wallet",
"website",
"wif",
"wifi",
"witg",
"work",
"world",
"wrkx",
"wtf",
"x",
"xmr",
"xyz",
"zil",
"zone"
];
static String? extractAddressByType({required String raw, required CryptoCurrency type}) {

View file

@ -209,4 +209,9 @@ class CWEthereum extends Ethereum {
throw err;
}
}
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultEthereumErc20Tokens().initialErc20Tokens.map((e) => e.contractAddress).toList();
}
}

View file

@ -208,4 +208,9 @@ class CWPolygon extends Polygon {
throw err;
}
}
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultPolygonErc20Tokens().initialPolygonErc20Tokens.map((e) => e.contractAddress).toList();
}
}

View file

@ -60,9 +60,12 @@ Future<void> startFiatRateUpdate(
tron!.getTronTokenCurrencies(appStore.wallet!).where((element) => element.enabled);
}
if (currencies != null) {
for (final currency in currencies) {
// skip potential scams:
if (currency.isPotentialScam) {
continue;
}
() async {
fiatConversionStore.prices[currency] = await FiatConversionService.fetchPrice(
crypto: currency,

View file

@ -154,4 +154,9 @@ class CWSolana extends Solana {
double? getEstimateFees(WalletBase wallet) {
return (wallet as SolanaWallet).estimatedFee;
}
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultSPLTokens().initialSPLTokens.map((e) => e.mintAddress).toList();
}
}

View file

@ -211,6 +211,21 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
.checkIfERC20TokenContractAddressIsAPotentialScamAddress(
_contractAddressController.text,
);
final isWhitelisted = await widget.homeSettingsViewModel
.checkIfTokenIsWhitelisted(_contractAddressController.text);
bool isPotentialScam = hasPotentialError;
final tokenSymbol = _tokenSymbolController.text.toUpperCase();
// check if the token symbol is the same as any of the base currencies symbols (ETH, SOL, POL, TRX, etc):
// if it is, then it's probably a scam unless it's in the whitelist
final baseCurrencySymbols =
CryptoCurrency.all.map((e) => e.title.toUpperCase()).toList();
if (baseCurrencySymbols.contains(tokenSymbol) && !isWhitelisted) {
isPotentialScam = true;
}
final actionCall = () async {
try {
await widget.homeSettingsViewModel.addToken(
@ -219,6 +234,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
title: _tokenSymbolController.text.toUpperCase(),
decimals: int.parse(_tokenDecimalController.text),
iconPath: _tokenIconPathController.text,
isPotentialScam: isPotentialScam,
),
contractAddress: _contractAddressController.text,
);
@ -226,7 +242,6 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
if (mounted) {
Navigator.pop(context);
}
} catch (e) {
showPopUp<void>(
context: context,
@ -303,7 +318,8 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
if (token != null) {
final isZano = widget.homeSettingsViewModel.walletType == WalletType.zano;
if (_tokenNameController.text.isEmpty || isZano) _tokenNameController.text = token.name;
if (_tokenSymbolController.text.isEmpty || isZano) _tokenSymbolController.text = token.title;
if (_tokenSymbolController.text.isEmpty || isZano)
_tokenSymbolController.text = token.title;
if (_tokenIconPathController.text.isEmpty)
_tokenIconPathController.text = token.iconPath ?? '';
if (_tokenDecimalController.text.isEmpty || isZano)
@ -338,7 +354,9 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
placeholder: S.of(context).token_contract_address,
options: [AddressTextFieldOption.paste],
buttonColor: Theme.of(context).hintColor,
validator: widget.homeSettingsViewModel.walletType == WalletType.zano ? null : AddressValidator(type: widget.homeSettingsViewModel.nativeToken).call,
validator: widget.homeSettingsViewModel.walletType == WalletType.zano
? null
: AddressValidator(type: widget.homeSettingsViewModel.nativeToken).call,
onPushPasteButton: (_) {
_pasteText();
},

View file

@ -18,176 +18,38 @@ class NavigationDock extends StatelessWidget {
@override
Widget build(BuildContext context) {
return dashboardViewModel.settingsStore.currentTheme.type == ThemeType.bright
? Positioned(
child: Observer(
builder: (_) {
return Container(
alignment: Alignment.bottomCenter,
height: 150,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(10),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(75),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(150),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor,
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
],
),
),
child: Container(
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50),
child: Container(
height: 75,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
border: Border.all(
color:
Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
width: 1,
),
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor,
),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: MainActions.all
.where((element) =>
element.canShow?.call(dashboardViewModel) ?? true)
.map(
(action) => Expanded(
child: Semantics(
button: true,
enabled:
(action.isEnabled?.call(dashboardViewModel) ?? true),
child: ActionButton(
key: ValueKey(
'dashboard_page_${action.name(context)}_action_button_key'),
image: Image.asset(
action.image,
height: 24,
width: 24,
color:
action.isEnabled?.call(dashboardViewModel) ?? true
? Theme.of(context)
.extension<DashboardPageTheme>()!
.mainActionsIconColor
: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
),
title: action.name(context),
onClick: () async =>
await action.onTap(context, dashboardViewModel),
textColor:
action.isEnabled?.call(dashboardViewModel) ?? true
? null
: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
),
),
),
)
.toList(),
),
),
),
),
),
),
);
},
return Positioned(
child: Observer(
builder: (_) {
return Container(
height: 150,
alignment: Alignment.bottomCenter,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: _getColors(context),
),
),
)
: Positioned(
child: Observer(
builder: (_) {
return Container(
alignment: Alignment.bottomCenter,
height: 150,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(5),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(50),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(125),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(150),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(200),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor,
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
],
),
),
child: Container(
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50),
child: Container(
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: Container(
height: 75,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
border: Border.all(
color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
width: 1,
),
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor,
// boxShadow: [
// BoxShadow(
// color: Theme.of(context)
// .extension<BalancePageTheme>()!
// .cardBorderColor
// .withAlpha(50),
// spreadRadius: dashboardViewModel.getShadowSpread(),
// blurRadius: dashboardViewModel.getShadowBlur())
// ],
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
border: Border.all(
color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
width: 1,
),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
color:
Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: MainActions.all
@ -229,9 +91,57 @@ class NavigationDock extends StatelessWidget {
),
),
),
);
},
),
),
),
);
},
),
);
}
List<Color> _getColors(BuildContext context) {
final isBright = dashboardViewModel.settingsStore.currentTheme.type == ThemeType.bright;
return isBright
? <Color>[
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(10),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(75),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(150),
Theme.of(context).extension<DashboardPageTheme>()!.thirdGradientBackgroundColor,
Theme.of(context).extension<DashboardPageTheme>()!.thirdGradientBackgroundColor
]
: <Color>[
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(5),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(50),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(125),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(150),
Theme.of(context)
.extension<DashboardPageTheme>()!
.thirdGradientBackgroundColor
.withAlpha(200),
Theme.of(context).extension<DashboardPageTheme>()!.thirdGradientBackgroundColor,
Theme.of(context).extension<DashboardPageTheme>()!.thirdGradientBackgroundColor
];
}
}

View file

@ -31,7 +31,7 @@ class ActionButton extends StatelessWidget {
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0),
padding: EdgeInsets.only(top: 5, bottom: 4, left: 0, right: 0),
alignment: alignment,
child: Column(
mainAxisSize: MainAxisSize.max,

View file

@ -136,7 +136,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
},
child: Container(
color: Theme.of(context).colorScheme.background,
padding: EdgeInsets.only(left: 40.0, right: 40.0, bottom: 40.0),
padding: EdgeInsets.only(left: 40.0, right: 40.0, bottom: 60.0),
child: Column(
children: <Widget>[
Spacer(flex: 2),
@ -146,7 +146,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
fontWeight: FontWeight.w500,
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor)),
Spacer(flex: 3),
Spacer(flex: 8),
Container(
width: 180,
child: Row(
@ -168,7 +168,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
}),
),
),
Spacer(flex: 2),
Spacer(flex: 3),
if (widget.hasLengthSwitcher) ...[
TextButton(
onPressed: () {
@ -204,8 +204,8 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
childAspectRatio: _aspectRatio,
physics: const NeverScrollableScrollPhysics(),
children: List.generate(12, (index) {
const double marginRight = 15;
const double marginLeft = 15;
const double marginRight = 8;
const double marginLeft = 8;
if (index == 9) {
// Empty container
@ -243,12 +243,12 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
key: ValueKey('pin_code_button_${index}_key'),
onPressed: () => _push(index),
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.background,
backgroundColor: Theme.of(context).cardColor,
shape: CircleBorder(),
),
child: Text('$index',
style: TextStyle(
fontSize: 30.0,
fontSize: 25.0,
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor)),
),

View file

@ -1,4 +1,3 @@
import 'dart:math';
import 'package:cake_wallet/di.dart';
@ -21,6 +20,7 @@ import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class AddressList extends StatefulWidget {
const AddressList({
@ -37,7 +37,6 @@ class AddressList extends StatefulWidget {
}
class _AddressListState extends State<AddressList> {
bool showHiddenAddresses = false;
void _toggleHiddenAddresses() {
@ -62,7 +61,7 @@ class _AddressListState extends State<AddressList> {
void updateItems() {
setState(() {
items = getItems(widget.addressListViewModel.items, showHiddenAddresses);
items = getItems(widget.addressListViewModel.forceRecomputeItems, showHiddenAddresses);
});
}
@ -132,9 +131,10 @@ class _AddressListState extends State<AddressList> {
showTrailingButton: widget.addressListViewModel.showAddManualAddresses,
showSearchButton: true,
onSearchCallback: updateItems,
trailingButtonTap: () => Navigator.of(context).pushNamed(Routes.newSubaddress).then((value) {
updateItems(); // refresh the new address
}),
trailingButtonTap: () =>
Navigator.of(context).pushNamed(Routes.newSubaddress).then((value) {
updateItems(); // refresh the new address
}),
trailingIcon: Icon(
Icons.add,
size: 20,
@ -149,7 +149,8 @@ class _AddressListState extends State<AddressList> {
cell = Container();
} else {
cell = Observer(builder: (_) {
final isCurrent = item.address == widget.addressListViewModel.address.address && editable;
final isCurrent =
item.address == widget.addressListViewModel.address.address && editable;
final backgroundColor = isCurrent
? Theme.of(context).extension<ReceivePageTheme>()!.currentTileBackgroundColor
: Theme.of(context).extension<ReceivePageTheme>()!.tilesBackgroundColor;
@ -157,17 +158,17 @@ class _AddressListState extends State<AddressList> {
? Theme.of(context).extension<ReceivePageTheme>()!.currentTileTextColor
: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor;
return AddressCell.fromItem(
item,
isCurrent: isCurrent,
hasBalance: widget.addressListViewModel.isBalanceAvailable,
hasReceived: widget.addressListViewModel.isReceivedAvailable,
// hasReceived:
backgroundColor: (kDebugMode && item.isHidden) ?
Theme.of(context).colorScheme.error :
(kDebugMode && item.isManual) ? Theme.of(context).colorScheme.error.withBlue(255) :
backgroundColor,
// hasReceived:
backgroundColor: (kDebugMode && item.isHidden)
? Theme.of(context).colorScheme.error
: (kDebugMode && item.isManual)
? Theme.of(context).colorScheme.error.withBlue(255)
: backgroundColor,
textColor: textColor,
onTap: (_) {
if (widget.onSelect != null) {
@ -177,9 +178,11 @@ class _AddressListState extends State<AddressList> {
widget.addressListViewModel.setAddress(item);
},
onEdit: editable
? () => Navigator.of(context).pushNamed(Routes.newSubaddress, arguments: item).then((value) {
updateItems(); // refresh the new address
})
? () => Navigator.of(context)
.pushNamed(Routes.newSubaddress, arguments: item)
.then((value) {
updateItems(); // refresh the new address
})
: null,
isHidden: item.isHidden,
onHide: () => _hideAddress(item),
@ -191,8 +194,8 @@ class _AddressListState extends State<AddressList> {
return index != 0
? cell
: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30), topRight: Radius.circular(30)),
borderRadius:
BorderRadius.only(topLeft: Radius.circular(30), topRight: Radius.circular(30)),
child: cell,
);
},
@ -203,5 +206,4 @@ class _AddressListState extends State<AddressList> {
await widget.addressListViewModel.toggleHideAddress(item);
updateItems();
}
}

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/core/execution_state.dart';
@ -544,6 +545,10 @@ class SendPage extends BasePage {
);
newContactAddress = newContactAddress ?? sendViewModel.newContactAddress();
if (newContactAddress?.address != null && isRegularElectrumAddress(newContactAddress!.address)) {
newContactAddress = null;
}
if (sendViewModel.coinTypeToSpendFrom != UnspentCoinType.any) newContactAddress = null;
if (newContactAddress != null && sendViewModel.showAddressBookPopup) {
@ -664,4 +669,35 @@ class SendPage extends BasePage {
),
context: context);
}
bool isRegularElectrumAddress(String address) {
final supportedTypes = [CryptoCurrency.btc, CryptoCurrency.ltc, CryptoCurrency.bch];
final excludedPatterns = [
RegExp(AddressValidator.silentPaymentAddressPattern),
RegExp(AddressValidator.mWebAddressPattern)
];
final trimmed = address.trim();
bool isValid = false;
for (var type in supportedTypes) {
final addressPattern = AddressValidator.getAddressFromStringPattern(type);
if (addressPattern != null) {
final regex = RegExp('^$addressPattern\$');
if (regex.hasMatch(trimmed)) {
isValid = true;
break;
}
}
}
for (var pattern in excludedPatterns) {
if (pattern.hasMatch(trimmed)) {
return false;
}
}
return isValid;
}
}

View file

@ -459,6 +459,14 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
}
});
reaction((_) => sendViewModel.selectedCryptoCurrency, (Currency currency) {
if (output.sendAll) {
output.setSendAll(sendViewModel.balance);
}
output.setCryptoAmount(cryptoAmountController.text);
});
reaction((_) => output.fiatAmount, (String amount) {
if (amount != fiatAmountController.text) {
fiatAmountController.text = amount;

View file

@ -20,7 +20,7 @@ class DesktopSettingsPage extends StatefulWidget {
}
class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
final int itemCount = SettingActions.desktopSettings.length;
final int itemCount = SettingActions.all.length;
int? currentPage;
@ -54,7 +54,7 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
child: ListView.separated(
padding: EdgeInsets.only(top: 0),
itemBuilder: (_, index) {
final item = SettingActions.desktopSettings[index];
final item = SettingActions.all[index];
if (!widget.dashboardViewModel.hasSilentPayments &&
item.name(context) == S.of(context).silent_payments_settings) {

View file

@ -3,10 +3,8 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/support_chat/widgets/chatwoot_widget.dart';
import 'package:cake_wallet/view_model/support_view_model.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/material.dart';
class SupportChatPage extends BasePage {
SupportChatPage(this.supportViewModel, {required this.secureStorage});
@ -23,17 +21,16 @@ class SupportChatPage extends BasePage {
Widget body(BuildContext context) => FutureBuilder<String>(
future: getCookie(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
printV(snapshot.data);
if (snapshot.hasData)
return ChatwootWidget(
secureStorage,
supportUrl: supportViewModel.fetchUrl(authToken: snapshot.data!)
supportUrl: supportViewModel.fetchUrl(authToken: snapshot.data!),
appVersion: supportViewModel.appVersion,
);
return Container();
},
);
Future<String> getCookie() async {
return await secureStorage.read(key: COOKIE_KEY) ?? "";
}
Future<String> getCookie() async =>
await secureStorage.read(key: COOKIE_KEY) ?? "";
}

View file

@ -1,46 +1,50 @@
import 'dart:convert';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
const COOKIE_KEY = 'chatwootCookie';
class ChatwootWidget extends StatefulWidget {
ChatwootWidget(this.secureStorage, {required this.supportUrl});
const ChatwootWidget(
this.secureStorage, {
required this.supportUrl,
required this.appVersion,
});
final SecureStorage secureStorage;
final String supportUrl;
final String appVersion;
@override
ChatwootWidgetState createState() => ChatwootWidgetState();
}
class ChatwootWidgetState extends State<ChatwootWidget> {
final GlobalKey _webViewkey = GlobalKey();
final GlobalKey _webViewKey = GlobalKey();
@override
Widget build(BuildContext context) => InAppWebView(
key: _webViewkey,
initialSettings: InAppWebViewSettings(
transparentBackground: true,
),
key: _webViewKey,
initialSettings: InAppWebViewSettings(transparentBackground: true),
initialUrlRequest: URLRequest(url: WebUri(widget.supportUrl)),
onWebViewCreated: (InAppWebViewController controller) {
controller.addWebMessageListener(
WebMessageListener(
jsObjectName: 'ReactNativeWebView',
onPostMessage: (WebMessage? message, WebUri? sourceOrigin, bool isMainFrame,
PlatformJavaScriptReplyProxy replyProxy) {
onPostMessage: (WebMessage? message, WebUri? sourceOrigin,
bool isMainFrame, PlatformJavaScriptReplyProxy replyProxy) {
final shortenedMessage = message?.data.toString().substring(16);
if (shortenedMessage != null && isJsonString(shortenedMessage)) {
if (shortenedMessage != null &&
_isJsonString(shortenedMessage)) {
final parsedMessage = jsonDecode(shortenedMessage);
final eventType = parsedMessage["event"];
if (eventType == 'loaded') {
final authToken = parsedMessage["config"]["authToken"];
printV(authToken);
storeCookie(authToken as String);
_storeCookie(authToken as String);
_setCustomAttributes(
controller, {"app_version": widget.appVersion});
}
}
},
@ -49,7 +53,7 @@ class ChatwootWidgetState extends State<ChatwootWidget> {
},
);
bool isJsonString(String str) {
bool _isJsonString(String str) {
try {
jsonDecode(str);
} catch (e) {
@ -58,7 +62,24 @@ class ChatwootWidgetState extends State<ChatwootWidget> {
return true;
}
Future<void> storeCookie(String value) async {
await widget.secureStorage.write(key: COOKIE_KEY, value: value);
/// Add additional contact attributes to the chatwoot chat.
/// IMPORTANT: You have to add the attribute key in the chatwoot settings
/// under: settings/custom-attributes
Future<void> _setCustomAttributes(
InAppWebViewController controller,
Map<String, dynamic> customAttributes,
) {
final attributeObject = {
"event": "set-custom-attributes",
"customAttributes": customAttributes,
};
return controller.postWebMessage(
message: WebMessage(
data: "chatwoot-widget:${jsonEncode(attributeObject)}",
),
);
}
Future<void> _storeCookie(String value) =>
widget.secureStorage.write(key: COOKIE_KEY, value: value);
}

View file

@ -0,0 +1,120 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
class AlertWithPickerOption extends BaseAlertDialog {
AlertWithPickerOption(
{required this.alertTitle,
required this.alertTitleTextSize,
required this.alertSubtitle,
required this.options,
this.onOptionSelected,
this.alertBarrierDismissible = true,
Key? key});
final String alertTitle;
final double alertTitleTextSize;
final String alertSubtitle;
final List<Map<String, String>> options;
final ValueChanged<Map<String, String>>? onOptionSelected;
final bool alertBarrierDismissible;
@override
String get titleText => alertTitle;
@override
double? get titleTextSize => alertTitleTextSize;
@override
String get contentText => alertSubtitle;
@override
bool get barrierDismissible => alertBarrierDismissible;
@override
Widget actionButtons(BuildContext context) => Container();
@override
bool get isBottomDividerExists => false;
@override
Widget content(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 16),
Text(
contentText,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none),
),
const SizedBox(height: 4),
Container(
constraints: const BoxConstraints(maxHeight: 200),
child: ListView.separated(
shrinkWrap: true,
padding: EdgeInsets.zero,
separatorBuilder: (context, index) => const SizedBox(height: 8),
itemCount: options.length,
itemBuilder: (context, index) {
final item = options[index];
final displayKey = item['displayKey'] ?? '';
final displayValue = item['displayValue'] ?? '';
return GestureDetector(
onTap: () {
onOptionSelected?.call(item);
Navigator.of(context).pop();
},
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Theme.of(context).colorScheme.background),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
displayKey,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
),
Row(
children: [
Text(
displayValue,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
),
const SizedBox(width: 4),
Icon(
Icons.arrow_forward_ios,
size: 18,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
],
),
],
),
),
);
},
),
),
],
);
}
}

View file

@ -9,6 +9,8 @@ class BaseAlertDialog extends StatelessWidget {
String? get titleText => '';
double? get titleTextSize => 20;
String get contentText => '';
String get leftActionButtonText => '';
@ -46,7 +48,7 @@ class BaseAlertDialog extends StatelessWidget {
titleText!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontSize: titleTextSize,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:flutter/material.dart';
@ -20,20 +22,8 @@ class SettingActions {
walletSettingAction,
addressBookSettingAction,
silentPaymentsSettingAction,
litecoinMwebSettingAction,
exportOutputsAction,
securityBackupSettingAction,
privacySettingAction,
displaySettingAction,
otherSettingAction,
supportSettingAction,
];
static List<SettingActions> desktopSettings = [
connectionSettingAction,
walletSettingAction,
addressBookSettingAction,
silentPaymentsSettingAction,
if (Platform.isIOS || Platform.isAndroid) litecoinMwebSettingAction,
if (Platform.isIOS || Platform.isAndroid) exportOutputsAction,
securityBackupSettingAction,
privacySettingAction,
displaySettingAction,

View file

@ -133,4 +133,9 @@ class CWTron extends Tron {
void updateTronGridUsageState(WalletBase wallet, bool isEnabled) {
(wallet as TronWallet).updateScanProviderUsageState(isEnabled);
}
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultTronTokens().initialTronTokens.map((e) => e.contractAddress).toList();
}
}

View file

@ -201,6 +201,7 @@ class ExceptionHandler {
"Connection closed before full header was received",
"Connection terminated during handshake",
"PERMISSION_NOT_GRANTED",
"OS Error: Permission denied",
"Failed host lookup:",
"CERTIFICATE_VERIFY_FAILED",
"Handshake error in client",

View file

@ -114,13 +114,12 @@ abstract class HomeSettingsViewModelBase with Store {
if (_balanceViewModel.wallet.type == WalletType.zano) {
await zano!.addZanoAssetById(_balanceViewModel.wallet, contractAddress);
}
_updateTokensList();
_updateFiatPrices(token);
} catch (e) {
throw e;
}
finally {
} finally {
isAddingToken = false;
}
}
@ -189,6 +188,40 @@ abstract class HomeSettingsViewModelBase with Store {
}
}
bool checkIfTokenIsWhitelisted(String contractAddress) {
// get the default tokens for each currency type:
List<String> defaultTokenAddresses = [];
switch (_balanceViewModel.wallet.type) {
case WalletType.ethereum:
defaultTokenAddresses = ethereum!.getDefaultTokenContractAddresses();
break;
case WalletType.polygon:
defaultTokenAddresses = polygon!.getDefaultTokenContractAddresses();
break;
case WalletType.solana:
defaultTokenAddresses = solana!.getDefaultTokenContractAddresses();
break;
case WalletType.tron:
defaultTokenAddresses = tron!.getDefaultTokenContractAddresses();
break;
case WalletType.zano:
case WalletType.banano:
case WalletType.monero:
case WalletType.none:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.haven:
case WalletType.nano:
case WalletType.wownero:
case WalletType.bitcoinCash:
return false;
}
// check if the contractAddress is in the defaultTokenAddresses
bool isInWhitelist = defaultTokenAddresses.any((element) => element == contractAddress);
return isInWhitelist;
}
Future<bool> _isPotentialScamTokenViaMoralis(
String contractAddress,
String chainName,
@ -363,6 +396,7 @@ abstract class HomeSettingsViewModelBase with Store {
CryptoCurrency get nativeToken => _balanceViewModel.wallet.currency;
void _updateFiatPrices(CryptoCurrency token) async {
if (token.isPotentialScam) return; // don't fetch price data for potential scam tokens
try {
_balanceViewModel.fiatConvertationStore.prices[token] =
await FiatConversionService.fetchPrice(
@ -455,9 +489,10 @@ abstract class HomeSettingsViewModelBase with Store {
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
tokens.addAll(zano!.getZanoAssets(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
tokens.addAll(zano!
.getZanoAssets(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
}

View file

@ -102,7 +102,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
outputs
.add(Output(wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
unspentCoinsListViewModel.initialSetup();
unspentCoinsListViewModel.initialSetup().then((_) {
unspentCoinsListViewModel.resetUnspentCoinsInfoSelections();
});
}
@observable
@ -728,11 +730,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return S.current.insufficient_funds_for_tx;
}
return
'''${S.current.insufficient_funds_for_tx} \n\n'''
'''${S.current.balance}: ${parsedErrorMessageResult.balanceEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.balanceUsd} ${fiatFromSettings.name})\n\n'''
'''${S.current.transaction_cost}: ${parsedErrorMessageResult.txCostEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.txCostUsd} ${fiatFromSettings.name})\n\n'''
'''${S.current.overshot}: ${parsedErrorMessageResult.overshotEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.overshotUsd} ${fiatFromSettings.name})''';
return '''${S.current.insufficient_funds_for_tx} \n\n'''
'''${S.current.balance}: ${parsedErrorMessageResult.balanceEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.balanceUsd} ${fiatFromSettings.name})\n\n'''
'''${S.current.transaction_cost}: ${parsedErrorMessageResult.txCostEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.txCostUsd} ${fiatFromSettings.name})\n\n'''
'''${S.current.overshot}: ${parsedErrorMessageResult.overshotEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.overshotUsd} ${fiatFromSettings.name})''';
}
return errorMessage;
@ -809,4 +810,4 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return false;
}
}
}

View file

@ -1,16 +1,19 @@
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/settings/link_list_item.dart';
import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
part 'support_view_model.g.dart';
class SupportViewModel = SupportViewModelBase with _$SupportViewModel;
abstract class SupportViewModelBase with Store {
SupportViewModelBase()
final SettingsStore settingsStore;
SupportViewModelBase(this.settingsStore)
: items = [
LinkListItem(
title: 'Email',
@ -116,5 +119,8 @@ abstract class SupportViewModelBase with Store {
return supportUrl;
}
String get appVersion =>
"${isMoneroOnly ? "Monero.com" : "Cake Wallet"} - ${settingsStore.appVersion}";
List<SettingsListItem> items;
}

View file

@ -68,7 +68,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
bool get hasAdjustableFieldChanged => items.any(_hasAdjustableFieldChanged);
Future<void> saveUnspentCoinInfo(UnspentCoinsItem item) async {
try {
final existingInfo = _unspentCoinsInfo.values
@ -79,7 +78,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
existingInfo.isSending = item.isSending;
existingInfo.note = item.note;
await existingInfo.save();
_updateUnspentCoinsInfo();
} catch (e) {
@ -167,6 +165,17 @@ abstract class UnspentCoinsListViewModelBase with Store {
items.addAll(unspents);
}
@action
void resetUnspentCoinsInfoSelections() {
// reset all unspent coins selections to true except frozen ones
for (final item in items) {
if (!item.isFrozen) {
item.isSending = true;
saveUnspentCoinInfo(item);
}
}
}
@action
void toggleSelectAll(bool value) {
for (final item in items) {

View file

@ -26,14 +26,14 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_i
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/amount_converter.dart';
import 'package:cw_core/currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:intl/intl.dart';
import 'package:mobx/mobx.dart';
part 'wallet_address_list_view_model.g.dart';
class WalletAddressListViewModel = WalletAddressListViewModelBase
with _$WalletAddressListViewModel;
class WalletAddressListViewModel = WalletAddressListViewModelBase with _$WalletAddressListViewModel;
abstract class PaymentURI {
PaymentURI({required this.amount, required this.address});
@ -222,9 +222,7 @@ class ZanoURI extends PaymentURI {
}
}
abstract class WalletAddressListViewModelBase
extends WalletChangeListenerViewModel with Store {
abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewModel with Store {
WalletAddressListViewModelBase({
required AppStore appStore,
required this.yatStore,
@ -245,8 +243,7 @@ abstract class WalletAddressListViewModelBase
_init();
selectedCurrency = walletTypeToCryptoCurrency(wallet.type);
hasAccounts = [WalletType.monero, WalletType.wownero, WalletType.haven]
.contains(wallet.type);
hasAccounts = [WalletType.monero, WalletType.wownero, WalletType.haven].contains(wallet.type);
}
static const String _cryptoNumberPattern = '0.00000000';
@ -259,8 +256,7 @@ abstract class WalletAddressListViewModelBase
double? _fiatRate;
String _rawAmount = '';
List<Currency> get currencies =>
[walletTypeToCryptoCurrency(wallet.type), ...FiatCurrency.all];
List<Currency> get currencies => [walletTypeToCryptoCurrency(wallet.type), ...FiatCurrency.all];
String get buttonTitle {
if (isElectrumWallet) {
@ -286,8 +282,8 @@ abstract class WalletAddressListViewModelBase
WalletType get type => wallet.type;
@computed
WalletAddressListItem get address => WalletAddressListItem(
address: wallet.walletAddresses.address, isPrimary: false);
WalletAddressListItem get address =>
WalletAddressListItem(address: wallet.walletAddresses.address, isPrimary: false);
@computed
PaymentURI get uri {
@ -317,25 +313,23 @@ abstract class WalletAddressListViewModelBase
case WalletType.wownero:
return WowneroURI(amount: amount, address: address.address);
case WalletType.zano:
return ZanoURI(amount: amount, address: address.address);
return ZanoURI(amount: amount, address: address.address);
case WalletType.none:
throw Exception('Unexpected type: ${type.toString()}');
}
}
@computed
ObservableList<ListItem> get items => ObservableList<ListItem>()
..addAll(_baseItems)
..addAll(addressList);
@computed
ObservableList<ListItem> get addressList {
ObservableList<ListItem> _computeAddressList() {
final addressList = ObservableList<ListItem>();
if (wallet.type == WalletType.monero) {
final primaryAddress =
monero!.getSubaddressList(wallet).subaddresses.first;
final addressItems =
monero!.getSubaddressList(wallet).subaddresses.map((subaddress) {
final primaryAddress = monero!.getSubaddressList(wallet).subaddresses.first;
final addressItems = monero!.getSubaddressList(wallet).subaddresses.map((subaddress) {
final isPrimary = subaddress == primaryAddress;
return WalletAddressListItem(
@ -351,10 +345,8 @@ abstract class WalletAddressListViewModelBase
}
if (wallet.type == WalletType.wownero) {
final primaryAddress =
wownero!.getSubaddressList(wallet).subaddresses.first;
final addressItems =
wownero!.getSubaddressList(wallet).subaddresses.map((subaddress) {
final primaryAddress = wownero!.getSubaddressList(wallet).subaddresses.first;
final addressItems = wownero!.getSubaddressList(wallet).subaddresses.map((subaddress) {
final isPrimary = subaddress == primaryAddress;
return WalletAddressListItem(
@ -367,10 +359,8 @@ abstract class WalletAddressListViewModelBase
}
if (wallet.type == WalletType.haven) {
final primaryAddress =
haven!.getSubaddressList(wallet).subaddresses.first;
final addressItems =
haven!.getSubaddressList(wallet).subaddresses.map((subaddress) {
final primaryAddress = haven!.getSubaddressList(wallet).subaddresses.first;
final addressItems = haven!.getSubaddressList(wallet).subaddresses.map((subaddress) {
final isPrimary = subaddress == primaryAddress;
return WalletAddressListItem(
@ -384,8 +374,7 @@ abstract class WalletAddressListViewModelBase
if (isElectrumWallet) {
if (bitcoin!.hasSelectedSilentPayments(wallet)) {
final addressItems =
bitcoin!.getSilentPaymentAddresses(wallet).map((address) {
final addressItems = bitcoin!.getSilentPaymentAddresses(wallet).map((address) {
final isPrimary = address.id == 0;
return WalletAddressListItem(
@ -436,8 +425,7 @@ abstract class WalletAddressListViewModelBase
if (wallet.type == WalletType.litecoin && addressItems.length >= 1000) {
// find the index of the last item with a txCount > 0
final addressItemsList = addressItems.toList();
int index = addressItemsList
.lastIndexWhere((item) => (item.txCount ?? 0) > 0);
int index = addressItemsList.lastIndexWhere((item) => (item.txCount ?? 0) > 0);
if (index == -1) {
index = 0;
}
@ -451,22 +439,19 @@ abstract class WalletAddressListViewModelBase
if (wallet.type == WalletType.ethereum) {
final primaryAddress = ethereum!.getAddress(wallet);
addressList.add(WalletAddressListItem(
isPrimary: true, name: null, address: primaryAddress));
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
if (wallet.type == WalletType.polygon) {
final primaryAddress = polygon!.getAddress(wallet);
addressList.add(WalletAddressListItem(
isPrimary: true, name: null, address: primaryAddress));
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
if (wallet.type == WalletType.solana) {
final primaryAddress = solana!.getAddress(wallet);
addressList.add(WalletAddressListItem(
isPrimary: true, name: null, address: primaryAddress));
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
if (wallet.type == WalletType.nano) {
@ -480,21 +465,18 @@ abstract class WalletAddressListViewModelBase
if (wallet.type == WalletType.tron) {
final primaryAddress = tron!.getAddress(wallet);
addressList.add(WalletAddressListItem(
isPrimary: true, name: null, address: primaryAddress));
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
for (var i = 0; i < addressList.length; i++) {
if (!(addressList[i] is WalletAddressListItem)) continue;
(addressList[i] as WalletAddressListItem).isHidden = wallet
.walletAddresses.hiddenAddresses
(addressList[i] as WalletAddressListItem).isHidden = wallet.walletAddresses.hiddenAddresses
.contains((addressList[i] as WalletAddressListItem).address);
}
for (var i = 0; i < addressList.length; i++) {
if (!(addressList[i] is WalletAddressListItem)) continue;
(addressList[i] as WalletAddressListItem).isManual = wallet
.walletAddresses.manualAddresses
(addressList[i] as WalletAddressListItem).isManual = wallet.walletAddresses.manualAddresses
.contains((addressList[i] as WalletAddressListItem).address);
}
@ -516,13 +498,28 @@ abstract class WalletAddressListViewModelBase
return addressList;
}
@computed
ObservableList<ListItem> get addressList {
return _computeAddressList();
}
List<ListItem> get forceRecomputeItems {
// necessary because the addressList contains non-observable items
List<ListItem> recomputed = [];
recomputed.addAll(_baseItems);
recomputed.addAll(_computeAddressList());
return recomputed;
}
Future<void> toggleHideAddress(WalletAddressListItem item) async {
if (item.isHidden) {
wallet.walletAddresses.hiddenAddresses
.removeWhere((element) => element == item.address);
item.isHidden = false;
wallet.walletAddresses.hiddenAddresses.removeWhere((element) => element == item.address);
} else {
item.isHidden = true;
wallet.walletAddresses.hiddenAddresses.add(item.address);
}
// update the address list:
await wallet.walletAddresses.saveAddressesInBox();
if (wallet.type == WalletType.monero) {
monero!
@ -568,28 +565,22 @@ abstract class WalletAddressListViewModelBase
].contains(wallet.type);
@computed
bool get isElectrumWallet => [
WalletType.bitcoin,
WalletType.litecoin,
WalletType.bitcoinCash
].contains(wallet.type);
bool get isElectrumWallet =>
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(wallet.type);
@computed
bool get isBalanceAvailable => isElectrumWallet;
@computed
bool get isReceivedAvailable =>
[WalletType.monero, WalletType.wownero].contains(wallet.type);
bool get isReceivedAvailable => [WalletType.monero, WalletType.wownero].contains(wallet.type);
@computed
bool get isSilentPayments =>
wallet.type == WalletType.bitcoin &&
bitcoin!.hasSelectedSilentPayments(wallet);
wallet.type == WalletType.bitcoin && bitcoin!.hasSelectedSilentPayments(wallet);
@computed
bool get isAutoGenerateSubaddressEnabled =>
_settingsStore.autoGenerateSubaddressStatus !=
AutoGenerateSubaddressStatus.disabled &&
_settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled &&
!isSilentPayments;
@computed
@ -672,8 +663,7 @@ abstract class WalletAddressListViewModelBase
@action
void _convertAmountToCrypto() {
final cryptoCurrency = walletTypeToCryptoCurrency(wallet.type);
final fiatRate =
_fiatRate ?? (fiatConversionStore.prices[cryptoCurrency] ?? 0.0);
final fiatRate = _fiatRate ?? (fiatConversionStore.prices[cryptoCurrency] ?? 0.0);
if (fiatRate <= 0.0) {
dev.log("Invalid Fiat Rate $fiatRate");

View file

@ -175,7 +175,7 @@
"contact_name_exists": " .ﻒﻠﺘﺨﻣ ﻢﺳﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ .ﻞﻌﻔﻟﺎﺑ ﺓﺩﻮﺟﻮﻣ ﻢﺳﻻﺍ ﺍﺬﻬﺑ ﻝﺎﺼﺗﺍ ﺔﻬﺟ",
"contact_support": "اتصل بالدعم",
"continue_text": "التالي",
"contract_warning": "تم وضع علامة على عنوان العقد هذا على أنه احتيالي محتمل. يرجى المعالجة بحذر.",
"contract_warning": "تم وضع علامة على عنوان العقد هذا على أنه احتيالي محتمل. يرجى المتابعة بحذر.",
"contractName": "ﺪﻘﻌﻟﺍ ﻢﺳﺍ",
"contractSymbol": "ﺪﻘﻌﻟﺍ ﺰﻣﺭ",
"copied_key_to_clipboard": "تم نسخ ${key} إلى الحافظة",
@ -437,6 +437,7 @@
"monero_light_theme": " ضوء مونيرو",
"moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}",
"more_options": "المزيد من الخيارات",
"multiple_addresses_detected": "عناوين متعددة تم اكتشافها",
"mweb_confirmed": "أكد MWEB",
"mweb_unconfirmed": "غير مؤكد MWEB",
"name": "ﻢﺳﺍ",
@ -513,6 +514,7 @@
"pin_number": "الرقم السري",
"placeholder_contacts": "سيتم عرض جهات الاتصال الخاصة بك هنا",
"placeholder_transactions": "سيتم عرض معاملاتك هنا",
"please_choose_one": "الرجاء اختيار واحد",
"please_fill_totp": "يرجى ملء الرمز المكون من 8 أرقام الموجود على جهازك الآخر",
"please_make_selection": "يرجى الأختيار لإنشاء أو استعادة محفظتك.",
"please_reference_document": "يرجى الرجوع إلى الوثائق أدناه لمزيد من المعلومات.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Вече съществува контакт с това име. Моля, изберете друго име.",
"contact_support": "Свържи се с отдел поддръжка",
"continue_text": "Напред",
"contract_warning": "Този адрес на договора е маркиран като потенциално измамник. Моля, обработете с повишено внимание.",
"contract_warning": "Този адрес на договора е маркиран като потенциално измамник. Моля, продължете с повишено внимание.",
"contractName": "Име на договора",
"contractSymbol": "Договор Символ",
"copied_key_to_clipboard": "Копиран ключ: ${key}",
@ -437,6 +437,7 @@
"monero_light_theme": "Лека тема Monero",
"moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}",
"more_options": "Още настройки",
"multiple_addresses_detected": "Открити множество адреси",
"mweb_confirmed": "Потвърден MWeb",
"mweb_unconfirmed": "Непотвърден mweb",
"name": "Име",
@ -513,6 +514,7 @@
"pin_number": "PIN код",
"placeholder_contacts": "Вашите контакти ще се покажат тук",
"placeholder_transactions": "Вашите транзакции ще се покажат тук",
"please_choose_one": "Моля, изберете един",
"please_fill_totp": "Моля, попълнете 8-цифрения код на другото ви устройство",
"please_make_selection": "Моля, изберете отдолу за създаване или възстановяване на портфейл.",
"please_reference_document": "Моля, вижте документите по-долу за повече информация.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Kontakt s tímto jménem již existuje. Vyberte prosím jiný název.",
"contact_support": "Kontaktovat podporu",
"continue_text": "Pokračovat",
"contract_warning": "Tato adresa smlouvy byla označena jako potenciálně podvodná. Zpracovejte prosím opatrně.",
"contract_warning": "Tato adresa smlouvy byla označena jako potenciálně podvodná. Pokračujte opatrně.",
"contractName": "Název smlouvy",
"contractSymbol": "Symbol smlouvy",
"copied_key_to_clipboard": "Zkopírován ${key} do schránky",
@ -437,6 +437,7 @@
"monero_light_theme": "Světlé téma Monero",
"moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}",
"more_options": "Více možností",
"multiple_addresses_detected": "Detekované více adres",
"mweb_confirmed": "Potvrzený mweb",
"mweb_unconfirmed": "Nepotvrzené mWeb",
"name": "název",
@ -513,6 +514,7 @@
"pin_number": "Číslo PIN",
"placeholder_contacts": "Vaše kontakty budou zobrazeny zde",
"placeholder_transactions": "Vaše transakce budou zobrazeny zde",
"please_choose_one": "Vyberte si prosím jeden",
"please_fill_totp": "Vyplňte prosím 8místný kód na vašem druhém zařízení",
"please_make_selection": "Prosím vyberte si níže, jestli chcete vytvořit, nebo obnovit peněženku.",
"please_reference_document": "Více informací naleznete v dokumentu níže.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Ein Kontakt mit diesem Namen besteht bereits. Bitte wählen Sie einen anderen Namen.",
"contact_support": "Support kontaktieren",
"continue_text": "Weiter",
"contract_warning": "Diese Contract Adresse wurde als potenziell betrügerisch gekennzeichnet. Bitte fahren Sie mit Vorsicht fort.",
"contract_warning": "Diese Vertragsadresse wurde als potenziell betrügerisch gekennzeichnet. Bitte gehen Sie mit Vorsicht vor.",
"contractName": "Contract-Name",
"contractSymbol": "Contract-Symbol",
"copied_key_to_clipboard": "${key} in Zwischenablage kopiert",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero Light-Thema",
"moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein",
"more_options": "Weitere Optionen",
"multiple_addresses_detected": "Mehrere Adressen erkannt",
"mweb_confirmed": "Bestätigt MWeb",
"mweb_unconfirmed": "Unbestätigter MWeb",
"name": "Name",
@ -513,6 +514,7 @@
"pin_number": "PIN-Nummer",
"placeholder_contacts": "Ihre Kontakte werden hier angezeigt",
"placeholder_transactions": "Ihre Transaktionen werden hier angezeigt",
"please_choose_one": "Bitte wählen Sie einen",
"please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist",
"please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.",
"please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "A contact with that name already exists. Please choose a different name.",
"contact_support": "Contact Support",
"continue_text": "Continue",
"contract_warning": "This contract address has been flagged as potentially fraudulent. Please process with caution.",
"contract_warning": "This contract address has been flagged as potentially fraudulent. Please proceed with caution.",
"contractName": "Contract Name",
"contractSymbol": "Contract Symbol",
"copied_key_to_clipboard": "Copied ${key} to Clipboard",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero Light Theme",
"moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}",
"more_options": "More Options",
"multiple_addresses_detected": "Multiple addresses detected",
"mweb_confirmed": "Confirmed MWEB",
"mweb_unconfirmed": "Unconfirmed MWEB",
"name": "Name",
@ -514,6 +515,7 @@
"pin_number": "PIN number",
"placeholder_contacts": "Your contacts will be displayed here",
"placeholder_transactions": "Your transactions will be displayed here",
"please_choose_one": "Please choose one",
"please_fill_totp": "Please fill in the 8-digit code present on your other device",
"please_make_selection": "Please make a selection below to create or recover your wallet.",
"please_reference_document": "Please reference the documents below for more information.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Ya existe un contacto con ese nombre. Elija un nombre diferente.",
"contact_support": "Contactar con Soporte",
"continue_text": "Continuar",
"contract_warning": "Esta dirección de contrato ha sido marcada como potencialmente fraudulenta. Por favor, procese con precaución.",
"contract_warning": "Esta dirección de contrato ha sido marcada como potencialmente fraudulenta. Proceda con precaución.",
"contractName": "Nombre del contrato",
"contractSymbol": "Símbolo de contrato",
"copied_key_to_clipboard": "Copiado ${key} al portapapeles",
@ -437,6 +437,7 @@
"monero_light_theme": "Tema ligero de Monero",
"moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}",
"more_options": "Más Opciones",
"multiple_addresses_detected": "Múltiples direcciones detectadas",
"mweb_confirmed": "Confirmado mweb",
"mweb_unconfirmed": "Mweb no confirmado",
"name": "Nombre",
@ -514,6 +515,7 @@
"pin_number": "Número PIN",
"placeholder_contacts": "Tus contactos se mostrarán aquí",
"placeholder_transactions": "Tus transacciones se mostrarán aquí",
"please_choose_one": "Elija uno",
"please_fill_totp": "Completa el código de 8 dígitos presente en su otro dispositivo",
"please_make_selection": "Selecciona a continuación para crear o recuperar su billetera.",
"please_reference_document": "Consulta los documentos a continuación para obtener más información.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Un contact portant ce nom existe déjà. Veuillez choisir un autre nom.",
"contact_support": "Contacter l'assistance",
"continue_text": "Continuer",
"contract_warning": "Cette adresse contractuelle a été signalée comme potentiellement frauduleuse. Veuillez traiter avec prudence.",
"contract_warning": "Cette adresse contractuelle a été signalée comme potentiellement frauduleuse. Veuillez procéder avec prudence.",
"contractName": "Nom du contrat",
"contractSymbol": "Symbole du contrat",
"copied_key_to_clipboard": "${key} copiée vers le presse-papier",
@ -437,6 +437,7 @@
"monero_light_theme": "Thème de lumière Monero",
"moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}",
"more_options": "Plus d'options",
"multiple_addresses_detected": "Plusieurs adresses détectées",
"mweb_confirmed": "Confirmé MWEB",
"mweb_unconfirmed": "Mweb non confirmé",
"name": "Nom",
@ -513,6 +514,7 @@
"pin_number": "Numéro PIN",
"placeholder_contacts": "Vos contacts apparaîtront ici",
"placeholder_transactions": "Vos transactions apparaîtront ici",
"please_choose_one": "Veuillez en choisir un",
"please_fill_totp": "Veuillez renseigner le code à 8 chiffres affiché sur votre autre appareil",
"please_make_selection": "Merci de faire un choix ci-dessous pour créer ou restaurer votre portefeuille (wallet).",
"please_reference_document": "Veuillez vous référer aux documents ci-dessous pour plus d'informations.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "An riga an sami lamba tare da wannan sunan. Da fatan za a zaɓi suna daban.",
"contact_support": "Tuntuɓi Support",
"continue_text": "Ci gaba",
"contract_warning": "An kafa wannan adireshin kwantaragin kwangilar yayin da yuwuwar zamba. Da fatan za a aiwatar da taka tsantsan.",
"contract_warning": "An kafa wannan adireshin kwantaragin kwangilar yayin da yuwuwar zamba. Da fatan za a ci gaba da taka tsantsan.",
"contractName": "Sunan Kwangila",
"contractSymbol": "Alamar Kwangila",
"copied_key_to_clipboard": "An kwafa ${key} a cikin kwafin",
@ -437,6 +437,7 @@
"monero_light_theme": "Jigon Hasken Monero",
"moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}",
"more_options": "Ƙarin Zaɓuɓɓuka",
"multiple_addresses_detected": "An gano adiresoshin da aka gano",
"mweb_confirmed": "Tabbatar da Mweb",
"mweb_unconfirmed": "Myconfired",
"name": "Suna",
@ -515,6 +516,7 @@
"pin_number": "Lambar PIN",
"placeholder_contacts": "Za a nuna lambobin sadarwar ku anan",
"placeholder_transactions": "Za a nuna ma'amalolin ku anan",
"please_choose_one": "Da fatan za a zabi ɗaya",
"please_fill_totp": "Da fatan za a cika lambar lambobi 8 da ke yanzu a kan sauran na'urarku",
"please_make_selection": "Don Allah zaɓi ƙasa don ƙirƙira ko dawo da kwalinku.",
"please_reference_document": "Da fatan za a nemi takaddun da ke ƙasa don ƙarin bayani.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "उस नाम का एक संपर्क पहले से मौजूद है. कृपया कोई भिन्न नाम चुनें.",
"contact_support": "सहायता से संपर्क करें",
"continue_text": "जारी रहना",
"contract_warning": "इस अनुबंध के पते को संभावित रूप से धोखाधड़ी के रूप में चिह्नित किया गया है। कृपया सावधानी के साथ प्रक्रिया करें।",
"contract_warning": "इस अनुबंध के पते को संभावित रूप से धोखाधड़ी के रूप में चिह्नित किया गया है। कृपया सावधानी के साथ आगे बढ़ें।",
"contractName": "अनुबंध का नाम",
"contractSymbol": "अनुबंध चिह्न",
"copied_key_to_clipboard": "की नकल की ${key} क्लिपबोर्ड पर",
@ -437,6 +437,7 @@
"monero_light_theme": "मोनेरो लाइट थीम",
"moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}",
"more_options": "और विकल्प",
"multiple_addresses_detected": "कई पते का पता चला",
"mweb_confirmed": "MWEB की पुष्टि की",
"mweb_unconfirmed": "अपुष्ट MWEB",
"name": "नाम",
@ -505,8 +506,8 @@
"paste": "पेस्ट करें",
"pause_wallet_creation": "हेवन वॉलेट बनाने की क्षमता फिलहाल रुकी हुई है।",
"payment_id": "भुगतान ID: ",
"Payment_was_received": "आपका भुगतान प्राप्त हो गया था।",
"payment_was_received": "आपका भुगतान प्राप्त हुआ था।",
"Payment_was_received": "आपका भुगतान प्राप्त हो गया था।",
"pending": " (अपूर्ण)",
"percentageOf": "${amount} का",
"pin_at_top": "शीर्ष पर ${token} पिन करें",
@ -514,6 +515,7 @@
"pin_number": "पिन नंबर",
"placeholder_contacts": "आपके संपर्क यहां प्रदर्शित होंगे",
"placeholder_transactions": "आपके लेनदेन यहां प्रदर्शित होंगे",
"please_choose_one": "एक का चयन करें",
"please_fill_totp": "कृपया अपने दूसरे डिवाइस पर मौजूद 8 अंकों का कोड भरें",
"please_make_selection": "कृपया नीचे चयन करें अपना बटुआ बनाएं या पुनर्प्राप्त करें.",
"please_reference_document": "कृपया अधिक जानकारी के लिए नीचे दिए गए दस्तावेज़ देखें।",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Kontakt s tim imenom već postoji. Odaberite drugo ime.",
"contact_support": "Kontaktirajte podršku",
"continue_text": "Nastavak",
"contract_warning": "Ova adresa ugovora označena je kao potencijalno lažna. Molimo obradite s oprezom.",
"contract_warning": "Ova adresa ugovora označena je kao potencijalno lažna. Molimo nastavite s oprezom.",
"contractName": "Naziv ugovora",
"contractSymbol": "Simbol ugovora",
"copied_key_to_clipboard": "${key} kopiran u međuspremnik",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero lagana tema",
"moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}",
"more_options": "Više opcija",
"multiple_addresses_detected": "Otkrivene više adresa",
"mweb_confirmed": "Potvrđen MWeb",
"mweb_unconfirmed": "Nepotvrđeni mWeb",
"name": "Ime",
@ -513,6 +514,7 @@
"pin_number": "PIN broj",
"placeholder_contacts": "Vaši će kontakti biti prikazani ovdje",
"placeholder_transactions": "Vaše će transakcije biti prikazane ovdje",
"please_choose_one": "Molimo odaberite jedan",
"please_fill_totp": "Unesite 8-znamenkasti kod koji se nalazi na vašem drugom uređaju",
"please_make_selection": "Molimo odaberite opcije niže za izradu novog novčanika ili za oporavak postojećeg.",
"please_reference_document": "Molimo pogledajte dokumente ispod za više informacija.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Այդ անվանման հետ կապ կա արդեն: Խնդրում ենք ընտրել այլ անուն:",
"contact_support": "Հետադարձ կապ",
"continue_text": "Շարունակել",
"contract_warning": "Պայմանագրի այս հասցեն դրոշմել է որպես հնարավոր կեղծ: Խնդրում ենք զգուշությամբ մշակել:",
"contract_warning": "Պայմանագրի այս հասցեն դրոշմել է որպես հնարավոր կեղծ: Խնդրում ենք զգուշությամբ շարունակեք:",
"contractName": "Գործարքի անուն",
"contractSymbol": "Գործարքի Նշան",
"copied_key_to_clipboard": "${key} պատճենված է տեքստի բուֆերում",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero պայծառ տեսք",
"moonpay_alert_text": "Գումարի արժեքը պետք է լինի հավասար կամ ավելի քան ${minAmount} ${fiatCurrency}",
"more_options": "Այլ տարբերակներ",
"multiple_addresses_detected": "Հայտնաբերվել են բազմաթիվ հասցեներ",
"mweb_confirmed": "Հաստատված MWEB",
"mweb_unconfirmed": "Չկարգավորված Mweb",
"name": "Անուն",
@ -513,6 +514,7 @@
"pin_number": "Պին-կոդ",
"placeholder_contacts": "Ձեր կոնտակտները այստեղ կցուցադրվեն",
"placeholder_transactions": "Ձեր գործարքները այստեղ կցուցադրվեն",
"please_choose_one": "Խնդրում ենք ընտրել մեկը",
"please_fill_totp": "Խնդրում ենք լրացնել 8-նիշյա կոդը, որը կա ձեր այլ սարքի վրա",
"please_make_selection": "Խնդրում ենք ընտրություն կատարել ներքևում ձեր դրամապանակը ստեղծելու կամ վերականգնելու համար",
"please_reference_document": "Խնդրում ենք դիտել ներքևի փաստաթղթերը ավելի շատ տեղեկատվության համար",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Kontak dengan nama tersebut sudah ada. Silakan pilih nama lain.",
"contact_support": "Hubungi Dukungan",
"continue_text": "Lanjutkan",
"contract_warning": "Alamat kontrak ini telah ditandai sebagai berpotensi curang. Silakan memproses dengan hati -hati.",
"contract_warning": "Alamat kontrak ini telah ditandai sebagai berpotensi curang. Silakan lanjutkan dengan hati -hati.",
"contractName": "Nama Kontrak",
"contractSymbol": "Simbol Kontrak",
"copied_key_to_clipboard": "Kunci ${key} disalin ke Clipboard",
@ -437,6 +437,7 @@
"monero_light_theme": "Tema Cahaya Monero",
"moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}",
"more_options": "Opsi Lainnya",
"multiple_addresses_detected": "Banyak alamat terdeteksi",
"mweb_confirmed": "Mengkonfirmasi mWeb",
"mweb_unconfirmed": "MWEB yang belum dikonfirmasi",
"name": "Nama",
@ -515,6 +516,7 @@
"pin_number": "Nomor PIN",
"placeholder_contacts": "Kontak Anda akan ditampilkan di sini",
"placeholder_transactions": "Transaksi Anda akan ditampilkan di sini",
"please_choose_one": "Pilih satu",
"please_fill_totp": "Harap isi kode 8 digit yang ada di perangkat Anda yang lain",
"please_make_selection": "Silahkan membuat pilihan di bawah ini untuk membuat atau memulihkan dompet Anda.",
"please_reference_document": "Silakan referensikan dokumen di bawah ini untuk informasi lebih lanjut.",

File diff suppressed because it is too large Load diff

View file

@ -175,7 +175,7 @@
"contact_name_exists": "その名前の連絡先はすでに存在します。別の名前を選択してください。",
"contact_support": "サポートに連絡する",
"continue_text": "持続する",
"contract_warning": "この契約住所は、潜在的に不正としてフラグが立てられています。注意して処理してください。",
"contract_warning": "この契約住所は、潜在的に不正としてフラグが立てられています。注意して進めてください。",
"contractName": "契約名",
"contractSymbol": "契約記号",
"copied_key_to_clipboard": "コピー済み ${key} クリップボードへ",
@ -438,6 +438,7 @@
"monero_light_theme": "モネロ ライト テーマ",
"moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}",
"more_options": "その他のオプション",
"multiple_addresses_detected": "複数のアドレスが検出されました",
"mweb_confirmed": "確認されたMWEB",
"mweb_unconfirmed": "未確認のMWEB",
"name": "名前",
@ -514,6 +515,7 @@
"pin_number": "PIN番号",
"placeholder_contacts": "連絡先はここに表示されます",
"placeholder_transactions": "あなたの取引はここに表示されます",
"please_choose_one": "選択してください",
"please_fill_totp": "他のデバイスにある 8 桁のコードを入力してください",
"please_make_selection": "以下を選択してください ウォレットを作成または回復する.",
"please_reference_document": "詳細については、以下のドキュメントを参照してください。",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "해당 이름을 가진 연락처가 이미 존재합니다. 다른 이름을 선택하세요.",
"contact_support": "지원팀에 문의",
"continue_text": "잇다",
"contract_warning": "이 계약 주소는 잠재적으로 사기성으로 표시되었습니다. 주의해서 처리하십시오.",
"contract_warning": "이 계약 주소는 잠재적으로 사기성으로 표시되었습니다. 주의해서 계속 진행하십시오.",
"contractName": "계약명",
"contractSymbol": "계약 기호",
"copied_key_to_clipboard": "복사 ${key} 클립 보드로",
@ -437,6 +437,7 @@
"monero_light_theme": "모네로 라이트 테마",
"moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}",
"more_options": "추가 옵션",
"multiple_addresses_detected": "여러 주소가 감지되었습니다",
"mweb_confirmed": "확인 mweb",
"mweb_unconfirmed": "확인되지 않은 mweb",
"name": "이름",
@ -513,6 +514,7 @@
"pin_number": "PIN 번호",
"placeholder_contacts": "연락처가 여기에 표시됩니다",
"placeholder_transactions": "거래가 여기에 표시됩니다",
"please_choose_one": "하나를 선택하십시오",
"please_fill_totp": "다른 기기에 있는 8자리 코드를 입력하세요.",
"please_make_selection": "아래에서 선택하십시오 지갑 만들기 또는 복구.",
"please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "ထိုအမည်နှင့် အဆက်အသွယ်တစ်ခု ရှိနှင့်ပြီးဖြစ်သည်။ အခြားအမည်တစ်ခုကို ရွေးပါ။",
"contact_support": "ပံ့ပိုးကူညီမှုထံ ဆက်သွယ်ပါ။",
"continue_text": "ဆက်လက်",
"contract_warning": "ဒီစာချုပ်လိပ်စာအလားအလာအလားအလာအလားအလာအလံများကိုအလံလွှင့်တင်ခဲ့သည်။ ကျေးဇူးပြုပြီးသတိဖြင့်လုပ်ငန်းစဉ်။",
"contract_warning": "ဒီစာချုပ်လိပ်စာအလားအလာအလားအလာအလားအလာအလံများကိုအလံလွှင့်တင်ခဲ့သည်။ ကျေးဇူးပြု. သတိဖြင့်ဆက်လက်လုပ်ဆောင်ပါ။",
"contractName": "စာချုပ်အမည်",
"contractSymbol": "စာချုပ်သင်္ကေတ",
"copied_key_to_clipboard": "${key} ကို Clipboard သို့ ကူးယူထားသည်။",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero Light အပြင်အဆင်",
"moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်",
"more_options": "နောက်ထပ် ရွေးချယ်စရာများ",
"multiple_addresses_detected": "အများအပြားလိပ်စာများရှာဖွေတွေ့ရှိ",
"mweb_confirmed": "အတည်ပြုလိုက် mweb",
"mweb_unconfirmed": "အတည်မပြုနိုင်သော mweb",
"name": "နာမည်",
@ -513,6 +514,7 @@
"pin_number": "လျှို့ဝှက်နံပါတ်",
"placeholder_contacts": "သင့်အဆက်အသွယ်များကို ဤနေရာတွင် ပြသပါမည်။",
"placeholder_transactions": "သင်၏ ငွေပေးငွေယူများကို ဤနေရာတွင် ပြသပါမည်။",
"please_choose_one": "ကျေးဇူးပြု. ရွေးပါ",
"please_fill_totp": "သင့်အခြားစက်တွင်ရှိသော ဂဏန်း ၈ လုံးကုဒ်ကို ကျေးဇူးပြု၍ ဖြည့်ပါ။",
"please_make_selection": "သင့်ပိုက်ဆံအိတ်ကို ဖန်တီးရန် သို့မဟုတ် ပြန်လည်ရယူရန် အောက်တွင် ရွေးချယ်မှုတစ်ခု ပြုလုပ်ပါ။",
"please_reference_document": "နောက်ထပ်အချက်အလက်များအတွက် အောက်ပါစာရွက်စာတမ်းများကို ကိုးကားပါ။",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Er bestaat al een contact met die naam. Kies een andere naam.",
"contact_support": "Contact opnemen met ondersteuning",
"continue_text": "Doorgaan met",
"contract_warning": "Dit contractadres is gemarkeerd als mogelijk frauduleus. Verwerk met voorzichtigheid.",
"contract_warning": "Dit contractadres is gemarkeerd als mogelijk frauduleus. Ga voorzichtig te werk.",
"contractName": "Contractnaam",
"contractSymbol": "Contractsymbool",
"copied_key_to_clipboard": "Gekopieerd ${key} naar het klembord",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero Light-thema",
"moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}",
"more_options": "Meer opties",
"multiple_addresses_detected": "Meerdere adressen gedetecteerd",
"mweb_confirmed": "Bevestigde MWEB",
"mweb_unconfirmed": "Onbevestigde MWEB",
"name": "Naam",
@ -513,6 +514,7 @@
"pin_number": "PIN-nummer",
"placeholder_contacts": "Je contacten worden hier weergegeven",
"placeholder_transactions": "Uw transacties worden hier weergegeven",
"please_choose_one": "Kies er een",
"please_fill_totp": "Vul de 8-cijferige code in die op uw andere apparaat aanwezig is",
"please_make_selection": "Maak hieronder uw keuze tot maak of herstel je portemonnee.",
"please_reference_document": "Raadpleeg de onderstaande documenten voor meer informatie.",

View file

@ -437,6 +437,7 @@
"monero_light_theme": "Lekki motyw Monero",
"moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}",
"more_options": "Więcej opcji",
"multiple_addresses_detected": "Wykryto wiele adresów",
"mweb_confirmed": "Potwierdził MWEB",
"mweb_unconfirmed": "Niepotwierdzone MWEB",
"name": "Nazwa",
@ -513,6 +514,7 @@
"pin_number": "Numer PIN",
"placeholder_contacts": "Twoje kontakty zostaną wyświetlone tutaj",
"placeholder_transactions": "Twoje transakcje zostaną wyświetlone tutaj",
"please_choose_one": "Wybierz jeden",
"please_fill_totp": "Wpisz 8-cyfrowy kod znajdujący się na drugim urządzeniu",
"please_make_selection": "Wybierz poniżej, aby utworzyć lub przywrócić swój portfel.",
"please_reference_document": "Proszę odwołać się do poniższych dokumentów, aby uzyskać więcej informacji.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Um contato com esse nome já existe. Escolha um nome diferente.",
"contact_support": "Contatar Suporte",
"continue_text": "Continuar",
"contract_warning": "Este endereço do contrato foi sinalizado como potencialmente fraudulento. Por favor, processe com cautela.",
"contract_warning": "Este endereço do contrato foi sinalizado como potencialmente fraudulento. Por favor, continue com cautela.",
"contractName": "Nome do contrato",
"contractSymbol": "Símbolo do Contrato",
"copied_key_to_clipboard": "${key} copiada para a área de transferência",
@ -438,6 +438,7 @@
"monero_light_theme": "Monero Light Theme",
"moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}",
"more_options": "Mais opções",
"multiple_addresses_detected": "Vários endereços detectados",
"mweb_confirmed": "MWEB confirmado",
"mweb_unconfirmed": "MWEB não confirmado",
"name": "Nome",
@ -515,6 +516,7 @@
"pin_number": "Número PIN",
"placeholder_contacts": "Seus contatos serão exibidos aqui",
"placeholder_transactions": "Suas transações serão exibidas aqui",
"please_choose_one": "Escolha um",
"please_fill_totp": "Por favor, preencha o código de 8 dígitos presente em seu outro dispositivo",
"please_make_selection": "Escolha se quer criar uma carteira nova ou restaurar uma antiga.",
"please_reference_document": "Por favor, consulte os documentos abaixo para mais informações.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Контакт с таким именем уже существует. Пожалуйста, выберите другое имя.",
"contact_support": "Связаться со службой поддержки",
"continue_text": "Продолжить",
"contract_warning": "Этот адрес контракта был отмечен как потенциально мошеннический. Пожалуйста, обработайтесь с осторожностью.",
"contract_warning": "Этот адрес контракта был отмечен как потенциально мошеннический. Пожалуйста, продолжайте с осторожностью.",
"contractName": "Название контракта",
"contractSymbol": "Символ контракта",
"copied_key_to_clipboard": "Скопировано ${key} в буфер обмена",
@ -437,6 +437,7 @@
"monero_light_theme": "Светлая тема Monero",
"moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}",
"more_options": "Дополнительные параметры",
"multiple_addresses_detected": "Обнаружено несколько адресов",
"mweb_confirmed": "Подтверждено MWEB",
"mweb_unconfirmed": "Неподтвержденная MWEB",
"name": "Имя",
@ -514,6 +515,7 @@
"pin_number": "ПИН-код",
"placeholder_contacts": "Ваши контакты будут отображаться здесь",
"placeholder_transactions": "Ваши транзакции будут отображаться здесь",
"please_choose_one": "Пожалуйста, выберите один",
"please_fill_totp": "Пожалуйста, введите 8-значный код на другом устройстве",
"please_make_selection": "Выберите способ создания кошелька: создать новый или восстановить ваш существующий.",
"please_reference_document": "Пожалуйста, обратитесь к документам ниже для получения дополнительной информации.",

View file

@ -437,6 +437,7 @@
"monero_light_theme": "ธีมแสง Monero",
"moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}",
"more_options": "ตัวเลือกเพิ่มเติม",
"multiple_addresses_detected": "ตรวจพบหลายที่อยู่",
"mweb_confirmed": "MWEB ยืนยันแล้ว",
"mweb_unconfirmed": "mweb ที่ไม่ได้รับการยืนยัน",
"name": "ชื่อ",
@ -513,6 +514,7 @@
"pin_number": "หมายเลข PIN",
"placeholder_contacts": "รายชื่อผู้ติดต่อของคุณจะปรากฏที่นี่",
"placeholder_transactions": "ธุรกรรมของคุณจะปรากฏที่นี่",
"please_choose_one": "โปรดเลือกหนึ่ง",
"please_fill_totp": "กรุณากรอกรหัส 8 หลักที่อยู่ในอุปกรณ์อื่นของคุณ",
"please_make_selection": "โปรดเลือกตามด้านล่างเพื่อสร้างหรือกู้กระเป๋าของคุณ",
"please_reference_document": "โปรดอ้างอิงเอกสารด้านล่างสำหรับข้อมูลเพิ่มเติม",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Ang isang pakikipag -ugnay sa pangalang iyon ay mayroon na. Mangyaring pumili ng ibang pangalan.",
"contact_support": "Makipag-ugnay sa Suporta",
"continue_text": "Magpatuloy",
"contract_warning": "Ang address ng kontrata na ito ay na -flag bilang potensyal na mapanlinlang. Mangyaring iproseso nang may pag -iingat.",
"contract_warning": "Ang address ng kontrata na ito ay na -flag bilang potensyal na mapanlinlang. Mangyaring magpatuloy sa pag -iingat.",
"contractName": "Pangalan ng Kontrata",
"contractSymbol": "Simbolo ng Kontrata",
"copied_key_to_clipboard": "Kinopya ang ${key} sa Clipboard",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero Light Theme",
"moonpay_alert_text": "Ang halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}",
"more_options": "Higit pang mga Pagpipilian",
"multiple_addresses_detected": "Maramihang mga address na napansin",
"mweb_confirmed": "Nakumpirma na MWeb",
"mweb_unconfirmed": "Hindi nakumpirma si Mweb",
"name": "Pangalan",
@ -513,6 +514,7 @@
"pin_number": "Numero ng PIN",
"placeholder_contacts": "Ang iyong mga contact ay ipapakita dito",
"placeholder_transactions": "Ang iyong mga transaksyon ay ipapakita dito",
"please_choose_one": "Mangyaring pumili ng isa",
"please_fill_totp": "Mangyaring punan ang 8-digit na code na naroroon sa iyong iba pang device",
"please_make_selection": "Mangyaring gumawa ng isang pagpipilian sa ibaba upang lumikha o mabawi ang iyong wallet.",
"please_reference_document": "Mangyaring sumangguni sa mga dokumento sa ibaba para sa karagdagang impormasyon.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Bu isimde bir kişi zaten mevcut. Lütfen farklı bir ad seçin.",
"contact_support": "Destek ile İletişime Geç",
"continue_text": "Devam et",
"contract_warning": "Bu sözleşme adresi potansiyel olarak hileli olarak işaretlenmiştir. Lütfen dikkatle işleyin.",
"contract_warning": "Bu sözleşme adresi potansiyel olarak hileli olarak işaretlenmiştir. Lütfen dikkatle devam edin.",
"contractName": "Sözleşme Adı",
"contractSymbol": "Sözleşme Sembolü",
"copied_key_to_clipboard": "${key} panoya kopyalandı",
@ -437,6 +437,7 @@
"monero_light_theme": "Monero Hafif Tema",
"moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır",
"more_options": "Daha Fazla Seçenek",
"multiple_addresses_detected": "Birden çok adres tespit edildi",
"mweb_confirmed": "Onaylanmış mweb",
"mweb_unconfirmed": "Doğrulanmamış mweb",
"name": "İsim",
@ -513,6 +514,7 @@
"pin_number": "PIN kodu",
"placeholder_contacts": "Kişilerin burada görüntülenecek",
"placeholder_transactions": "İşlemlerin burada görüntülenecek",
"please_choose_one": "Lütfen bir tane seçin",
"please_fill_totp": "Lütfen diğer cihazınızda bulunan 8 haneli kodu girin",
"please_make_selection": "Cüzdan oluşturmak veya geri döndürmek için aşağıdan seçim yap.",
"please_reference_document": "Daha fazla bilgi için lütfen aşağıdaki belgelere bakınız.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Контакт із такою назвою вже існує. Виберіть інше ім'я.",
"contact_support": "Звернутися до служби підтримки",
"continue_text": "Продовжити",
"contract_warning": "Ця адреса контракту була позначена як потенційно шахрайська. Будь ласка, обробляйте обережно.",
"contract_warning": "Ця адреса контракту була позначена як потенційно шахрайська. Будь ласка, продовжуйте обережно.",
"contractName": "Назва контракту",
"contractSymbol": "Контракт символ",
"copied_key_to_clipboard": "Скопійовано ${key} в буфер обміну",
@ -437,6 +437,7 @@
"monero_light_theme": "Легка тема Monero",
"moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}",
"more_options": "Більше параметрів",
"multiple_addresses_detected": "Виявлено кілька адрес",
"mweb_confirmed": "Підтвердив Mweb",
"mweb_unconfirmed": "Неперевірений MWEB",
"name": "Ім'я",
@ -513,6 +514,7 @@
"pin_number": "PIN-код",
"placeholder_contacts": "Тут будуть показані ваші контакти",
"placeholder_transactions": "Тут відображатимуться ваші транзакції",
"please_choose_one": "Будь ласка, виберіть один",
"please_fill_totp": "Будь ласка, введіть 8-значний код, наявний на вашому іншому пристрої",
"please_make_selection": "Оберіть спосіб створення гаманця: створити новий чи відновити ваш існуючий.",
"please_reference_document": "Для отримання додаткової інформації зверніться до документів нижче.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": " ۔ﮟﯾﺮﮐ ﺐﺨﺘﻨﻣ ﻡﺎﻧ ﻒﻠﺘﺨﻣ ﮏﯾﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ۔ﮯﮨ ﺩﻮﺟﻮﻣ ﮯﺳ ﮯﻠﮩﭘ ﮧﻄﺑﺍﺭ ﮏﯾﺍ ﮫﺗﺎﺳ ﮯﮐ ﻡﺎﻧ ﺱﺍ",
"contact_support": "سپورٹ سے رابطہ کریں۔",
"continue_text": "جاری رہے",
"contract_warning": "اس معاہدے کے پتے کو ممکنہ طور پر جعلی قرار دیا گیا ہے۔ براہ کرم احتیاط کے ساتھ کارروائی کریں۔",
"contract_warning": "اس معاہدے کے پتے کو ممکنہ طور پر جعلی قرار دیا گیا ہے۔ براہ کرم احتیاط کے ساتھ آگے بڑھیں۔",
"contractName": "ﻡﺎﻧ ﺎﮐ ﮦﺪﮨﺎﻌﻣ",
"contractSymbol": "ﺖﻣﻼﻋ ﯽﮐ ﮦﺪﮨﺎﻌﻣ",
"copied_key_to_clipboard": "${key} کو کلپ بورڈ پر کاپی کیا گیا۔",
@ -437,6 +437,7 @@
"monero_light_theme": "مونیرو لائٹ تھیم",
"moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔",
"more_options": "مزید زرائے",
"multiple_addresses_detected": "متعدد پتے کا پتہ چلا",
"mweb_confirmed": "تصدیق شدہ MWEB",
"mweb_unconfirmed": "غیر مصدقہ MWEB",
"name": "ﻡﺎﻧ",
@ -515,6 +516,7 @@
"pin_number": "پن نمبر",
"placeholder_contacts": "آپ کے رابطے یہاں دکھائے جائیں گے۔",
"placeholder_transactions": "آپ کے لین دین یہاں دکھائے جائیں گے۔",
"please_choose_one": "براہ کرم ایک کا انتخاب کریں",
"please_fill_totp": "براہ کرم اپنے دوسرے آلے پر موجود 8 ہندسوں کا کوڈ پُر کریں۔",
"please_make_selection": "اپنا بٹوہ بنانے یا بازیافت کرنے کے لیے براہ کرم ذیل میں ایک انتخاب کریں۔",
"please_reference_document": "مزید معلومات کے لیے براہ کرم نیچے دی گئی دستاویزات کا حوالہ دیں۔",

View file

@ -174,7 +174,7 @@
"contact_name_exists": "Một liên hệ với cái tên đó đã tồn tại. Vui lòng chọn một tên khác.",
"contact_support": "Liên hệ Hỗ trợ",
"continue_text": "Tiếp tục",
"contract_warning": "Địa chỉ hợp đồng này đã được gắn cờ là có khả năng lừa đảo. Vui lòng xử lý một cách thận trọng.",
"contract_warning": "Địa chỉ hợp đồng này đã được gắn cờ là có khả năng lừa đảo. Hãy tiến hành thận trọng.",
"contractName": "Tên Hợp đồng",
"contractSymbol": "Ký hiệu Hợp đồng",
"copied_key_to_clipboard": "Đã sao chép ${key} vào khay nhớ tạm",
@ -436,6 +436,7 @@
"monero_light_theme": "Chủ đề sáng Monero",
"moonpay_alert_text": "Giá trị số tiền phải lớn hơn hoặc bằng ${minAmount} ${fiatCurrency}",
"more_options": "Thêm tùy chọn",
"multiple_addresses_detected": "Nhiều địa chỉ được phát hiện",
"mweb_confirmed": "Xác nhận MWEB",
"mweb_unconfirmed": "MWEB chưa được xác nhận",
"name": "Tên",
@ -512,6 +513,7 @@
"pin_number": "Số PIN",
"placeholder_contacts": "Danh bạ của bạn sẽ được hiển thị ở đây",
"placeholder_transactions": "Giao dịch của bạn sẽ được hiển thị ở đây",
"please_choose_one": "Vui lòng chọn một",
"please_fill_totp": "Vui lòng điền mã 8 chữ số trên thiết bị khác của bạn",
"please_make_selection": "Vui lòng chọn một tùy chọn dưới đây để tạo hoặc khôi phục ví của bạn.",
"please_reference_document": "Vui lòng tham khảo các tài liệu dưới đây để biết thêm thông tin.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "Olubasọrọ pẹlu orukọ yẹn ti wa tẹlẹ. Jọwọ yan orukọ ti o yatọ.",
"contact_support": "Bá ìranlọ́wọ́ sọ̀rọ̀",
"continue_text": "Tẹ̀síwájú",
"contract_warning": "Adirẹsi adehun adehun yii ti samisi bi arekereke. Jọwọ ṣe ilana pẹlu iṣọra.",
"contract_warning": "Adirẹsi adehun adehun yii ti samisi bi arekereke. Jọwọ tẹsiwaju pẹlu iṣọra.",
"contractName": "Orukọ adehun",
"contractSymbol": "Aami adehun",
"copied_key_to_clipboard": "Ti ṣeda ${key} sí àtẹ àkọsílẹ̀",
@ -438,6 +438,7 @@
"monero_light_theme": "Monero Light Akori",
"moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}",
"more_options": "Ìyàn àfikún",
"multiple_addresses_detected": "Awọn adirẹsi ọpọ rii",
"mweb_confirmed": "Jẹrisi Mweb",
"mweb_unconfirmed": "Ajopo Mweb",
"name": "Oruko",
@ -514,6 +515,7 @@
"pin_number": "Òǹkà ìdánimọ̀ àdáni",
"placeholder_contacts": "A máa fihàn àwọn olùbásọ̀rọ̀ yín ḿbí",
"placeholder_transactions": "A máa fihàn àwọn àránṣẹ́ yín ḿbí",
"please_choose_one": "Jọwọ yan ọkan",
"please_fill_totp": "Jọwọ bọ ti ẹrọ ti o wọle ni 8-digits ti o wa ni eto miiran re",
"please_make_selection": "Ẹ jọ̀wọ́, yàn dá àpamọ́wọ́ yín tàbí dá àpamọ́wọ́ yín padà nísàlẹ̀.",
"please_reference_document": "Ẹ jọ̀wọ́ fi àwọn àkọsílẹ̀ lábẹ́ túbọ̀ mọ ìsọfúnni.",

View file

@ -175,7 +175,7 @@
"contact_name_exists": "已存在具有该名称的联系人。请选择不同的名称。",
"contact_support": "联系支持",
"continue_text": "继续",
"contract_warning": "该合同地址已被标记为潜在的欺诈性。请谨慎处理。",
"contract_warning": "该合同地址已被标记为潜在的欺诈性。请谨慎行事。",
"contractName": "合约名称",
"contractSymbol": "合约符号",
"copied_key_to_clipboard": "复制 ${key} 到剪贴板",
@ -437,6 +437,7 @@
"monero_light_theme": "门罗币浅色主题",
"moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}",
"more_options": "更多选项",
"multiple_addresses_detected": "检测到的多个地址",
"mweb_confirmed": "确认的MWEB",
"mweb_unconfirmed": "未经证实的MWEB",
"name": "姓名",
@ -513,6 +514,7 @@
"pin_number": "PIN 码",
"placeholder_contacts": "您的联系人将显示在这里",
"placeholder_transactions": "您的交易将显示在这里",
"please_choose_one": "请选择一个",
"please_fill_totp": "请填写您其他设备上的 8 位代码",
"please_make_selection": "请在下面进行选择 创建或恢复您的钱包.",
"please_reference_document": "请参考以下文档以获取更多信息。",

View file

@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.20.0"
MONERO_COM_BUILD_NUMBER=113
MONERO_COM_VERSION="1.20.2"
MONERO_COM_BUILD_NUMBER=114
MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app"
MONERO_COM_SCHEME="monero.com"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.23.0"
CAKEWALLET_BUILD_NUMBER=246
CAKEWALLET_VERSION="4.23.2"
CAKEWALLET_BUILD_NUMBER=247
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
CAKEWALLET_SCHEME="cakewallet"

View file

@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.20.1"
MONERO_COM_BUILD_NUMBER=111
MONERO_COM_VERSION="1.20.2"
MONERO_COM_BUILD_NUMBER=112
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.23.1"
CAKEWALLET_BUILD_NUMBER=295
CAKEWALLET_VERSION="4.23.2"
CAKEWALLET_BUILD_NUMBER=298
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven"

View file

@ -14,8 +14,8 @@ if [ -n "$1" ]; then
fi
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.13.0"
CAKEWALLET_BUILD_NUMBER=46
CAKEWALLET_VERSION="1.13.2"
CAKEWALLET_BUILD_NUMBER=47
if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
echo "Wrong app type."

View file

@ -16,13 +16,13 @@ if [ -n "$1" ]; then
fi
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.10.0"
MONERO_COM_BUILD_NUMBER=43
MONERO_COM_VERSION="1.10.2"
MONERO_COM_BUILD_NUMBER=44
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.16.0"
CAKEWALLET_BUILD_NUMBER=104
CAKEWALLET_VERSION="1.16.2"
CAKEWALLET_BUILD_NUMBER=105
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

View file

@ -1,5 +1,5 @@
#define MyAppName "Cake Wallet"
#define MyAppVersion "0.4.0"
#define MyAppVersion "0.4.2"
#define MyAppPublisher "Cake Labs LLC"
#define MyAppURL "https://cakewallet.com/"
#define MyAppExeName "CakeWallet.exe"

View file

@ -872,6 +872,7 @@ import 'package:cw_evm/evm_chain_wallet.dart';
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:eth_sig_util/util/utils.dart';
@ -922,6 +923,7 @@ abstract class Ethereum {
void setLedgerConnection(WalletBase wallet, ledger.LedgerConnection connection);
Future<List<HardwareAccountData>> getHardwareWalletAccounts(LedgerViewModel ledgerVM, {int index = 0, int limit = 5});
List<String> getDefaultTokenContractAddresses();
}
""";
@ -977,6 +979,7 @@ import 'package:cw_evm/evm_chain_wallet.dart';
import 'package:cw_polygon/polygon_client.dart';
import 'package:cw_polygon/polygon_wallet.dart';
import 'package:cw_polygon/polygon_wallet_service.dart';
import 'package:cw_polygon/default_polygon_erc20_tokens.dart';
import 'package:eth_sig_util/util/utils.dart';
@ -1027,6 +1030,7 @@ abstract class Polygon {
void setLedgerConnection(WalletBase wallet, ledger.LedgerConnection connection);
Future<List<HardwareAccountData>> getHardwareWalletAccounts(LedgerViewModel ledgerVM, {int index = 0, int limit = 5});
List<String> getDefaultTokenContractAddresses();
}
""";
@ -1269,6 +1273,7 @@ import 'package:cw_solana/solana_wallet_service.dart';
import 'package:cw_solana/solana_transaction_info.dart';
import 'package:cw_solana/solana_transaction_credentials.dart';
import 'package:cw_solana/solana_wallet_creation_credentials.dart';
import 'package:cw_solana/default_spl_tokens.dart';
""";
const solanaCwPart = "part 'cw_solana.dart';";
const solanaContent = """
@ -1310,6 +1315,7 @@ abstract class Solana {
String getTokenAddress(CryptoCurrency asset);
List<int>? getValidationLength(CryptoCurrency type);
double? getEstimateFees(WalletBase wallet);
List<String> getDefaultTokenContractAddresses();
}
""";
@ -1355,6 +1361,7 @@ import 'package:cw_tron/tron_client.dart';
import 'package:cw_tron/tron_token.dart';
import 'package:cw_tron/tron_wallet.dart';
import 'package:cw_tron/tron_wallet_service.dart';
import 'package:cw_tron/default_tron_tokens.dart';
""";
const tronCwPart = "part 'cw_tron.dart';";
@ -1386,6 +1393,7 @@ abstract class Tron {
String? getTronTRC20EstimatedFee(WalletBase wallet);
void updateTronGridUsageState(WalletBase wallet, bool isEnabled);
List<String> getDefaultTokenContractAddresses();
}
""";