Merge branch 'refs/heads/main' into CW-1010-implement-tari-support

# Conflicts:
#	cw_core/lib/crypto_currency.dart
This commit is contained in:
Konstantin Ullrich 2025-05-21 14:43:19 +02:00
commit 430aa2ee72
No known key found for this signature in database
GPG key ID: 6B3199AD9B3D23B8
80 changed files with 401 additions and 237 deletions

View file

@ -111,6 +111,8 @@
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="nano-gpt" />
</intent-filter>
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
</activity>
<meta-data
android:name="flutterEmbedding"

View file

@ -1,4 +1,3 @@
Background sync improvements
Payment notifications
UI/UX improvements
Monero enhancements
UI improvements
Bug fixes

View file

@ -1,5 +1,4 @@
Background sync improvements
Payment notifications
WalletConnect enhancements
UI/UX improvements
Add Bitcoin Payjoin
Monero enhancements
UI improvements
Bug fixes

View file

@ -20,6 +20,7 @@ BitcoinBaseAddress addressFromScript(Script script,
return P2pkhAddress.fromScriptPubkey(
script: script, network: BitcoinNetwork.mainnet);
case P2shAddressType.p2pkhInP2sh:
case P2shAddressType.p2pkInP2sh:
return P2shAddress.fromScriptPubkey(
script: script, network: BitcoinNetwork.mainnet);
case SegwitAddresType.p2wpkh:

View file

@ -1167,4 +1167,4 @@ packages:
version: "2.2.2"
sdks:
dart: ">=3.5.0 <4.0.0"
flutter: ">=3.27.4"
flutter: ">=3.24.0"

View file

@ -233,7 +233,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
static const ton = CryptoCurrency(title: 'TON', fullName: 'Toncoin', raw: 95, name: 'ton', iconPath: 'assets/images/ton_icon.png', decimals: 8);
static const zano = CryptoCurrency(title: 'ZANO', tag: 'ZANO', fullName: 'Zano', raw: 96, name: 'zano', iconPath: 'assets/images/zano_icon.png', decimals: 12);
static const flip = CryptoCurrency(title: 'FLIP', tag: 'ETH', fullName: 'Chainflip', raw: 97, name: 'flip', iconPath: 'assets/images/flip_icon.png', decimals: 18);
static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Digital Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png', decimals: 18);
static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Decentralized Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png', decimals: 18);
static const tari = CryptoCurrency(title: 'tXTR', fullName: 'Tari', raw: 99, name: 'tari', iconPath: 'assets/images/tari.png', decimals: 8);
static final Map<int, CryptoCurrency> _rawCurrencyMap =

View file

@ -810,4 +810,4 @@ packages:
version: "3.1.3"
sdks:
dart: ">=3.5.0 <4.0.0"
flutter: ">=3.27.4"
flutter: ">=3.24.0"

View file

@ -18,7 +18,7 @@ class DefaultEthereumErc20Tokens {
enabled: true,
),
Erc20Token(
name: "Digital Euro",
name: "Decentralized Euro",
symbol: "DEURO",
contractAddress: "0xbA3f535bbCcCcA2A154b573Ca6c5A49BAAE0a3ea",
decimal: 18,

View file

@ -31,11 +31,14 @@ class EthereumWallet extends EVMChainWallet {
}) : super(nativeCurrency: CryptoCurrency.eth);
@override
void addInitialTokens() {
void addInitialTokens([bool isMigration = false]) {
final initialErc20Tokens = DefaultEthereumErc20Tokens().initialErc20Tokens;
for (var token in initialErc20Tokens) {
evmChainErc20TokensBox.put(token.contractAddress, token);
for (final token in initialErc20Tokens) {
if (!evmChainErc20TokensBox.containsKey(token.contractAddress)) {
if (isMigration) token.enabled = false;
evmChainErc20TokensBox.put(token.contractAddress, token);
}
}
}

View file

@ -53,6 +53,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
);
await wallet.init();
wallet.addInitialTokens(true);
await wallet.save();
saveBackup(name);
return wallet;

View file

@ -136,7 +136,7 @@ abstract class EVMChainWalletBase
//! Methods to be overridden by every child
void addInitialTokens();
void addInitialTokens([bool isMigration]);
// Future<EVMChainWallet> open({
// required String name,

View file

@ -25,8 +25,8 @@ bool isUpdating = false;
void refreshAccounts() {
try {
isUpdating = true;
subaddressAccount = currentWallet!.subaddressAccount();
subaddressAccount!.refresh();
subaddressAccount = currentWallet?.subaddressAccount();
subaddressAccount?.refresh();
isUpdating = false;
} catch (e) {
isUpdating = false;

View file

@ -139,16 +139,16 @@ String getAddress({int accountIndex = 0, int addressIndex = 0}) {
}
int getFullBalance({int accountIndex = 0}) =>
currentWallet!.balance(accountIndex: accountIndex);
currentWallet?.balance(accountIndex: accountIndex) ?? 0;
int getUnlockedBalance({int accountIndex = 0}) =>
currentWallet!.unlockedBalance(accountIndex: accountIndex);
currentWallet?.unlockedBalance(accountIndex: accountIndex) ?? 0;
int getCurrentHeight() => currentWallet!.blockChainHeight();
int getCurrentHeight() => currentWallet?.blockChainHeight() ?? 0;
int getNodeHeightSync() => currentWallet!.daemonBlockChainHeight();
int getNodeHeightSync() => currentWallet?.daemonBlockChainHeight() ?? 0;
bool isConnectedSync() => currentWallet!.connected() != 0;
bool isConnectedSync() => currentWallet?.connected() != 0;
Future<bool> setupNodeSync(
{required String address,

View file

@ -34,12 +34,12 @@ import 'package:cw_monero/monero_transaction_history.dart';
import 'package:cw_monero/monero_transaction_info.dart';
import 'package:cw_monero/monero_unspent.dart';
import 'package:cw_monero/monero_wallet_addresses.dart';
import 'package:cw_monero/monero_wallet_service.dart';
import 'package:cw_monero/pending_monero_transaction.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
import 'package:mobx/mobx.dart';
import 'package:monero/src/monero.dart' as m;
import 'package:monero/monero.dart' as monero;
part 'monero_wallet.g.dart';
@ -193,19 +193,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
final wmaddr = wmPtr.ffiAddress();
final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.ffiAddress();
openedWalletsByPath.remove("$currentWalletDirPath/$name");
if (Platform.isWindows) {
await Isolate.run(() {
monero.WalletManager_closeWallet(
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
});
} else {
unawaited(Isolate.run(() {
monero.WalletManager_closeWallet(
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
}));
}
closeWalletAwaitIfShould(wmaddr, waddr);
currentWallet = null;
printV("wallet closed");
}
@ -446,7 +434,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
// final status = monero.PendingTransaction_status(pendingTransactionDescription);
return PendingMoneroTransaction(pendingTransactionDescription);
return PendingMoneroTransaction(pendingTransactionDescription, this);
}
@override

View file

@ -224,19 +224,7 @@ class MoneroWalletService extends WalletService<
final wmaddr = wmPtr.ffiAddress();
final waddr = w.ffiAddress();
openedWalletsByPath.remove("$path/$wallet");
if (Platform.isWindows) {
await Isolate.run(() {
monero.WalletManager_closeWallet(
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
});
} else {
unawaited(Isolate.run(() {
monero.WalletManager_closeWallet(
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
}));
}
await closeWalletAwaitIfShould(wmaddr, waddr);
printV("wallet closed");
}
@ -570,3 +558,19 @@ class MoneroWalletService extends WalletService<
false;
}
}
Future<void> closeWalletAwaitIfShould(int wmaddr, int waddr) async {
if (Platform.isWindows) {
await Isolate.run(() {
monero.WalletManager_closeWallet(
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
});
} else {
unawaited(Isolate.run(() {
monero.WalletManager_closeWallet(
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
}));
}
}

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:cw_monero/api/account_list.dart';
import 'package:cw_monero/api/structs/pending_transaction.dart';
import 'package:cw_monero/api/transaction_history.dart'
@ -7,6 +9,7 @@ import 'package:cw_core/amount_converter.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_monero/api/wallet.dart';
import 'package:cw_monero/monero_wallet.dart';
class DoubleSpendException implements Exception {
DoubleSpendException();
@ -17,9 +20,10 @@ class DoubleSpendException implements Exception {
}
class PendingMoneroTransaction with PendingTransaction {
PendingMoneroTransaction(this.pendingTransactionDescription);
PendingMoneroTransaction(this.pendingTransactionDescription, this.wallet);
final PendingTransactionDescription pendingTransactionDescription;
final MoneroWalletBase wallet;
@override
String get id => pendingTransactionDescription.hash;
@ -55,6 +59,10 @@ class PendingMoneroTransaction with PendingTransaction {
rethrow;
}
storeSync(force: true);
unawaited(() async {
await Future.delayed(const Duration(milliseconds: 250));
await wallet.fetchTransactions();
}());
}
@override
@ -63,6 +71,11 @@ class PendingMoneroTransaction with PendingTransaction {
final ret = monero_transaction_history.commitTransactionFromPointerAddress(
address: pendingTransactionDescription.pointerAddress,
useUR: true);
storeSync(force: true);
unawaited(() async {
await Future.delayed(const Duration(milliseconds: 250));
await wallet.fetchTransactions();
}());
return ret;
} catch (e) {
final message = e.toString();

View file

@ -978,4 +978,4 @@ packages:
version: "3.1.3"
sdks:
dart: ">=3.6.0 <4.0.0"
flutter: ">=3.27.4"
flutter: ">=3.24.0"

View file

@ -31,6 +31,13 @@ class DefaultPolygonErc20Tokens {
decimal: 6,
enabled: true,
),
Erc20Token(
name: "Decentralized Euro",
symbol: "DEURO",
contractAddress: "0xC2ff25dD99e467d2589b2c26EDd270F220F14E47",
decimal: 18,
enabled: true,
),
Erc20Token(
name: "Avalanche Token",
symbol: "AVAX",

View file

@ -41,11 +41,14 @@ class PolygonWallet extends EVMChainWallet {
}
@override
void addInitialTokens() {
void addInitialTokens([bool isMigration = false]) {
final initialErc20Tokens = DefaultPolygonErc20Tokens().initialPolygonErc20Tokens;
for (var token in initialErc20Tokens) {
evmChainErc20TokensBox.put(token.contractAddress, token);
for (final token in initialErc20Tokens) {
if (!evmChainErc20TokensBox.containsKey(token.contractAddress)) {
if (isMigration) token.enabled = false;
evmChainErc20TokensBox.put(token.contractAddress, token);
}
}
}

View file

@ -55,6 +55,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
);
await wallet.init();
wallet.addInitialTokens(true);
await wallet.save();
saveBackup(name);
return wallet;

View file

@ -845,4 +845,4 @@ packages:
version: "3.1.3"
sdks:
dart: ">=3.5.0 <4.0.0"
flutter: ">=3.27.4"
flutter: ">=3.24.0"

View file

@ -76,6 +76,7 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- payjoin_flutter (0.20.0)
- permission_handler_apple (9.3.0):
- Flutter
- reown_yttrium (0.0.1):
@ -126,6 +127,7 @@ DEPENDENCIES:
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- payjoin_flutter (from `.symlinks/plugins/payjoin_flutter/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- reown_yttrium (from `.symlinks/plugins/reown_yttrium/ios`)
- sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`)
@ -186,6 +188,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
payjoin_flutter:
:path: ".symlinks/plugins/payjoin_flutter/ios"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
reown_yttrium:
@ -208,40 +212,43 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/wakelock_plus/ios"
SPEC CHECKSUMS:
connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
CryptoSwift: e64e11850ede528a02a0f3e768cec8e9d92ecb90
cw_decred: a02cf30175a46971c1e2fa22c48407534541edc6
cw_mweb: 3aea2fb35b2bd04d8b2d21b83216f3b8fb768d85
device_display_brightness: 04374ebd653619292c1d996f00f42877ea19f17f
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
devicelocale: bd64aa714485a8afdaded0892c1e7d5b7f680cf8
cw_decred: 9c0e1df74745b51a1289ec5e91fb9e24b68fa14a
cw_mweb: 22cd01dfb8ad2d39b15332006f22046aaa8352a3
device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
devicelocale: 35ba84dc7f45f527c3001535d8c8d104edd5d926
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
fast_scanner: 2cb1ad3e69e645e9980fb4961396ce5804caa3e3
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
fast_scanner: 44c00940355a51258cd6c2085734193cd23d95bc
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_local_authentication: 989278c681612f1ee0e36019e149137f114b9d7f
flutter_mailer: 3a8cd4f36c960fb04528d5471097270c19fec1c4
flutter_secure_storage: 2c2ff13db9e0a5647389bff88b0ecac56e3f3418
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
in_app_review: 5596fe56fab799e8edb3561c03d053363ab13457
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
flutter_local_notifications: ff50f8405aaa0ccdc7dcfb9022ca192e8ad9688f
flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f
in_app_review: a31b5257259646ea78e0e35fc914979b0031d011
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
payjoin_flutter: 6397d7b698cdad6453be4949ab6aca1863f6c5e5
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
reown_yttrium: c0e87e5965fa60a3559564cc35cffbba22976089
SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
sensitive_clipboard: 161e9abc3d56b3131309d8a321eb4690a803c16b
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sp_scanner: b1bc9321690980bdb44bba7ec85d5543e716d1b5
sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
uni_links: ed8c961e47ed9ce42b6d91e1de8049e38a4b3152
universal_ble: ff19787898040d721109c6324472e5dd4bc86adc
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
universal_ble: cf52a7b3fd2e7c14d6d7262e9fdadb72ab6b88a6
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
wakelock_plus: 76957ab028e12bfa4e66813c99e46637f367fc7e
YttriumWrapper: 31e937fe9fbe0f1314d2ca6be9ce9b379a059966
PODFILE CHECKSUM: 5296465b1c6d14d506230356756826012f65d97a

View file

@ -327,5 +327,7 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>FlutterDeepLinkingEnabled</key>
<false/>
</dict>
</plist>

View file

@ -64,6 +64,7 @@ abstract class BuyProvider {
required bool isBuyAction,
required String walletAddress,
PaymentType? paymentType,
String? customPaymentMethodType,
String? countryCode}) async =>
null;
}

View file

@ -50,6 +50,7 @@ class Quote extends SelectableOption {
this.rampName,
this.rampIconPath,
this.limits,
this.customPaymentMethodType,
}) : super(title: provider.isAggregator ? rampName ?? '' : provider.title);
final double rate;
@ -68,6 +69,7 @@ class Quote extends SelectableOption {
bool _isBestRate = false;
bool isBuyAction;
Limits? limits;
String? customPaymentMethodType;
late FiatCurrency _fiatCurrency;
late CryptoCurrency _cryptoCurrency;
@ -130,7 +132,7 @@ class Quote extends SelectableOption {
set setLimits(Limits limits) => this.limits = limits;
factory Quote.fromOnramperJson(Map<String, dynamic> json, bool isBuyAction,
Map<String, dynamic> metaData, PaymentType paymentType) {
Map<String, dynamic> metaData, PaymentType paymentType, String? customPaymentMethodType) {
final rate = _toDouble(json['rate']) ?? 0.0;
final networkFee = _toDouble(json['networkFee']) ?? 0.0;
final transactionFee = _toDouble(json['transactionFee']) ?? 0.0;
@ -183,6 +185,7 @@ class Quote extends SelectableOption {
rampName: rampName,
rampIconPath: rampIconPath,
paymentType: paymentType,
customPaymentMethodType: customPaymentMethodType,
quoteId: json['quoteId'] as String? ?? '',
recommendations: enumRecommendations,
provider: ProvidersHelper.getProviderByType(ProviderType.onramper)!,

View file

@ -231,6 +231,7 @@ class DFXBuyProvider extends BuyProvider {
required bool isBuyAction,
required String walletAddress,
PaymentType? paymentType,
String? customPaymentMethodType,
String? countryCode}) async {
/// if buying with any currency other than eur or chf then DFX is not supported
@ -373,7 +374,7 @@ class DFXBuyProvider extends BuyProvider {
case 'Instant':
return PaymentType.sepa;
default:
return PaymentType.all;
return PaymentType.unknown;
}
}

View file

@ -113,6 +113,7 @@ class KryptonimBuyProvider extends BuyProvider {
required bool isBuyAction,
required String walletAddress,
PaymentType? paymentType,
String? customPaymentMethodType,
String? countryCode,
}) async {
log('Kryptonim: Fetching quote: ${isBuyAction ? cryptoCurrency : fiatCurrency} -> ${isBuyAction ? fiatCurrency : cryptoCurrency}, amount: $amount');
@ -149,7 +150,7 @@ class KryptonimBuyProvider extends BuyProvider {
final selectedPaymentType =
PaymentMethod.getPaymentTypeId(selectedPaymentMethod['payment_method'] as String?);
final quote = Quote.fromKryptonimJson(selectedPaymentMethod, isBuyAction, selectedPaymentType);
final quote = Quote.fromKryptonimJson(selectedPaymentMethod, isBuyAction, selectedPaymentType ?? PaymentType.unknown);
quote.setFiatCurrency = fiatCurrency;
quote.setCryptoCurrency = cryptoCurrency;

View file

@ -104,6 +104,7 @@ class MeldBuyProvider extends BuyProvider {
required bool isBuyAction,
required String walletAddress,
PaymentType? paymentType,
String? customPaymentMethodType,
String? countryCode}) async {
String? paymentMethod;
if (paymentType != null && paymentType != PaymentType.all) {

View file

@ -162,6 +162,7 @@ class MoonPayProvider extends BuyProvider {
required bool isBuyAction,
required String walletAddress,
PaymentType? paymentType,
String? customPaymentMethodType,
String? countryCode}) async {
String? paymentMethod;
@ -410,7 +411,7 @@ class MoonPayProvider extends BuyProvider {
case 'yellow_card_bank_transfer':
return PaymentType.yellowCardBankTransfer;
default:
return PaymentType.all;
return PaymentType.unknown;
}
}
}

View file

@ -33,6 +33,7 @@ class OnRamperBuyProvider extends BuyProvider {
static const quotes = '/quotes';
static const paymentTypes = '/payment-types';
static const supported = '/supported';
static const defaultsAll = '/defaults/all';
static const List<CryptoCurrency> _notSupportedCrypto = [];
static const List<FiatCurrency> _notSupportedFiat = [];
@ -40,6 +41,8 @@ class OnRamperBuyProvider extends BuyProvider {
final SettingsStore _settingsStore;
String? recommendedPaymentType;
String get _apiKey => secrets.onramperApiKey;
@override
@ -57,6 +60,34 @@ class OnRamperBuyProvider extends BuyProvider {
@override
bool get isAggregator => true;
Future<String?> getRecommendedPaymentType(bool isBuyAction) async {
final params = {'type': isBuyAction ? 'buy' : 'sell'};
final url = Uri.https(_baseApiUrl, '$supported$defaultsAll', params);
try {
final response =
await http.get(url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
if (response.statusCode == 200) {
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
final recommended = data['message']['recommended'] as Map<String, dynamic>;
final recommendedPaymentType = recommended['paymentMethod'] as String?;
return recommendedPaymentType ;
} else {
final responseBody =
jsonDecode(response.body) as Map<String, dynamic>;
printV('Failed to fetch available payment types: ${responseBody['message']}');
}
} catch (e) {
printV('Failed to fetch available payment types: $e');
}
return null;
}
Future<List<PaymentMethod>> getAvailablePaymentTypes(
String fiatCurrency, CryptoCurrency cryptoCurrency, bool isBuyAction) async {
@ -77,9 +108,14 @@ class OnRamperBuyProvider extends BuyProvider {
if (response.statusCode == 200) {
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
final List<dynamic> message = data['message'] as List<dynamic>;
return message
final allAvailablePaymentMethods = message
.map((item) => PaymentMethod.fromOnramperJson(item as Map<String, dynamic>))
.toList();
recommendedPaymentType = await getRecommendedPaymentType(isBuyAction);
return allAvailablePaymentMethods;
} else {
final responseBody =
jsonDecode(response.body) as Map<String, dynamic>;
@ -131,13 +167,13 @@ class OnRamperBuyProvider extends BuyProvider {
required bool isBuyAction,
required String walletAddress,
PaymentType? paymentType,
String? customPaymentMethodType,
String? countryCode}) async {
String? paymentMethod;
if (paymentType != null && paymentType != PaymentType.all) {
paymentMethod = normalizePaymentMethod(paymentType);
if (paymentMethod == null) paymentMethod = paymentType.name;
}
if (paymentType == PaymentType.all && recommendedPaymentType != null) paymentMethod = recommendedPaymentType!;
else if (paymentType == PaymentType.unknown) paymentMethod = customPaymentMethodType;
else if (paymentType != null) paymentMethod = normalizePaymentMethod(paymentType);
final actionType = isBuyAction ? 'buy' : 'sell';
@ -182,7 +218,7 @@ class OnRamperBuyProvider extends BuyProvider {
if (rampMetaData == null) continue;
final quote = Quote.fromOnramperJson(
item, isBuyAction, _onrampMetadata, _getPaymentTypeByString(paymentMethod));
item, isBuyAction, _onrampMetadata, _getPaymentTypeByString(paymentMethod), customPaymentMethodType);
quote.setFiatCurrency = fiatCurrency;
quote.setCryptoCurrency = cryptoCurrency;
validQuotes.add(quote);
@ -225,7 +261,7 @@ class OnRamperBuyProvider extends BuyProvider {
final defaultCrypto =
quote.cryptoCurrency.title + _getNormalizeNetwork(quote.cryptoCurrency).toLowerCase();
final paymentMethod = normalizePaymentMethod(quote.paymentType);
final paymentMethod = quote.paymentType == PaymentType.unknown ? quote.customPaymentMethodType : normalizePaymentMethod(quote.paymentType);
final uri = Uri.https(_baseUrl, '', {
'apiKey': _apiKey,
@ -330,6 +366,8 @@ class OnRamperBuyProvider extends BuyProvider {
return 'dana';
case PaymentType.ideal:
return 'ideal';
case PaymentType.pixPay:
return 'pix';
default:
return null;
}
@ -379,8 +417,10 @@ class OnRamperBuyProvider extends BuyProvider {
return PaymentType.dana;
case 'ideal':
return PaymentType.ideal;
case 'pix':
return PaymentType.pixPay;
default:
return PaymentType.all;
return PaymentType.unknown;
}
}

View file

@ -34,6 +34,8 @@ enum PaymentType {
yellowCardBankTransfer,
fiatBalance,
bancontact,
pixPay,
unknown,
}
extension PaymentTypeTitle on PaymentType {
@ -101,6 +103,8 @@ extension PaymentTypeTitle on PaymentType {
return 'Fiat Balance';
case PaymentType.bancontact:
return 'Bancontact';
case PaymentType.pixPay:
return 'PIX Pay';
default:
return null;
}
@ -158,12 +162,14 @@ class PaymentMethod extends SelectableOption {
required this.customTitle,
required this.customIconPath,
this.customDescription,
this.customPaymentMethodType,
}) : super(title: paymentMethodType.title ?? customTitle);
final PaymentType paymentMethodType;
final String customTitle;
final String customIconPath;
final String? customDescription;
final String? customPaymentMethodType;
bool isSelected = false;
@override
@ -188,7 +194,8 @@ class PaymentMethod extends SelectableOption {
factory PaymentMethod.fromOnramperJson(Map<String, dynamic> json) {
final type = PaymentMethod.getPaymentTypeId(json['paymentTypeId'] as String?);
return PaymentMethod(
paymentMethodType: type,
paymentMethodType: type ?? PaymentType.unknown,
customPaymentMethodType: json['paymentTypeId'] as String?,
customTitle: json['name'] as String? ?? 'Unknown',
customIconPath: json['icon'] as String? ?? 'assets/images/card.png',
customDescription: json['description'] as String?);
@ -212,7 +219,7 @@ class PaymentMethod extends SelectableOption {
final type = PaymentMethod.getPaymentTypeId(json['paymentMethod'] as String?);
final logos = json['logos'] as Map<String, dynamic>;
return PaymentMethod(
paymentMethodType: type,
paymentMethodType: type ?? PaymentType.unknown,
customTitle: json['name'] as String? ?? 'Unknown',
customIconPath: logos['dark'] as String? ?? 'assets/images/card.png',
customDescription: json['description'] as String?);
@ -221,13 +228,13 @@ class PaymentMethod extends SelectableOption {
factory PaymentMethod.fromKryptonimJson(Map<String, dynamic> json) {
final type = PaymentMethod.getPaymentTypeId(json['payment_method'] as String?);
return PaymentMethod(
paymentMethodType: type,
paymentMethodType: type ?? PaymentType.unknown,
customTitle: json['payment_method'] as String? ?? 'Unknown',
customIconPath: 'assets/images/card.png',
);
}
static PaymentType getPaymentTypeId(String? type) {
static PaymentType? getPaymentTypeId(String? type) {
switch (type?.toLowerCase()) {
case 'banktransfer':
case 'bank':
@ -289,8 +296,10 @@ class PaymentMethod extends SelectableOption {
return PaymentType.sepaOpenBankingPayment;
case 'bancontact':
return PaymentType.bancontact;
case 'pix':
return PaymentType.pixPay;
default:
return PaymentType.all;
return null;
}
}
}

View file

@ -192,6 +192,7 @@ class RobinhoodBuyProvider extends BuyProvider {
required bool isBuyAction,
required String walletAddress,
PaymentType? paymentType,
String? customPaymentMethodType,
String? countryCode}) async {
String? paymentMethod;
@ -267,7 +268,7 @@ class RobinhoodBuyProvider extends BuyProvider {
case 'bank_transfer':
return PaymentType.bankTransfer;
default:
return PaymentType.all;
return PaymentType.unknown;
}
}
}

View file

@ -83,7 +83,7 @@ class $BackupService {
outer:
for (var file in zip.files) {
final filename = file.name;
for (var ignore in ignoreFiles) {
for (var ignore in ignoreFiles) {
if (filename.endsWith(ignore) && !filename.contains("wallets/")) {
printV("ignoring backup file: $filename");
continue outer;
@ -145,7 +145,7 @@ class $BackupService {
MapEntry(key, TransactionDescription.fromJson(value as Map<String, dynamic>)));
var box = transactionDescriptionBox;
if (!box.isOpen) {
final transactionDescriptionsBoxKey =
final transactionDescriptionsBoxKey =
await getEncryptionKey(secureStorage: _secureStorage, forKey: TransactionDescription.boxKey);
box = await CakeHive.openBox<TransactionDescription>(
TransactionDescription.boxName,
@ -251,19 +251,22 @@ class $BackupService {
await importWalletKeychainInfo(info);
});
for (var key in (keychainJSON['_all'] as Map<String, dynamic>).keys) {
try {
if (!key.startsWith('MONERO_WALLET_')) continue;
final decodedPassword = decodeWalletPassword(password: keychainJSON['_all'][key].toString());
final walletName = key.split('_WALLET_')[1];
final walletType = key.split('_WALLET_')[0].toLowerCase();
await importWalletKeychainInfo({
'name': walletName,
'type': "WalletType.$walletType",
'password': decodedPassword,
});
} catch (e) {
printV('Error importing wallet ($key) password: $e');
if (keychainJSON['_all'] is Map<String, dynamic>) {
for (var key in (keychainJSON['_all'] as Map<String, dynamic>).keys) {
try {
if (!key.startsWith('MONERO_WALLET_')) continue;
final decodedPassword = decodeWalletPassword(
password: keychainJSON['_all'][key].toString());
final walletName = key.split('_WALLET_')[1];
final walletType = key.split('_WALLET_')[0].toLowerCase();
await importWalletKeychainInfo({
'name': walletName,
'type': "WalletType.$walletType",
'password': decodedPassword,
});
} catch (e) {
printV('Error importing wallet ($key) password: $e');
}
}
}

View file

@ -2,16 +2,19 @@ import 'package:cw_core/enumerable_item.dart';
import 'package:cw_core/wallet_info.dart';
class MoneroSeedType extends EnumerableItem<int> with Serializable<int> {
const MoneroSeedType({required String title, required int raw}) : super(title: title, raw: raw);
const MoneroSeedType({required String title, required int raw, this.shortTitle})
: super(title: title, raw: raw);
final String? shortTitle;
static const all = [legacy, polyseed, bip39];
static const defaultSeedType = polyseed;
static const legacy = MoneroSeedType(raw: 0, title: 'Legacy (25 words)');
static const polyseed = MoneroSeedType(raw: 1, title: 'Polyseed (16 words)');
static const legacy = MoneroSeedType(raw: 0, title: 'Legacy (25 words)', shortTitle: "Legacy");
static const polyseed = MoneroSeedType(raw: 1, title: 'Polyseed (16 words)', shortTitle: "Polyseed");
static const wowneroSeed = MoneroSeedType(raw: 2, title: 'Wownero');
static const bip39 = MoneroSeedType(raw: 3, title: 'BIP39 (12 words)');
static const bip39 = MoneroSeedType(raw: 3, title: 'BIP39 (12 words)', shortTitle: "BIP39");
static MoneroSeedType deserialize({required int raw}) {
switch (raw) {

View file

@ -47,10 +47,10 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
String get title => 'SwapTrade';
@override
bool get isAvailable => false;
bool get isAvailable => true;
@override
bool get isEnabled => false;
bool get isEnabled => true;
@override
bool get supportsFixedRate => false;
@ -59,7 +59,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
ExchangeProviderDescription get description => ExchangeProviderDescription.swapTrade;
@override
Future<bool> checkIsAvailable() async => false;
Future<bool> checkIsAvailable() async => true;
@override
Future<Limits> fetchLimits({

View file

@ -97,6 +97,11 @@ class ExchangePage extends BasePage {
}
};
bool get _shouldWaitTillSynced =>
[CryptoCurrency.xmr, CryptoCurrency.btc, CryptoCurrency.ltc]
.contains(exchangeViewModel.depositCurrency) &&
!(exchangeViewModel.status is SyncedSyncStatus);
@override
Widget middle(BuildContext context) => Row(
mainAxisAlignment: MainAxisAlignment.center,
@ -252,20 +257,21 @@ class ExchangePage extends BasePage {
onPressed: exchangeViewModel.isAvailableInSelected ? () {
FocusScope.of(context).unfocus();
if (_formKey.currentState != null &&
_formKey.currentState!.validate()) {
if ((exchangeViewModel.depositCurrency == CryptoCurrency.xmr) &&
(!(exchangeViewModel.status is SyncedSyncStatus))) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).exchange,
alertContent: S.of(context).exchange_sync_alert_content,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
} else {
if (_formKey.currentState != null &&
_formKey.currentState!.validate()) {
if (_shouldWaitTillSynced) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).exchange,
alertContent:
S.of(context).exchange_sync_alert_content,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
});
} else {
final check = exchangeViewModel.shouldDisplayTOTP();
authService.authenticateAction(
context,

View file

@ -154,6 +154,7 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
items: MoneroSeedType.all,
selectedItem: widget.seedTypeViewModel.moneroSeedType,
onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
displayItem: (seedType) => seedType.shortTitle ?? seedType.toString(),
),
);
}),

View file

@ -97,8 +97,7 @@ class QRWidget extends StatelessWidget {
padding: EdgeInsets.zero,
decoration: BoxDecoration(
border: Border(top: BorderSide.none),
borderRadius:
BorderRadius.all(Radius.circular(5)),
borderRadius: BorderRadius.all(Radius.circular(5)),
color: Colors.white,
),
child: Column(
@ -112,11 +111,10 @@ class QRWidget extends StatelessWidget {
),
),
),
if (addressListViewModel
.payjoinEndpoint.isNotEmpty) ...[
if (addressListViewModel.payjoinEndpoint.isNotEmpty &&
!addressListViewModel.isSilentPayments) ...[
Row(
mainAxisAlignment:
MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(
@ -196,10 +194,12 @@ class QRWidget extends StatelessWidget {
walletType: addressListViewModel.type,
textAlign: TextAlign.center,
evenTextStyle: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
color:
Theme.of(context).extension<DashboardPageTheme>()!.textColor))),
fontSize: 15,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
),
),
),
Padding(
padding: EdgeInsets.only(left: 12),
child: copyImage,
@ -210,24 +210,27 @@ class QRWidget extends StatelessWidget {
),
),
),
if (addressListViewModel.payjoinEndpoint.isNotEmpty) ...[
Padding(
padding: EdgeInsets.only(top: 12),
child: PrimaryImageButton(
onPressed: () {
Clipboard.setData(ClipboardData(
text: addressListViewModel.payjoinEndpoint));
showBar<void>(context, S.of(context).copied_to_clipboard);
},
image: Image.asset('assets/images/payjoin.png', width: 25,),
text: S.of(context).copy_payjoin_url,
color: Theme.of(context).cardColor,
textColor: Theme.of(context)
.extension<CakeTextTheme>()!
.buttonTextColor,
Observer(
builder: (_) => Offstage(
offstage: addressListViewModel.payjoinEndpoint.isEmpty || addressListViewModel.isSilentPayments,
child: Padding(
padding: EdgeInsets.only(top: 12),
child: PrimaryImageButton(
onPressed: () {
Clipboard.setData(ClipboardData(text: addressUri.toString()));
showBar<void>(context, S.of(context).copied_to_clipboard);
},
image: Image.asset(
'assets/images/payjoin.png',
width: 25,
),
text: S.of(context).copy_payjoin_address,
color: Theme.of(context).cardColor,
textColor: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
),
),
),
],
),
],
),
),

View file

@ -64,7 +64,8 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
final mainImageColor = Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor;
final brightImageColor = Theme.of(context).extension<InfoTheme>()!.textColor;
final imageColor = widget.themeType == ThemeType.bright ? brightImageColor : mainImageColor;
final imageLedger = Image.asset('assets/images/hardware_wallet/ledger_nano_x.png', width: 40, color: imageColor);
final imageLedger = Image.asset('assets/images/hardware_wallet/ledger_nano_x.png',
width: 40, color: imageColor);
final imageSeedKeys = Image.asset('assets/images/restore_wallet_image.png', color: imageColor);
final imageBackup = Image.asset('assets/images/backup.png', color: imageColor);
@ -78,9 +79,7 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
children: <Widget>[
OptionTile(
key: ValueKey('restore_options_from_seeds_or_keys_button_key'),
onPressed: () => Navigator.pushNamed(
context,
Routes.restoreWalletFromSeedKeys),
onPressed: () => Navigator.pushNamed(context, Routes.restoreWalletFromSeedKeys),
image: imageSeedKeys,
title: S.of(context).restore_title_from_seed_keys,
description: S.of(context).restore_description_from_seed_keys,
@ -101,26 +100,27 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
padding: EdgeInsets.only(top: 24),
child: OptionTile(
key: ValueKey('restore_options_from_hardware_wallet_button_key'),
onPressed: () => Navigator.pushNamed(
context, Routes.restoreWalletFromHardwareWallet),
onPressed: () =>
Navigator.pushNamed(context, Routes.restoreWalletFromHardwareWallet),
image: imageLedger,
title: S.of(context).restore_title_from_hardware_wallet,
description: S.of(context).restore_description_from_hardware_wallet,
),
),
Padding(
padding: EdgeInsets.only(top: 24),
child: OptionTile(
key: ValueKey('restore_options_from_qr_button_key'),
onPressed: () => _onScanQRCode(context),
icon: Icon(
Icons.qr_code_rounded,
color: imageColor,
size: 50,
),
title: S.of(context).scan_qr_code,
description: S.of(context).cold_or_recover_wallet),
)
if (DeviceInfo.instance.isMobile)
Padding(
padding: EdgeInsets.only(top: 24),
child: OptionTile(
key: ValueKey('restore_options_from_qr_button_key'),
onPressed: () => _onScanQRCode(context),
icon: Icon(
Icons.qr_code_rounded,
color: imageColor,
size: 50,
),
title: S.of(context).scan_qr_code,
description: S.of(context).cold_or_recover_wallet),
)
],
),
)),
@ -145,7 +145,7 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
Future<void> _onScanQRCode(BuildContext context) async {
final isCameraPermissionGranted =
await PermissionHandler.checkPermission(Permission.camera, context);
await PermissionHandler.checkPermission(Permission.camera, context);
if (!isCameraPermissionGranted) return;
try {

View file

@ -600,6 +600,8 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
final maxCustomFeeRate = sendViewModel.feesViewModel.maxCustomFeeRate?.toDouble();
double? customFeeRate = isBitcoinWallet ? sendViewModel.feesViewModel.customBitcoinFeeRate.toDouble() : null;
FocusManager.instance.primaryFocus?.unfocus();
await showPopUp<void>(
context: context,
builder: (BuildContext context) {

View file

@ -9,6 +9,7 @@ import 'package:cake_wallet/src/widgets/list_row.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/src/widgets/standard_list_card.dart';
import 'package:cake_wallet/src/widgets/standard_list_status_row.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/view_model/trade_details_view_model.dart';
import 'package:flutter/material.dart';
@ -59,9 +60,31 @@ class TradeDetailsPageBodyState extends State<TradeDetailsPageBody> {
final item = tradeDetailsViewModel.items[index];
if (item is TrackTradeListItem)
return GestureDetector(
return ListRow(
title: '${item.title}',
value: '${item.value}',
textWidget: GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(text: '${item.value}'));
showBar<void>(context, S.of(context).copied_to_clipboard);
},
child: Text(
'${item.value}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
),
image: GestureDetector(
onTap: item.onTap,
child: ListRow(title: '${item.title}', value: '${item.value}'));
child: Icon(
Icons.launch_rounded,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
);
if (item is DetailsListStatusItem)
return StandardListStatusRow(title: item.title, value: item.value);

View file

@ -20,7 +20,7 @@ class ListRow extends StatelessWidget {
final String value;
final double titleFontSize;
final double valueFontSize;
final Image? image;
final Widget? image;
final EdgeInsetsGeometry? padding;
final Color? color;
final Color? hintTextColor;

View file

@ -225,7 +225,7 @@ class ExceptionHandler {
// just ignoring until we find a solution to this issue or migrate from flutter secure storage
"core/auth_service.dart:64",
"core/key_service.dart:14",
"core/wallet_loading_service.dart:134",
"core/wallet_loading_service.dart:139",
];
static Future<void> _addDeviceInfo(File file) async {

View file

@ -359,14 +359,23 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
onTimeout: () => [],
)));
final Map<PaymentType, PaymentMethod> uniquePaymentMethods = {};
final List<PaymentMethod> tempPaymentMethods = [];
for (var methods in result) {
for (var method in methods) {
uniquePaymentMethods[method.paymentMethodType] = method;
final alreadyExists = tempPaymentMethods.any((m) {
return m.paymentMethodType == method.paymentMethodType &&
m.customTitle == method.customTitle;
});
if (!alreadyExists) {
tempPaymentMethods.add(method);
}
}
}
paymentMethods = ObservableList<PaymentMethod>.of(uniquePaymentMethods.values);
paymentMethods = ObservableList<PaymentMethod>.of(tempPaymentMethods);
if (paymentMethods.isNotEmpty) {
paymentMethods.insert(0, PaymentMethod.all());
selectedPaymentMethod = paymentMethods.first;
@ -404,6 +413,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
paymentType: selectedPaymentMethod?.paymentMethodType,
isBuyAction: isBuyAction,
walletAddress: wallet.walletAddresses.address,
customPaymentMethodType: selectedPaymentMethod?.customPaymentMethodType,
)
.timeout(
Duration(seconds: 10),

View file

@ -593,7 +593,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
final sharedPreferences = await SharedPreferences.getInstance();
await sharedPreferences.setString(PreferencesKey.backgroundSyncLastTrigger(wallet.name), DateTime.now().add(Duration(minutes: 1)).toIso8601String());
unawaited(wallet.fetchTransactions());
state = TransactionCommitted();
} catch (e) {
state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency));

View file

@ -83,7 +83,7 @@ class BitcoinURI extends PaymentURI {
final qp = <String, String>{};
if (amount.isNotEmpty) qp['amount'] = amount.replaceAll(',', '.');
if (pjUri.isNotEmpty) {
if (pjUri.isNotEmpty && !address.startsWith("sp")) {
qp['pjos'] = '0';
qp['pj'] = pjUri;
}

View file

@ -2,8 +2,6 @@ import 'package:cake_wallet/core/wallet_loading_service.dart';
import 'package:cake_wallet/entities/wallet_group.dart';
import 'package:cake_wallet/entities/wallet_list_order_types.dart';
import 'package:cake_wallet/entities/wallet_manager.dart';
import 'package:cake_wallet/reactions/bip39_wallet_utils.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/store/app_store.dart';

View file

@ -202,6 +202,7 @@
"copy": "نسخ",
"copy_address": "نسخ العنوان",
"copy_id": "نسخ معرف العملية",
"copy_payjoin_address": "نسخ عنوان payjoin",
"copy_payjoin_url": "نسخ Payjoin url",
"copyWalletConnectLink": "ﺎﻨﻫ ﻪﻘﺼﻟﺍﻭ dApp ﻦﻣ WalletConnect ﻂﺑﺍﺭ ﺦﺴﻧﺍ",
"corrupted_seed_notice": "تالف ملفات هذه المحفظة ولا يمكن فتحها. يرجى الاطلاع على عبارة البذور وحفظها واستعادة المحفظة.\n\nإذا كانت القيمة فارغة ، لم تتمكن البذور من استردادها بشكل صحيح.",
@ -1071,4 +1072,4 @@
"you_will_send": "تحويل من",
"youCanGoBackToYourDapp": "يمكنك العودة إلى DAPP الخاص بك الآن",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Копиране",
"copy_address": "Copy Address",
"copy_id": "Копиране на ID",
"copy_payjoin_address": "Копирайте адрес на payjoin",
"copy_payjoin_url": "Копиране Payjoin url",
"copyWalletConnectLink": "Копирайте връзката WalletConnect от dApp и я поставете тук",
"corrupted_seed_notice": "Файловете за този портфейл са повредени и не могат да бъдат отворени. Моля, прегледайте фразата за семена, запазете я и възстановете портфейла.\n\nАко стойността е празна, тогава семето не успя да бъде правилно възстановено.",
@ -1071,4 +1072,4 @@
"you_will_send": "Обръщане от",
"youCanGoBackToYourDapp": "Можете да се върнете при вашия Dapp сега",
"yy": "гг"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kopírovat",
"copy_address": "Zkopírovat adresu",
"copy_id": "Kopírovat ID",
"copy_payjoin_address": "Kopírovat adresu payjoin",
"copy_payjoin_url": "Kopírovat Payjoin URL",
"copyWalletConnectLink": "Zkopírujte odkaz WalletConnect z dApp a vložte jej sem",
"corrupted_seed_notice": "Soubory pro tuto peněženku jsou poškozeny a nemohou být otevřeny. Podívejte se prosím na osivo, uložte ji a obnovte peněženku.\n\nPokud je hodnota prázdná, pak semeno nebylo možné správně obnovit.",
@ -1071,4 +1072,4 @@
"you_will_send": "Směnit z",
"youCanGoBackToYourDapp": "Nyní se můžete vrátit do svého dappu",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kopieren",
"copy_address": "Adresse kopieren",
"copy_id": "ID kopieren",
"copy_payjoin_address": "Kopieren Sie Payjoin -Adresse",
"copy_payjoin_url": "Payjoin URL kopieren",
"copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein",
"corrupted_seed_notice": "Die Dateien für diese Wallet sind beschädigt und können nicht geöffnet werden. Bitte sehen Sie sich die Seeds an, speichern Sie sie und stellen Sie die Wallet wieder her.\n\nWenn der Wert leer ist, konnte der Seed nicht korrekt wiederhergestellt werden.",
@ -1074,4 +1075,4 @@
"you_will_send": "Konvertieren von",
"youCanGoBackToYourDapp": "Sie können jetzt zu Ihrem Dapp zurückkehren",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Copy",
"copy_address": "Copy Address",
"copy_id": "Copy ID",
"copy_payjoin_address": "Copy Payjoin Address",
"copy_payjoin_url": "Copy Payjoin URL",
"copyWalletConnectLink": "Copy the WalletConnect link from dApp and paste here",
"corrupted_seed_notice": "The files for this wallet are corrupted and are unable to be opened. Please view the seed phrase, save it, and restore the wallet.\n\nIf the value is empty, then the seed was unable to be correctly recovered.",
@ -1072,4 +1073,4 @@
"you_will_send": "Convert from",
"youCanGoBackToYourDapp": "You can go back to your dApp now",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Dupdo",
"copy_address": "Copiar dirección ",
"copy_id": "Copiar ID",
"copy_payjoin_address": "Copiar dirección de payjoin",
"copy_payjoin_url": "Copiar Payjoin url",
"copyWalletConnectLink": "Copie el enlace de WalletConnect de dApp y péguelo aquí",
"corrupted_seed_notice": "Los archivos para esta billetera están dañados y no pueden abrirse. Vea la frase de semillas, guárdela y restaura la billetera.\n\nSi el valor está vacío, entonces la semilla no pudo recuperarse correctamente.",
@ -1072,4 +1073,4 @@
"you_will_send": "Convertir de",
"youCanGoBackToYourDapp": "Puedes volver a tu dapp ahora",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Copier",
"copy_address": "Copier l'Adresse",
"copy_id": "Copier l'ID",
"copy_payjoin_address": "Copier l'adresse de paiement",
"copy_payjoin_url": "Copie Payjoin URL",
"copyWalletConnectLink": "Copiez le lien WalletConnect depuis l'application décentralisée (dApp) et collez-le ici",
"corrupted_seed_notice": "Les fichiers de ce portefeuille sont corrompus et ne peuvent pas être ouverts. Veuillez consulter la phrase de graines, sauver et restaurer le portefeuille.\n\nSi la valeur est vide, la graine n'a pas pu être correctement récupérée.",
@ -1071,4 +1072,4 @@
"you_will_send": "Convertir depuis",
"youCanGoBackToYourDapp": "Vous pouvez retourner à votre Dapp maintenant",
"yy": "AA"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kwafi",
"copy_address": "Kwafi Adireshin",
"copy_id": "Kwafi ID",
"copy_payjoin_address": "Kwafi Adireshin Payjoin",
"copy_payjoin_url": "Kwafa Payjoin url",
"copyWalletConnectLink": "Kwafi hanyar haɗin WalletConnect daga dApp kuma liƙa a nan",
"corrupted_seed_notice": "Fayilolin don wannan walat ɗin sun lalata kuma ba za a iya buɗe su ba. Da fatan za a duba kalmar iri, adana shi, da dawo da walat.\n\nIdan darajar ta kasance fanko, to sai zuriyar da ba ta iya murmurewa daidai ba.",
@ -1073,4 +1074,4 @@
"you_will_send": "Maida daga",
"youCanGoBackToYourDapp": "Kuna iya komawa zuwa DPP ɗinku yanzu",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "प्रतिलिपि",
"copy_address": "पता कॉपी करें",
"copy_id": "प्रतिलिपि ID",
"copy_payjoin_address": "कॉपी पेजोइन पता",
"copy_payjoin_url": "कॉपी Payjoin url",
"copyWalletConnectLink": "dApp से वॉलेटकनेक्ट लिंक को कॉपी करें और यहां पेस्ट करें",
"corrupted_seed_notice": "इस वॉलेट की फाइलें दूषित हैं और उन्हें खोलने में असमर्थ हैं। कृपया बीज वाक्यांश देखें, इसे बचाएं, और बटुए को पुनर्स्थापित करें।\n\nयदि मूल्य खाली है, तो बीज सही ढंग से पुनर्प्राप्त करने में असमर्थ था।",
@ -1073,4 +1074,4 @@
"you_will_send": "से रूपांतरित करें",
"youCanGoBackToYourDapp": "अब आप अपने DAPP पर वापस जा सकते हैं",
"yy": "वाईवाई"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kopiraj",
"copy_address": "Kopiraj adresu",
"copy_id": "Kopirati ID",
"copy_payjoin_address": "Kopirajte Payjoin adresu",
"copy_payjoin_url": "Kopirajte Payjoin url",
"copyWalletConnectLink": "Kopirajte vezu WalletConnect iz dApp-a i zalijepite je ovdje",
"corrupted_seed_notice": "Datoteke za ovaj novčanik su oštećene i nisu u mogućnosti otvoriti. Molimo pogledajte sjemensku frazu, spremite je i vratite novčanik.\n\nAko je vrijednost prazna, tada sjeme nije bilo u stanju ispravno oporaviti.",
@ -1071,4 +1072,4 @@
"you_will_send": "Razmijeni iz",
"youCanGoBackToYourDapp": "Sada se možete vratiti na svoj dapp",
"yy": "GG"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Պատճենել",
"copy_address": "Պատճենել հասցեն",
"copy_id": "Պատճենել ID",
"copy_payjoin_address": "Պատճենեք վճարման հասցեն",
"copy_payjoin_url": "Պատճենել Payjoin url",
"copyWalletConnectLink": "Պատճենել WalletConnect հղումը dApp-ից և տեղադրել այստեղ",
"corrupted_seed_notice": "Այս դրամապանակի համար ֆայլերը կոռումպացված են եւ չեն կարողանում բացվել: Խնդրում ենք դիտել սերմերի արտահայտությունը, պահպանել այն եւ վերականգնել դրամապանակը:\n\nԵթե ​​արժեքը դատարկ է, ապա սերմը չկարողացավ ճիշտ վերականգնվել:",
@ -1069,4 +1070,4 @@
"you_will_send": "Փոխանակեք",
"youCanGoBackToYourDapp": "Այժմ կարող եք վերադառնալ ձեր DAPP- ին",
"yy": "ՏՏ"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Salin",
"copy_address": "Salin Alamat",
"copy_id": "Salin ID",
"copy_payjoin_address": "Salin Alamat Payjoin",
"copy_payjoin_url": "Salin Payjoin url",
"copyWalletConnectLink": "Salin tautan WalletConnect dari dApp dan tempel di sini",
"corrupted_seed_notice": "File untuk dompet ini rusak dan tidak dapat dibuka. Silakan lihat frasa benih, simpan, dan kembalikan dompet.\n\nJika nilainya kosong, maka benih tidak dapat dipulihkan dengan benar.",
@ -1074,4 +1075,4 @@
"you_will_send": "Konversi dari",
"youCanGoBackToYourDapp": "Anda dapat kembali ke dapp Anda sekarang",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Copia",
"copy_address": "Copia Indirizzo",
"copy_id": "Copia ID",
"copy_payjoin_address": "Copia l'indirizzo PayJoin",
"copy_payjoin_url": "Copia Payjoin url",
"copyWalletConnectLink": "Copia il collegamento WalletConnect dalla dApp e incollalo qui",
"corrupted_seed_notice": "I file per questo portafoglio sono corrotti e non è possibile aprirli. Visualizza la frase del seme, salvala e ripristina il portafoglio.\n\nSe il valore è vuoto, non è stato possibile recuperare correttamente il seme.",
@ -1073,4 +1074,4 @@
"you_will_send": "Conveti da",
"youCanGoBackToYourDapp": "Puoi tornare al tuo DApp ora",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "コピー",
"copy_address": "住所をコピー",
"copy_id": "IDをコピー",
"copy_payjoin_address": "Payjoinアドレスをコピーします",
"copy_payjoin_url": "Payjoin urlをコピーします",
"copyWalletConnectLink": "dApp から WalletConnect リンクをコピーし、ここに貼り付けます",
"corrupted_seed_notice": "このウォレットのファイルは破損しており、開くことができません。シードフレーズを表示し、保存し、財布を復元してください。\n\n値が空の場合、種子を正しく回復することができませんでした。",
@ -1072,4 +1073,4 @@
"you_will_send": "から変換",
"youCanGoBackToYourDapp": "あなたは今あなたのダップに戻ることができます",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "복사",
"copy_address": "주소 복사",
"copy_id": "ID 복사",
"copy_payjoin_address": "Payjoin 주소를 복사하십시오",
"copy_payjoin_url": "Payjoin url을 복사하십시오",
"copyWalletConnectLink": "dApp에서 WalletConnect 링크를 복사하여 여기에 붙여넣으세요",
"corrupted_seed_notice": "이 지갑의 파일이 손상되어 열 수 없습니다. 시드 구문을 보고 저장한 다음 지갑을 복구하세요.\n\n값이 비어 있으면 시드를 올바르게 복구할 수 없었습니다.",
@ -1072,4 +1073,4 @@
"you_will_send": "전환 출처",
"youCanGoBackToYourDapp": "이제 dApp으로 돌아갈 수 있습니다",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "ကော်ပီ",
"copy_address": "လိပ်စာကို ကူးယူပါ။",
"copy_id": "ID ကူးယူပါ။",
"copy_payjoin_address": "Payjoin လိပ်စာကိုကူးယူပါ",
"copy_payjoin_url": "Payjoin URL ကိုကူးယူပါ",
"copyWalletConnectLink": "dApp မှ WalletConnect လင့်ခ်ကို ကူးယူပြီး ဤနေရာတွင် ကူးထည့်ပါ။",
"corrupted_seed_notice": "ဤပိုက်ဆံအိတ်အတွက်ဖိုင်များသည်အကျင့်ပျက်ခြစားမှုများနှင့်မဖွင့်နိုင်ပါ။ ကျေးဇူးပြု. မျိုးစေ့များကိုကြည့်ပါ, ၎င်းကိုသိမ်းဆည်းပါ, ပိုက်ဆံအိတ်ကိုပြန်ယူပါ။\n\nအကယ်. တန်ဖိုးသည်အချည်းနှီးဖြစ်ပါကမျိုးစေ့ကိုမှန်ကန်စွာပြန်လည်ကောင်းမွန်မရရှိနိုင်ပါ။",
@ -1071,4 +1072,4 @@
"you_will_send": "မှပြောင်းပါ။",
"youCanGoBackToYourDapp": "သငျသညျယခုသင်၏ dapp ကိုပြန်သွားနိုင်ပါတယ်",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kopiëren",
"copy_address": "Adres kopiëren",
"copy_id": "ID kopiëren",
"copy_payjoin_address": "Payjoin -adres kopiëren",
"copy_payjoin_url": "Kopieer Payjoin url",
"copyWalletConnectLink": "Kopieer de WalletConnect-link van dApp en plak deze hier",
"corrupted_seed_notice": "De bestanden voor deze portemonnee zijn beschadigd en kunnen niet worden geopend. Bekijk de zaadzin, bewaar deze en herstel de portemonnee.\n\nAls de waarde leeg is, kon het zaad niet correct worden hersteld.",
@ -1072,4 +1073,4 @@
"you_will_send": "Converteren van",
"youCanGoBackToYourDapp": "U kunt nu terug naar uw DApp gaan",
"yy": "JJ"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kopiuj",
"copy_address": "Skopiuj adress",
"copy_id": "skopiuj ID",
"copy_payjoin_address": "Kopiuj adres PAYJOIN",
"copy_payjoin_url": "Skopiuj Payjoin url",
"copyWalletConnectLink": "Skopiuj link do WalletConnect z dApp i wklej tutaj",
"corrupted_seed_notice": "Pliki dla tego portfela są uszkodzone i nie można ich otworzyć. Zobacz frazę seed, zapisz je i przywróć portfel.\n\nJeśli wartość jest pusta, frazy seed nie można było poprawnie odzyskać.",
@ -1071,4 +1072,4 @@
"you_will_send": "Konwertuj z",
"youCanGoBackToYourDapp": "Możesz teraz wrócić do swojego dapp",
"yy": "RR"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Copiar",
"copy_address": "Copiar endereço",
"copy_id": "Copiar ID",
"copy_payjoin_address": "Copie o endereço PayJoin",
"copy_payjoin_url": "Copie Payjoin url",
"copyWalletConnectLink": "Copie o link WalletConnect do dApp e cole aqui",
"corrupted_seed_notice": "Os arquivos para esta carteira estão corrompidos e não podem ser abertos. Veja a frase das sementes, salve -a e restaure a carteira.\n\nSe o valor estiver vazio, a semente não pôde ser recuperada corretamente.",
@ -1074,4 +1075,4 @@
"you_will_send": "Converter de",
"youCanGoBackToYourDapp": "Você pode voltar para o seu dapp agora",
"yy": "aa"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Скопировать",
"copy_address": "Cкопировать адрес",
"copy_id": "Скопировать ID",
"copy_payjoin_address": "Скопируйте адрес оплатывания",
"copy_payjoin_url": "Копировать Payjoin url",
"copyWalletConnectLink": "Скопируйте ссылку WalletConnect из dApp и вставьте сюда.",
"corrupted_seed_notice": "Файлы для этого кошелька повреждены и не могут быть открыты. Пожалуйста, просмотрите семенную фразу, сохраните ее и восстановите кошелек.\n\nЕсли значение пустое, то семя не смог правильно восстановить.",
@ -1072,4 +1073,4 @@
"you_will_send": "Конвертировать из",
"youCanGoBackToYourDapp": "Вы можете вернуться к своему даппу сейчас",
"yy": "ГГ"
}
}

View file

@ -202,6 +202,7 @@
"copy": "คัดลอก",
"copy_address": "คัดลอกที่อยู่",
"copy_id": "คัดลอก ID",
"copy_payjoin_address": "คัดลอกที่อยู่ PayJoin",
"copy_payjoin_url": "คัดลอก Payjoin url",
"copyWalletConnectLink": "คัดลอกลิงก์ WalletConnect จาก dApp แล้ววางที่นี่",
"corrupted_seed_notice": "ไฟล์สำหรับกระเป๋าเงินนี้เสียหายและไม่สามารถเปิดได้ โปรดดูวลีเมล็ดบันทึกและกู้คืนกระเป๋าเงิน\n\nหากค่าว่างเปล่าเมล็ดก็ไม่สามารถกู้คืนได้อย่างถูกต้อง",
@ -1071,4 +1072,4 @@
"you_will_send": "แปลงจาก",
"youCanGoBackToYourDapp": "คุณสามารถกลับไปที่ dapp ของคุณได้ทันที",
"yy": "ปี"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kopyahin",
"copy_address": "Kopyahin ang Address",
"copy_id": "Kopyahin ang ID",
"copy_payjoin_address": "Kopyahin ang address ng PayJoin",
"copy_payjoin_url": "Kopyahin ang Payjoin url",
"copyWalletConnectLink": "Kopyahin ang link ng WalletConnect mula sa dApp at i-paste dito",
"corrupted_seed_notice": "Ang mga file para sa pitaka na ito ay nasira at hindi mabubuksan. Mangyaring tingnan ang parirala ng binhi, i -save ito, at ibalik ang pitaka.\n\nKung ang halaga ay walang laman, kung gayon ang binhi ay hindi ma -recover nang tama.",
@ -1071,4 +1072,4 @@
"you_will_send": "I-convert mula sa",
"youCanGoBackToYourDapp": "Maaari kang bumalik sa iyong dapp ngayon",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Kopyala",
"copy_address": "Adresi kopyala",
"copy_id": "ID'yi kopyala",
"copy_payjoin_address": "PayJoin adresini kopyala",
"copy_payjoin_url": "Payjoin url kopyala",
"copyWalletConnectLink": "WalletConnect bağlantısını dApp'ten kopyalayıp buraya yapıştırın",
"corrupted_seed_notice": "Bu cüzdanın dosyaları bozuk ve açılamıyor. Lütfen tohum ifadesini görüntüleyin, kaydedin ve cüzdanı geri yükleyin.\n\nDeğer boşsa, tohum doğru bir şekilde geri kazanılamadı.",
@ -1071,4 +1072,4 @@
"you_will_send": "Biçiminden dönüştür:",
"youCanGoBackToYourDapp": "Şimdi Dapp'ınıza geri dönebilirsin",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Скопіювати",
"copy_address": "Cкопіювати адресу",
"copy_id": "Скопіювати ID",
"copy_payjoin_address": "Копіювати адресу Payjoin",
"copy_payjoin_url": "Скопіюйте Payjoin url",
"copyWalletConnectLink": "Скопіюйте посилання WalletConnect із dApp і вставте сюди",
"corrupted_seed_notice": "Файли для цього гаманця пошкоджені і не можуть бути відкриті. Перегляньте насіннєву фразу, збережіть її та відновіть гаманець.\n\nЯкщо значення порожнє, то насіння не могло бути правильно відновленим.",
@ -1072,4 +1073,4 @@
"you_will_send": "Конвертувати з",
"youCanGoBackToYourDapp": "Ви можете повернутися до свого DAPP зараз",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "کاپی",
"copy_address": "ایڈریس کاپی کریں۔",
"copy_id": "کاپی ID",
"copy_payjoin_address": "پے جوائن ایڈریس کاپی کریں",
"copy_payjoin_url": "کاپی کریں Payjoin url",
"copyWalletConnectLink": "dApp ﮯﺳ WalletConnect ۔ﮟﯾﺮﮐ ﭧﺴﯿﭘ ﮞﺎﮩﯾ ﺭﻭﺍ ﮟﯾﺮﮐ ﯽﭘﺎﮐ ﻮﮐ ﮏﻨﻟ",
"corrupted_seed_notice": "اس پرس کے لئے فائلیں خراب ہیں اور کھولنے سے قاصر ہیں۔ براہ کرم بیج کے فقرے کو دیکھیں ، اسے بچائیں ، اور بٹوے کو بحال کریں۔\n\nاگر قیمت خالی ہے ، تو بیج صحیح طور پر بازیافت کرنے سے قاصر تھا۔",
@ -1073,4 +1074,4 @@
"you_will_send": "سے تبدیل کریں۔",
"youCanGoBackToYourDapp": "اب آپ اپنے ڈی اے پی پی پر واپس جاسکتے ہیں",
"yy": "YY"
}
}

View file

@ -201,6 +201,7 @@
"copy": "Sao chép",
"copy_address": "Sao chép Địa chỉ",
"copy_id": "Sao chép ID",
"copy_payjoin_address": "Sao chép địa chỉ payjoin",
"copy_payjoin_url": "Sao chép Payjoin url",
"copyWalletConnectLink": "Sao chép liên kết WalletConnect từ dApp và dán vào đây",
"corrupted_seed_notice": "Các tệp cho ví này bị hỏng và không thể mở. Vui lòng xem cụm từ hạt giống, lưu nó và khôi phục ví.\n\nNếu giá trị trống, thì hạt giống không thể được phục hồi chính xác.",
@ -1068,4 +1069,4 @@
"you_will_send": "Chuyển đổi từ",
"youCanGoBackToYourDapp": "Bạn có thể quay lại DAPP của mình ngay bây giờ",
"yy": "YY"
}
}

View file

@ -202,6 +202,7 @@
"copy": "Ṣẹ̀dà",
"copy_address": "Ṣẹ̀dà àdírẹ́sì",
"copy_id": "Ṣẹ̀dà àmì ìdánimọ̀",
"copy_payjoin_address": "Daakọ Iwe Adirẹsi Payjoin",
"copy_payjoin_url": "Daakọ Payjoin url",
"copyWalletConnectLink": "Daakọ ọna asopọ WalletConnect lati dApp ki o si lẹẹmọ nibi",
"corrupted_seed_notice": "Awọn faili fun apamọwọ yii jẹ ibajẹ ati pe ko lagbara lati ṣii. Jọwọ wo ọrọ iseda, fipamọ rẹ, ki o mu apamọwọ naa pada.\n\nTi iye ba ṣofo, lẹhinna irugbin naa ko lagbara lati gba pada ni deede.",
@ -1072,4 +1073,4 @@
"you_will_send": "Ṣe pàṣípààrọ̀ láti",
"youCanGoBackToYourDapp": "O le pada si tapla rẹ bayi",
"yy": "Ọd"
}
}

View file

@ -202,6 +202,7 @@
"copy": "复制",
"copy_address": "复制地址",
"copy_id": "复制ID",
"copy_payjoin_address": "复制工资公司地址",
"copy_payjoin_url": "复制Payjoin url",
"copyWalletConnectLink": "从 dApp 复制 WalletConnect 链接并粘贴到此处",
"corrupted_seed_notice": "该钱包的文件被损坏,无法打开。请查看种子短语,保存并恢复钱包。\n\n如果该值为空则种子无法正确恢复。",
@ -1071,4 +1072,4 @@
"you_will_send": "转换自",
"youCanGoBackToYourDapp": "您现在可以回到DAPP",
"yy": "YY"
}
}

View file

@ -14,15 +14,15 @@ TYPES=($MONERO_COM $CAKEWALLET)
APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="4.27.0"
MONERO_COM_BUILD_NUMBER=121
MONERO_COM_VERSION="4.28.0"
MONERO_COM_BUILD_NUMBER=124
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.27.0"
CAKEWALLET_BUILD_NUMBER=259
CAKEWALLET_VERSION="4.28.0"
CAKEWALLET_BUILD_NUMBER=262
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
CAKEWALLET_SCHEME="cakewallet"

View file

@ -12,13 +12,13 @@ TYPES=($MONERO_COM $CAKEWALLET)
APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="4.27.1"
MONERO_COM_BUILD_NUMBER=120
MONERO_COM_VERSION="4.28.0"
MONERO_COM_BUILD_NUMBER=123
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.27.1"
CAKEWALLET_BUILD_NUMBER=314
CAKEWALLET_VERSION="4.28.0"
CAKEWALLET_BUILD_NUMBER=319
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"

View file

@ -14,8 +14,8 @@ if [ -n "$1" ]; then
fi
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.27.0"
CAKEWALLET_BUILD_NUMBER=54
CAKEWALLET_VERSION="4.28.0"
CAKEWALLET_BUILD_NUMBER=55
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="4.27.0"
MONERO_COM_BUILD_NUMBER=51
MONERO_COM_VERSION="4.28.0"
MONERO_COM_BUILD_NUMBER=53
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.27.0"
CAKEWALLET_BUILD_NUMBER=113
CAKEWALLET_VERSION="4.28.0"
CAKEWALLET_BUILD_NUMBER=115
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

View file

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