CW1612: AnyPay Service Layer (#3516)

* fix android CI

* feat: add anypay core models, parser and routing engine

* feat: add anypay resolver, anypay service and wallet switch service

* refactor: route the send page payment flow through anypay service

* fix: show message when there's no swap providers for a pair and reset the trade guard on dismissal

* refactor: merge the swap from network and send to network decision pages together and clean up anypay widgets

* feat: reapply deep links to a currently open send flow and register the solana scheme

* feat: add support for zcash address detection to anypay and other minor fixes

* refactor: remove trailing icon

* feat: hide swap flow for sp and mweb addresses

* feat: enhance zcash address detection and deeplink handling

* fix: pin bitcoin_base

* refactor: Move the anypay decision navigation out of the send page and address minor review comments

* refactor: Move the anypay decision navigation out of the send page and address minor review comments

* feat: handle exception in switch service and mvoe balance compute to call site

* refactor: combine anypay entry points to one and extract selected mode widget

---------

Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
This commit is contained in:
David Adegoke
2026-08-20 09:35:44 +02:00
committed by GitHub
co-authored by Czarek Nakamoto
parent 4cc1495686
commit 3b100eae33
67 changed files with 2672 additions and 1210 deletions
@@ -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)