| 1 | import 'package:cake_wallet/core/address_resolver/address_lookup_provider.dart'; |
| 2 | import 'package:cake_wallet/core/address_resolver/address_sources.dart'; |
| 3 | import 'package:cake_wallet/core/address_resolver/bip_353/bip_353_address_provider.dart'; |
| 4 | import 'package:cake_wallet/core/address_resolver/ens/ens_address_provider.dart'; |
| 5 | import 'package:cake_wallet/core/address_resolver/fio/fio_address_provider.dart'; |
| 6 | import 'package:cake_wallet/core/address_resolver/lnurl_pay/lnurl_pay_address_provider.dart'; |
| 7 | import 'package:cake_wallet/core/address_resolver/mastodon/mastodon_address_provider.dart'; |
| 8 | import 'package:cake_wallet/core/address_resolver/nostr/nostr_address_provider.dart'; |
| 9 | import 'package:cake_wallet/core/address_resolver/openalias/openalias_address_provider.dart'; |
| 10 | import 'package:cake_wallet/core/address_resolver/parsed_address.dart'; |
| 11 | import 'package:cake_wallet/core/address_resolver/thorchain/thorchain_address_provider.dart'; |
| 12 | import 'package:cake_wallet/core/address_resolver/twitter/twitter_address_provider.dart'; |
| 13 | import 'package:cake_wallet/core/address_resolver/unstoppable/unstoppable_address_provider.dart'; |
| 14 | import 'package:cake_wallet/core/address_resolver/wellknown/wellknown_address_provider.dart'; |
| 15 | import 'package:cake_wallet/core/address_resolver/yat/yat_address_provider.dart'; |
| 16 | import 'package:cake_wallet/core/address_resolver/zano/zano_alias_address_provider.dart'; |
| 17 | import 'package:cake_wallet/core/address_resolver/zcash/zcash_address_provider.dart'; |
| 18 | import 'package:cake_wallet/core/address_resolver/zcash/zcash_me_address_provider.dart'; |
| 19 | import 'package:cake_wallet/store/settings_store.dart'; |
| 20 | import 'package:cw_core/crypto_currency.dart'; |
| 21 | import 'package:cw_core/utils/print_verbose.dart'; |
| 22 | import 'package:cw_core/wallet_base.dart'; |
| 23 | |
| 24 | class AddressResolverService { |
| 25 | AddressResolverService({required this.settingsStore}); |
| 26 | |
| 27 | final SettingsStore settingsStore; |
| 28 | |
| 29 | // Sources available for address resolution and lookup settings. |
| 30 | static const supportedSources = [ |
| 31 | AddressSource.lnurlPay, |
| 32 | AddressSource.twitter, |
| 33 | AddressSource.mastodon, |
| 34 | AddressSource.yatRecord, |
| 35 | AddressSource.unstoppableDomains, |
| 36 | AddressSource.openAlias, |
| 37 | AddressSource.ens, |
| 38 | AddressSource.zcashName, |
| 39 | AddressSource.zcashAddress, |
| 40 | AddressSource.wellKnown, |
| 41 | AddressSource.zanoAlias, |
| 42 | AddressSource.bip353, |
| 43 | AddressSource.fio, |
| 44 | AddressSource.thorChain, |
| 45 | AddressSource.nostr, |
| 46 | ]; |
| 47 | |
| 48 | List<AddressLookupProvider> _buildProviders() { |
| 49 | final allProviders = <AddressLookupProvider>[ |
| 50 | LNUrlPayAddressProvider(), |
| 51 | TwitterAddressProvider(), |
| 52 | MastodonAddressProvider(), |
| 53 | YatAddressProvider(), |
| 54 | UnstoppableAddressProvider(), |
| 55 | OpenaliasAddressProvider(), |
| 56 | EnsAddressProvider(), |
| 57 | ZcashNameAddressProvider(), |
| 58 | ZcashMeAddressProvider(), |
| 59 | WellKnownAddressProvider(), |
| 60 | ZanoAliasAddressProvider(), |
| 61 | Bip353AddressProvider(), |
| 62 | FioAddressProvider(), |
| 63 | ThorchainAddressProvider(), |
| 64 | NostrAddressProvider(), |
| 65 | ]; |
| 66 | |
| 67 | return allProviders.where((provider) => supportedSources.contains(provider.source)).toList(); |
| 68 | } |
| 69 | |
| 70 | Future<List<ParsedAddress>> resolve({ |
| 71 | required String query, |
| 72 | required WalletBase wallet, |
| 73 | required CryptoCurrency currency, |
| 74 | }) async { |
| 75 | try { |
| 76 | final providers = _buildProviders(); |
| 77 | // return first entry if currency is specified and provider supports it |
| 78 | if (currency != null) { |
| 79 | for (final provider in providers) { |
| 80 | final cur = currency.title; |
| 81 | final src = provider.source.label; |
| 82 | |
| 83 | printV('[address resolver service] checking $src - $cur - $query'); |
| 84 | if (!provider.isEnabled(settingsStore)) { |
| 85 | printV('[address resolver service] ...skipping $src (disabled)'); |
| 86 | continue; |
| 87 | } |
| 88 | if (!provider.canHandle(query)) { |
| 89 | printV('[address resolver service] ...skipping $src (cannot handle)'); |
| 90 | continue; |
| 91 | } |
| 92 | if (!provider.supportedCurrencies.contains(currency)) { |
| 93 | printV('[address resolver service] ...skipping $src (unsupported currency)'); |
| 94 | continue; |
| 95 | } |
| 96 | |
| 97 | try { |
| 98 | printV('[address resolver service] ...resolving $src - $cur - $query'); |
| 99 | final results = await provider.resolve( |
| 100 | query: query, |
| 101 | currencies: [currency], |
| 102 | wallet: wallet, |
| 103 | ); |
| 104 | |
| 105 | if (results.isNotEmpty) { |
| 106 | final parsedAddress = results.first.parsedAddressByCurrencyMap[currency]; |
| 107 | final parsedAddressStr = |
| 108 | parsedAddress == null || parsedAddress.isEmpty ? 'N/A' : parsedAddress; |
| 109 | printV('[address resolver service] resolved $src - $cur - $parsedAddressStr'); |
| 110 | return [results.first]; |
| 111 | } |
| 112 | } catch (e) { |
| 113 | printV('[address resolver service] Error resolving $src: $e'); |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | return []; |
| 118 | } |
| 119 | |
| 120 | return []; // TODO: Implement multi-currency resolution if no specific currency is provided. |
| 121 | |
| 122 | final tasks = <Future<List<ParsedAddress>>>[]; |
| 123 | |
| 124 | for (final provider in providers) { |
| 125 | if (!provider.isEnabled(settingsStore)) continue; |
| 126 | if (!provider.canHandle(query)) continue; |
| 127 | |
| 128 | tasks.add( |
| 129 | provider.resolve( |
| 130 | query: query, |
| 131 | currencies: provider.supportedCurrencies, |
| 132 | wallet: wallet, |
| 133 | ), |
| 134 | ); |
| 135 | } |
| 136 | |
| 137 | final results = await Future.wait(tasks); |
| 138 | return results.expand((items) => items).toList(); |
| 139 | } catch (e) { |
| 140 | printV('Error resolving address: $e'); |
| 141 | return []; |
| 142 | } |
| 143 | } |
| 144 | } |