| 1 | import 'dart:async'; |
| 2 | |
| 3 | import 'package:cake_wallet/core/address_resolver/address_resolver_service.dart'; |
| 4 | import 'package:cake_wallet/core/address_resolver/address_sources.dart'; |
| 5 | import 'package:cake_wallet/entities/exchange_api_mode.dart'; |
| 6 | import 'package:cake_wallet/entities/fiat_api_mode.dart'; |
| 7 | import 'package:cake_wallet/evm/evm.dart'; |
| 8 | import 'package:cake_wallet/generated/i18n.dart'; |
| 9 | import 'package:cake_wallet/reactions/wallet_connect.dart'; |
| 10 | import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; |
| 11 | import 'package:cake_wallet/store/settings_store.dart'; |
| 12 | import 'package:cake_wallet/tron/tron.dart'; |
| 13 | import 'package:cake_wallet/utils/show_pop_up.dart'; |
| 14 | import 'package:cake_wallet/utils/tor.dart'; |
| 15 | import 'package:cw_core/balance.dart'; |
| 16 | import 'package:cw_core/transaction_history.dart'; |
| 17 | import 'package:cw_core/transaction_info.dart'; |
| 18 | import 'package:cw_core/wallet_base.dart'; |
| 19 | import 'package:cw_core/wallet_type.dart'; |
| 20 | import 'package:flutter/material.dart'; |
| 21 | import 'package:mobx/mobx.dart'; |
| 22 | |
| 23 | part 'connection_sync_view_model.g.dart'; |
| 24 | |
| 25 | class ConnectionSyncViewModel = ConnectionSyncViewModelBase with _$ConnectionSyncViewModel; |
| 26 | |
| 27 | abstract class ConnectionSyncViewModelBase with Store { |
| 28 | ConnectionSyncViewModelBase(this._settingsStore, this._wallet); |
| 29 | |
| 30 | final SettingsStore _settingsStore; |
| 31 | final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet; |
| 32 | |
| 33 | @computed |
| 34 | bool get lookupTwitter => _settingsStore.lookupsTwitter; |
| 35 | |
| 36 | @computed |
| 37 | bool get lookupsZanoAlias => _settingsStore.lookupsZanoAlias; |
| 38 | |
| 39 | @computed |
| 40 | bool get looksUpMastodon => _settingsStore.lookupsMastodon; |
| 41 | |
| 42 | @computed |
| 43 | bool get looksUpYatService => _settingsStore.lookupsYatService; |
| 44 | |
| 45 | @computed |
| 46 | bool get looksUpUnstoppableDomains => _settingsStore.lookupsUnstoppableDomains; |
| 47 | |
| 48 | @computed |
| 49 | bool get looksUpOpenAlias => _settingsStore.lookupsOpenAlias; |
| 50 | |
| 51 | @computed |
| 52 | bool get looksUpENS => _settingsStore.lookupsENS; |
| 53 | |
| 54 | @computed |
| 55 | bool get lookupsZcashNames => _settingsStore.lookupsZcashNames; |
| 56 | |
| 57 | @computed |
| 58 | bool get looksUpWellKnown => _settingsStore.lookupsWellKnown; |
| 59 | |
| 60 | @computed |
| 61 | bool get lookupsNostr => _settingsStore.lookupsNostr; |
| 62 | |
| 63 | @computed |
| 64 | bool get lookupsFio => _settingsStore.lookupsFio; |
| 65 | |
| 66 | @computed |
| 67 | bool get lookupsBip353 => _settingsStore.lookupsBip353; |
| 68 | |
| 69 | @computed |
| 70 | bool get lookupsThorChain => _settingsStore.lookupsThorChain; |
| 71 | |
| 72 | @computed |
| 73 | bool get lookupsZcashAddress => _settingsStore.lookupsZcashAddress; |
| 74 | |
| 75 | @computed |
| 76 | bool get lookupsLNUrlPay => _settingsStore.lookupsLNUrl; |
| 77 | |
| 78 | @computed |
| 79 | ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus; |
| 80 | |
| 81 | @computed |
| 82 | FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode; |
| 83 | |
| 84 | @computed |
| 85 | bool get disableAutomaticExchangeStatusUpdates => |
| 86 | _settingsStore.disableAutomaticExchangeStatusUpdates; |
| 87 | |
| 88 | @computed |
| 89 | bool get builtinTor => _settingsStore.currentBuiltinTor; |
| 90 | |
| 91 | List<AddressSource> get domainLookupSources => AddressResolverService.supportedSources; |
| 92 | |
| 93 | bool lookupValue(AddressSource source) { |
| 94 | switch (source) { |
| 95 | case AddressSource.twitter: |
| 96 | return lookupTwitter; |
| 97 | case AddressSource.mastodon: |
| 98 | return looksUpMastodon; |
| 99 | case AddressSource.yatRecord: |
| 100 | return looksUpYatService; |
| 101 | case AddressSource.unstoppableDomains: |
| 102 | return looksUpUnstoppableDomains; |
| 103 | case AddressSource.openAlias: |
| 104 | return looksUpOpenAlias; |
| 105 | case AddressSource.ens: |
| 106 | return looksUpENS; |
| 107 | case AddressSource.zcashName: |
| 108 | return lookupsZcashNames; |
| 109 | case AddressSource.zcashAddress: |
| 110 | return lookupsZcashAddress; |
| 111 | case AddressSource.wellKnown: |
| 112 | return looksUpWellKnown; |
| 113 | case AddressSource.zanoAlias: |
| 114 | return lookupsZanoAlias; |
| 115 | case AddressSource.bip353: |
| 116 | return lookupsBip353; |
| 117 | case AddressSource.fio: |
| 118 | return lookupsFio; |
| 119 | case AddressSource.lnurlPay: |
| 120 | return lookupsLNUrlPay; |
| 121 | case AddressSource.thorChain: |
| 122 | return lookupsThorChain; |
| 123 | case AddressSource.nostr: |
| 124 | return lookupsNostr; |
| 125 | case AddressSource.contact: |
| 126 | case AddressSource.notParsed: |
| 127 | return false; |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | @action |
| 132 | void setLookupValue(AddressSource source, bool value) { |
| 133 | switch (source) { |
| 134 | case AddressSource.twitter: |
| 135 | _settingsStore.lookupsTwitter = value; |
| 136 | break; |
| 137 | case AddressSource.mastodon: |
| 138 | _settingsStore.lookupsMastodon = value; |
| 139 | break; |
| 140 | case AddressSource.yatRecord: |
| 141 | _settingsStore.lookupsYatService = value; |
| 142 | break; |
| 143 | case AddressSource.unstoppableDomains: |
| 144 | _settingsStore.lookupsUnstoppableDomains = value; |
| 145 | break; |
| 146 | case AddressSource.openAlias: |
| 147 | _settingsStore.lookupsOpenAlias = value; |
| 148 | break; |
| 149 | case AddressSource.ens: |
| 150 | _settingsStore.lookupsENS = value; |
| 151 | break; |
| 152 | case AddressSource.zcashName: |
| 153 | _settingsStore.lookupsZcashNames = value; |
| 154 | break; |
| 155 | case AddressSource.zcashAddress: |
| 156 | _settingsStore.lookupsZcashAddress = value; |
| 157 | break; |
| 158 | case AddressSource.wellKnown: |
| 159 | _settingsStore.lookupsWellKnown = value; |
| 160 | break; |
| 161 | case AddressSource.zanoAlias: |
| 162 | _settingsStore.lookupsZanoAlias = value; |
| 163 | break; |
| 164 | case AddressSource.bip353: |
| 165 | _settingsStore.lookupsBip353 = value; |
| 166 | break; |
| 167 | case AddressSource.fio: |
| 168 | _settingsStore.lookupsFio = value; |
| 169 | break; |
| 170 | case AddressSource.lnurlPay: |
| 171 | _settingsStore.lookupsLNUrl = value; |
| 172 | break; |
| 173 | case AddressSource.thorChain: |
| 174 | _settingsStore.lookupsThorChain = value; |
| 175 | break; |
| 176 | case AddressSource.nostr: |
| 177 | _settingsStore.lookupsNostr = value; |
| 178 | break; |
| 179 | case AddressSource.contact: |
| 180 | case AddressSource.notParsed: |
| 181 | break; |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | @computed |
| 186 | bool get hasPowNodes => [WalletType.nano, WalletType.banano].contains(_wallet.type); |
| 187 | |
| 188 | @computed |
| 189 | bool get useMempoolFeeAPI => _settingsStore.useMempoolFeeAPI; |
| 190 | |
| 191 | @computed |
| 192 | bool get canUseMempoolFeeAPI => _wallet.type == WalletType.bitcoin; |
| 193 | |
| 194 | @computed |
| 195 | bool get useBlinkProtection => _settingsStore.useBlinkProtection; |
| 196 | |
| 197 | bool get canUseBlinkProtection => canSupportBlinkProtection(_wallet.chainId); |
| 198 | |
| 199 | @computed |
| 200 | bool get useEtherscan => _settingsStore.useEtherscan; |
| 201 | |
| 202 | @computed |
| 203 | bool get usePolygonScan => _settingsStore.usePolygonScan; |
| 204 | |
| 205 | @computed |
| 206 | bool get useBaseScan => _settingsStore.useBaseScan; |
| 207 | |
| 208 | @computed |
| 209 | bool get useArbiScan => _settingsStore.useArbiScan; |
| 210 | |
| 211 | @computed |
| 212 | bool get useBscScan => _settingsStore.useBscScan; |
| 213 | |
| 214 | @computed |
| 215 | bool get useTronGrid => _settingsStore.useTronGrid; |
| 216 | |
| 217 | @computed |
| 218 | bool get canUseEtherscan => _wallet.chainId == 1; |
| 219 | |
| 220 | @computed |
| 221 | bool get canUsePolygonScan => _wallet.chainId == 137; |
| 222 | |
| 223 | @computed |
| 224 | bool get canUseBaseScan => _wallet.chainId == 8453; |
| 225 | |
| 226 | @computed |
| 227 | bool get canUseArbiScan => _wallet.chainId == 42161; |
| 228 | |
| 229 | @computed |
| 230 | bool get canUseBscScan => _wallet.chainId == 56; |
| 231 | |
| 232 | @computed |
| 233 | bool get canUseTronGrid => _wallet.type == WalletType.tron; |
| 234 | |
| 235 | @action |
| 236 | void setUseMempoolFeeAPI(bool value) => _settingsStore.useMempoolFeeAPI = value; |
| 237 | |
| 238 | @action |
| 239 | void setDisableAutomaticExchangeStatusUpdates(bool value) => |
| 240 | _settingsStore.disableAutomaticExchangeStatusUpdates = value; |
| 241 | |
| 242 | @action |
| 243 | void setFiatMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode; |
| 244 | |
| 245 | @action |
| 246 | void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value; |
| 247 | |
| 248 | @action |
| 249 | void setUseBlinkProtection(bool value) => _settingsStore.useBlinkProtection = value; |
| 250 | |
| 251 | bool get hasRescan => |
| 252 | _wallet.hasRescan && |
| 253 | _wallet.type != WalletType.bitcoin && |
| 254 | _wallet.type != WalletType.litecoin; |
| 255 | |
| 256 | @action |
| 257 | void setUseEtherscan(bool value) { |
| 258 | _settingsStore.useEtherscan = value; |
| 259 | evm!.updateScanProviderUsageState(_wallet, value); |
| 260 | } |
| 261 | |
| 262 | @action |
| 263 | void setUsePolygonScan(bool value) { |
| 264 | _settingsStore.usePolygonScan = value; |
| 265 | evm!.updateScanProviderUsageState(_wallet, value); |
| 266 | } |
| 267 | |
| 268 | @action |
| 269 | void setUseBaseScan(bool value) { |
| 270 | _settingsStore.useBaseScan = value; |
| 271 | evm!.updateScanProviderUsageState(_wallet, value); |
| 272 | } |
| 273 | |
| 274 | @action |
| 275 | void setUseTronGrid(bool value) { |
| 276 | _settingsStore.useTronGrid = value; |
| 277 | tron!.updateTronGridUsageState(_wallet, value); |
| 278 | } |
| 279 | |
| 280 | @action |
| 281 | void setUseArbiScan(bool value) { |
| 282 | _settingsStore.useArbiScan = value; |
| 283 | evm!.updateScanProviderUsageState(_wallet, value); |
| 284 | } |
| 285 | |
| 286 | @action |
| 287 | void setUseBscScan(bool value) { |
| 288 | _settingsStore.useBscScan = value; |
| 289 | evm!.updateScanProviderUsageState(_wallet, value); |
| 290 | } |
| 291 | |
| 292 | @action |
| 293 | void setBuiltinTor(bool value, BuildContext context) { |
| 294 | if (value) { |
| 295 | unawaited( |
| 296 | showPopUp<bool>( |
| 297 | context: context, |
| 298 | builder: (BuildContext context) { |
| 299 | return AlertWithOneAction( |
| 300 | alertTitle: S.of(context).tor_connection, |
| 301 | alertContent: S.of(context).tor_experimental, |
| 302 | buttonText: S.of(context).ok, |
| 303 | buttonAction: () => Navigator.of(context).pop(true), |
| 304 | ); |
| 305 | }, |
| 306 | ), |
| 307 | ); |
| 308 | } |
| 309 | _settingsStore.currentBuiltinTor = value; |
| 310 | if (value) { |
| 311 | unawaited(ensureTorStarted(context: context).then((_) async { |
| 312 | if (_settingsStore.currentBuiltinTor == false) return; |
| 313 | int? chainId; |
| 314 | if (isEVMCompatibleChain(_wallet.type)) { |
| 315 | chainId = evm!.getSelectedChainId(_wallet); |
| 316 | } |
| 317 | await _wallet.connectToNode( |
| 318 | node: _settingsStore.getCurrentNode(_wallet.type, chainId: chainId)); |
| 319 | })); |
| 320 | } else { |
| 321 | unawaited(ensureTorStopped(context: context).then((_) async { |
| 322 | if (_settingsStore.currentBuiltinTor == true) return; |
| 323 | int? chainId; |
| 324 | if (isEVMCompatibleChain(_wallet.type)) { |
| 325 | chainId = evm!.getSelectedChainId(_wallet); |
| 326 | } |
| 327 | await _wallet.connectToNode( |
| 328 | node: _settingsStore.getCurrentNode(_wallet.type, chainId: chainId)); |
| 329 | })); |
| 330 | } |
| 331 | } |
| 332 | } |