Merge branch 'dev' into cw-1440-new-buy-sell-flow

This commit is contained in:
malik1004x
2026-08-20 16:26:13 +02:00
committed by GitHub
220 changed files with 11956 additions and 9280 deletions
@@ -203,7 +203,7 @@ class TransactionListItem extends ActionListItem with Keyable {
case WalletType.decred:
case WalletType.zcash:
amount = calculateFiatAmountRaw(
cryptoAmount: transaction.amount.toDouble(),
cryptoAmount: double.parse(transaction.amount.toString()),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
case WalletType.ethereum:
@@ -214,15 +214,15 @@ class TransactionListItem extends ActionListItem with Keyable {
final asset = assetOfTransaction;
final price = balanceViewModel.fiatConversionStore.prices[asset];
amount = calculateFiatAmountRaw(
cryptoAmount: transaction.amount.toDouble(),
cryptoAmount: double.parse(transaction.amount.toString()),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
case WalletType.solana:
final asset = assetOfTransaction;
final asset = solana!.assetOfTransaction(balanceViewModel.wallet, transaction);
final price = balanceViewModel.fiatConversionStore.prices[asset];
amount = calculateFiatAmountRaw(
cryptoAmount: transaction.amount.toDouble(),
cryptoAmount: double.parse(transaction.amount.toString()),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
@@ -230,7 +230,7 @@ class TransactionListItem extends ActionListItem with Keyable {
final asset = tron!.assetOfTransaction(balanceViewModel.wallet, transaction);
final price = balanceViewModel.fiatConversionStore.prices[asset];
amount = calculateFiatAmountRaw(
cryptoAmount: transaction.amount.toDouble(),
cryptoAmount: double.parse(transaction.amount.toString()),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
@@ -242,7 +242,7 @@ class TransactionListItem extends ActionListItem with Keyable {
}
final price = balanceViewModel.fiatConversionStore.prices[asset];
amount = calculateFiatAmountRaw(
cryptoAmount: transaction.amount.toDouble(),
cryptoAmount: double.parse(transaction.amount.toString()),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
@@ -2,12 +2,10 @@ import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:developer';
import 'dart:math' show min;
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/core/amount_parsing_proxy.dart';
import 'package:cake_wallet/core/create_trade_result.dart';
import 'package:cake_wallet/core/fiat_conversion_service.dart';
@@ -415,6 +413,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
@observable
bool tradeStarted = false;
@observable
bool noProviderForPair = false;
@observable
bool isSendFromExternal = false;
@@ -980,6 +981,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
bestRate = _sortedAvailableProviders.keys.first;
bestRateProvider = _sortedAvailableProviders.values.first;
}
noProviderForPair = _sortedAvailableProviders.isEmpty;
}
@action
@@ -1603,24 +1605,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
}
}
String? _addressTypeValidation(String refundAddress, String receiveAddress) {
final isRefundAddressSP =
RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(refundAddress);
if (isRefundAddressSP) return 'Silent Payment ${S.current.address_not_allowed_as_refund}';
final isReceiveAddressSP =
RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(receiveAddress);
if (isReceiveAddressSP) return 'Silent Payment ${S.current.address_not_allowed_as_receive}';
final isRefundAddressMWEB = RegExp(AddressValidator.mWebAddressPattern).hasMatch(refundAddress);
if (isRefundAddressMWEB) return 'MWEB ${S.current.address_not_allowed_as_refund}';
final isReceiveAddressMWEB =
RegExp(AddressValidator.mWebAddressPattern).hasMatch(receiveAddress);
if (isReceiveAddressMWEB) return 'MWEB ${S.current.address_not_allowed_as_receive}';
return null;
}
void _defineIsReceiveAmountEditable() {
/*if ((provider is ChangeNowExchangeProvider)
&&(depositCurrency == CryptoCurrency.xmr)
@@ -42,8 +42,6 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
}
});
updateBleState();
if (!Platform.isIOS) {
ledgerPlusUSB = sdk.LedgerInterface.usb();
}
@@ -39,7 +39,6 @@ abstract class TrezorConnectViewModelBase extends HardwareWalletViewModel with S
_initBLE();
}
});
updateBleState();
if (!Platform.isIOS) {
trezorUSB = sdk.TrezorInterface.usb();
+21 -2
View File
@@ -25,6 +25,10 @@ class LinkViewModel {
Uri? currentLink;
bool readyToOpenPage = false;
final StreamController<Uri> _incomingPaymentLinksController = StreamController<Uri>.broadcast();
Stream<Uri> get incomingPaymentLinks => _incomingPaymentLinksController.stream;
bool get _isValidPaymentUri => currentLink?.path.isNotEmpty ?? false;
bool get isWalletConnectLink => currentLink?.authority == 'wc';
bool get isNanoGptLink => currentLink?.scheme == 'nano-gpt';
@@ -96,7 +100,10 @@ class LinkViewModel {
}
if (_isValidPaymentUri) {
return {"paymentRequest": PaymentRequest.fromUri(currentLink)};
return {
"paymentRequest": PaymentRequest.fromUri(currentLink),
"rawLink": currentLink.toString(),
};
}
return null;
@@ -132,8 +139,20 @@ class LinkViewModel {
return;
}
// Prevent navigating to the same route again.
if (route == Routes.send &&
!isQuickActionLink &&
currentLink != null &&
_incomingPaymentLinksController.hasListener) {
final link = currentLink!;
currentLink = null;
_incomingPaymentLinksController.add(link);
return;
}
// Prevent navigating to the same route again and clear the link so a later auth
// event cannot refire it.
if (appStore.currentRouteName == route) {
currentLink = null;
return;
}
@@ -11,6 +11,7 @@ import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
import 'package:cw_core/currency_for_wallet_type.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:bip39/bip39.dart' as bip39;
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:collection/collection.dart';
@@ -89,9 +90,7 @@ class WalletRestoreFromQRCode {
try {
return AddressResolverUtils.extractAddressByType(
raw: rawString,
type: walletTypeToCryptoCurrency(
type,
),
type: walletTypeToCryptoCurrency(type),
requireSurroundingWhitespaces: false,
);
} catch (_) {
@@ -127,8 +126,8 @@ class WalletRestoreFromQRCode {
final prefix = code.startsWith('xpub')
? 'xpub'
: code.startsWith('zpub')
? 'zpub'
: '????';
? 'zpub'
: '????';
if (walletType == null) {
await _specifyWalletAssets(context, "Can't determine wallet type, please pick it manually");
walletType =
@@ -140,8 +139,8 @@ class WalletRestoreFromQRCode {
formattedUri = seedPhrase != null
? '$walletType:?seed=$seedPhrase'
: code.startsWith(prefix)
? '$walletType:?$prefix=$code'
: throw Exception('Failed to determine valid seed phrase');
? '$walletType:?$prefix=$code'
: throw Exception('Failed to determine valid seed phrase');
} else {
final index = code.indexOf(':');
final query = code.substring(index + 1).replaceAll('?', '&');
@@ -202,9 +201,15 @@ class WalletRestoreFromQRCode {
seedValue.split(' ').forEach((element) {
if (!words.contains(element)) {
throw Exception(
"Unexpected restore mode: mnemonic_seed is invalid or doesn't match wallet type");
"Unexpected restore mode: mnemonic_seed is invalid or doesn't match wallet type",
);
}
});
if (isEVMCompatibleChain(type) && !bip39.validateMnemonic(seedValue)) {
throw Exception(
'EVM mnemonic has an invalid checksum. Please check the seed phrase for typos.',
);
}
return WalletRestoreMode.seed;
}
@@ -268,12 +273,14 @@ class WalletRestoreFromQRCode {
Future<void> _specifyWalletAssets(BuildContext context, String error) async {
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.current.error,
alertContent: error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.current.error,
alertContent: error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
},
);
}
+10 -5
View File
@@ -126,9 +126,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
super(appStore: _appStore) {
outputs.add(Output(wallet, _appStore, _fiatConversationStore, _outputCryptoCurrencyHandler));
unspentCoinsListViewModel
.initialSetup();
// .then((_) => unspentCoinsListViewModel.resetUnspentCoinsInfoSelections());
unspentCoinsListViewModel.initialSetup();
// .then((_) => unspentCoinsListViewModel.resetUnspentCoinsInfoSelections());
reaction((_) {
if (isEVMCompatibleChain(wallet.type)) {
@@ -1718,9 +1717,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
String? payjoinUri;
@action
Future<void> fetchTokenForContractAddress(String contractAddress) async {
Future<void> fetchTokenForContractAddress(String contractAddress,
{WalletType? walletType}) async {
final token = await TokenUtilities.findTokenByAddress(
walletType: wallet.type,
walletType: walletType ?? wallet.type,
address: contractAddress,
);
@@ -1729,6 +1729,11 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
}
@action
void applyAnyPayCurrency(CryptoCurrency currency) {
selectedCryptoCurrency = currency;
}
String _decodeMethodSelector(String s) =>
(s.startsWith('0x') && s.length >= 10) ? s.substring(0, 10) : '';
}