mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
* 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>
110 lines
3.5 KiB
Dart
110 lines
3.5 KiB
Dart
import "package:cake_wallet/core/anypay/anypay_models.dart";
|
|
import "package:cake_wallet/core/anypay/anypay_router.dart";
|
|
import "package:cake_wallet/reactions/wallet_connect.dart";
|
|
import "package:cake_wallet/utils/token_utilities.dart";
|
|
import "package:cw_core/crypto_currency.dart";
|
|
import "package:cw_core/wallet_type.dart";
|
|
|
|
class AnyPayResolver {
|
|
AnyPayResolver({AnyPayTokenLookup? tokenLookup})
|
|
: _tokenLookup = tokenLookup ?? const TokenUtilitiesLookup();
|
|
|
|
final AnyPayTokenLookup _tokenLookup;
|
|
|
|
Future<AnyPayResolution> resolve(AnyPayRequest request, WalletSnapshot snapshot) async {
|
|
if (!request.hasContract) {
|
|
return const NoTokenRequested();
|
|
}
|
|
|
|
final contract = request.contractAddress!;
|
|
final detectedType = request.detection.detectedWalletType;
|
|
|
|
if (detectedType != null && isEVMCompatibleChain(detectedType)) {
|
|
return _resolveEvm(request, snapshot, contract);
|
|
}
|
|
|
|
final token = await _tokenLookup.findTokenByAddress(
|
|
walletType: detectedType ?? snapshot.type,
|
|
address: contract,
|
|
);
|
|
|
|
if (token == null) {
|
|
return TokenUnknown(contract);
|
|
}
|
|
|
|
return TokenResolved(
|
|
token: token,
|
|
amountOverride: request.paymentRequest.resolveTokenAmount(token),
|
|
);
|
|
}
|
|
|
|
Future<AnyPayResolution> _resolveEvm(
|
|
AnyPayRequest request,
|
|
WalletSnapshot snapshot,
|
|
String contract,
|
|
) async {
|
|
final requestedChainId = AnyPayRouter.requestedEvmChainId(request, snapshot) ?? 1;
|
|
|
|
final lookupType = snapshot.supportedEvmChains[requestedChainId];
|
|
if (lookupType != null) {
|
|
final token =
|
|
await _tokenLookup.findTokenByAddress(walletType: lookupType, address: contract);
|
|
if (token != null) {
|
|
return TokenResolved(
|
|
token: token,
|
|
chainId: requestedChainId,
|
|
amountOverride: request.paymentRequest.resolveTokenAmount(token),
|
|
);
|
|
}
|
|
}
|
|
|
|
// The QRs from our old app versions omit the chainId on mainnet, so a contract the target
|
|
// network does not know may still belong to another EVM network.
|
|
if (request.chainBinding is ChainlessEvm) {
|
|
final reboundChainId = await _tokenLookup.findEvmChainIdForContract(
|
|
contract,
|
|
excludingChainId: requestedChainId,
|
|
);
|
|
final reboundType =
|
|
reboundChainId != null ? snapshot.supportedEvmChains[reboundChainId] : null;
|
|
if (reboundType != null) {
|
|
final token =
|
|
await _tokenLookup.findTokenByAddress(walletType: reboundType, address: contract);
|
|
if (token != null) {
|
|
return TokenResolved(
|
|
token: token,
|
|
chainId: reboundChainId,
|
|
amountOverride: request.paymentRequest.resolveTokenAmount(token),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return TokenUnknown(contract);
|
|
}
|
|
}
|
|
|
|
abstract class AnyPayTokenLookup {
|
|
Future<CryptoCurrency?> findTokenByAddress({
|
|
required WalletType walletType,
|
|
required String address,
|
|
});
|
|
|
|
Future<int?> findEvmChainIdForContract(String contractAddress, {int? excludingChainId});
|
|
}
|
|
|
|
class TokenUtilitiesLookup implements AnyPayTokenLookup {
|
|
const TokenUtilitiesLookup();
|
|
|
|
@override
|
|
Future<CryptoCurrency?> findTokenByAddress({
|
|
required WalletType walletType,
|
|
required String address,
|
|
}) =>
|
|
TokenUtilities.findTokenByAddress(walletType: walletType, address: address);
|
|
|
|
@override
|
|
Future<int?> findEvmChainIdForContract(String contractAddress, {int? excludingChainId}) =>
|
|
TokenUtilities.findEvmChainIdForContract(contractAddress, excludingChainId: excludingChainId);
|
|
}
|