dev
dart 140 lines 4.75 KB
Raw
1 import "package:cake_wallet/core/anypay/anypay_models.dart";
2 import "package:cake_wallet/core/anypay/anypay_parser.dart";
3 import "package:cake_wallet/core/anypay/anypay_resolver.dart";
4 import "package:cake_wallet/core/anypay/anypay_router.dart";
5 import "package:cake_wallet/evm/evm.dart";
6 import "package:cake_wallet/new-ui/services/wallet_switch_service.dart";
7 import "package:cake_wallet/reactions/wallet_connect.dart";
8 import "package:cake_wallet/solana/solana.dart";
9 import "package:cake_wallet/store/app_store.dart";
10 import "package:cake_wallet/tron/tron.dart";
11 import "package:cake_wallet/utils/payment_request.dart";
12 import "package:cw_core/amount/money.dart";
13 import "package:cw_core/crypto_currency.dart";
14 import "package:cw_core/currency_for_wallet_type.dart";
15 import "package:cw_core/utils/print_verbose.dart";
16 import "package:cw_core/wallet_info.dart";
17 import "package:cw_core/wallet_type.dart";
18
19 class AnyPayService {
20 AnyPayService({
21 required this.appStore,
22 required this.walletSwitchService,
23 AnyPayResolver? resolver,
24 }) : resolver = resolver ?? AnyPayResolver();
25
26 final AppStore appStore;
27 final WalletSwitchService walletSwitchService;
28 final AnyPayResolver resolver;
29
30 Future<AnyPayEvaluation> evaluateRawInput(String input) => _evaluate(AnyPayParser.fromRaw(input));
31
32 Future<AnyPayEvaluation> evaluatePaymentRequest(PaymentRequest request) =>
33 _evaluate(AnyPayParser.fromPaymentRequest(request));
34
35 Future<AnyPayEvaluation> evaluateForEvmChain(AnyPayRequest request, int chainId) => _evaluate(
36 AnyPayRequest(
37 rawInput: request.rawInput,
38 paymentRequest: request.paymentRequest,
39 detection: request.detection,
40 chainBinding: ExplicitEvmChain(chainId),
41 ),
42 );
43
44 Future<AnyPayEvaluation> _evaluate(AnyPayRequest request) async {
45 try {
46 final snapshot = await _buildWalletSnapshot();
47 final resolution = await resolver.resolve(request, snapshot);
48
49 return AnyPayEvaluation(
50 request: request,
51 decision: AnyPayRouter.route(request, snapshot, resolution),
52 );
53 } catch (e) {
54 printV("anypay evaluation failed: $e");
55 return AnyPayEvaluation(
56 request: request,
57 decision: const AnyPayApplyToCurrentWallet(),
58 );
59 }
60 }
61
62 Future<WalletSnapshot> _buildWalletSnapshot() async {
63 final wallet = appStore.wallet!;
64 final currentWalletIsEvm = isEVMCompatibleChain(wallet.type);
65
66 final supportedEvmChains = <int, WalletType>{};
67 if (evm != null) {
68 for (final chain in evm!.getAllChains()) {
69 final walletType = evm!.getWalletTypeByChainId(chain.chainId);
70 if (walletType != null) {
71 supportedEvmChains[chain.chainId] = walletType;
72 }
73 }
74 }
75
76 return WalletSnapshot(
77 type: wallet.type,
78 currentWalletIsEvm: currentWalletIsEvm,
79 currentChainId: currentWalletIsEvm && evm != null
80 ? evm!.getSelectedChainId(wallet) ?? evm!.getChainIdByWalletType(wallet.type)
81 : null,
82 wallets: await WalletInfo.getAll(),
83 supportedEvmChains: supportedEvmChains,
84 hasEvmProxy: evm != null,
85 hasSolanaProxy: solana != null,
86 hasTronProxy: tron != null,
87 );
88 }
89
90 AnyPaySwapIntent buildSwapIntent(
91 AnyPayRequest request, {
92 required WalletType targetWalletType,
93 int? targetChainId,
94 CryptoCurrency? token,
95 }) {
96 final receiveCurrency = token ??
97 (targetChainId != null
98 ? walletTypeToCryptoCurrency(targetWalletType, chainId: targetChainId)
99 : request.detection.detectedCurrency ?? walletTypeToCryptoCurrency(targetWalletType));
100
101 final amountValue = token != null
102 ? request.paymentRequest.resolveTokenAmount(token)
103 : (request.amount.isNotEmpty ? request.amount : null);
104
105 return AnyPaySwapIntent(
106 request: request,
107 receiveCurrency: receiveCurrency,
108 targetWalletType: targetWalletType,
109 receiveAmount: amountValue != null ? Money.tryParse(amountValue, receiveCurrency) : null,
110 );
111 }
112
113 Future<bool> switchWalletForPayment(WalletInfo walletInfo, {int? chainId}) async {
114 try {
115 await walletSwitchService.switchToWallet(walletInfo);
116 } catch (e) {
117 printV("wallet switch failed: $e");
118 return false;
119 }
120
121 final wallet = appStore.wallet!;
122 if (chainId != null && evm != null && isEVMCompatibleChain(wallet.type)) {
123 try {
124 final node = appStore.settingsStore.getCurrentNode(wallet.type, chainId: chainId);
125 await evm!.selectChain(wallet, chainId, node: node);
126 } catch (e, s) {
127 printV("switchWalletForPayment chain select failed: $e\n$s");
128 return false;
129 }
130 }
131
132 try {
133 await wallet.updateBalance();
134 } catch (e) {
135 printV("balance refresh after wallet switch failed: $e");
136 }
137
138 return true;
139 }
140 }