diff --git a/.github/workflows/pr_test_build_android.yml b/.github/workflows/pr_test_build_android.yml index e9665e179..e0adbf571 100644 --- a/.github/workflows/pr_test_build_android.yml +++ b/.github/workflows/pr_test_build_android.yml @@ -168,6 +168,8 @@ jobs: echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart + echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart + echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart diff --git a/.github/workflows/pr_test_build_linux.yml b/.github/workflows/pr_test_build_linux.yml index 9632786a5..5ea0cb377 100644 --- a/.github/workflows/pr_test_build_linux.yml +++ b/.github/workflows/pr_test_build_linux.yml @@ -144,6 +144,8 @@ jobs: echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart + echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart + echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 2fa8d4159..97d8ef20b 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1159,6 +1159,7 @@ abstract class ElectrumWalletBase 'derivationPath': walletInfo.derivationInfo?.derivationPath, 'silent_addresses': walletAddresses.silentAddresses.map((addr) => addr.toJSON()).toList(), 'silent_address_index': walletAddresses.currentSilentAddressIndex.toString(), + 'mweb_addresses': walletAddresses.mwebAddresses.map((addr) => addr.toJSON()).toList(), }); int feeRate(TransactionPriority priority) { diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart index 314b8768a..2de86d780 100644 --- a/cw_bitcoin/lib/electrum_wallet_addresses.dart +++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart @@ -39,6 +39,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { Map? initialChangeAddressIndex, List? initialSilentAddresses, int initialSilentAddressIndex = 0, + List? initialMwebAddresses, Bip32Slip10Secp256k1? masterHd, BitcoinAddressType? initialAddressPageType, }) : _addresses = ObservableList.of((initialAddresses ?? []).toSet()), @@ -59,6 +60,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { silentAddresses = ObservableList.of( (initialSilentAddresses ?? []).toSet()), currentSilentAddressIndex = initialSilentAddressIndex, + mwebAddresses = + ObservableList.of((initialMwebAddresses ?? []).toSet()), super(walletInfo) { if (masterHd != null) { silentAddress = SilentPaymentOwner.fromPrivateKeys( @@ -101,6 +104,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { final ObservableList receiveAddresses; final ObservableList changeAddresses; final ObservableList silentAddresses; + final ObservableList mwebAddresses; final BasedUtxoNetwork network; final Bip32Slip10Secp256k1 mainHd; final Bip32Slip10Secp256k1 sideHd; @@ -477,6 +481,11 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { foundAddress = addressRecord; } }); + mwebAddresses.forEach((addressRecord) { + if (addressRecord.address == address) { + foundAddress = addressRecord; + } + }); if (foundAddress != null) { foundAddress!.setNewName(label); @@ -607,8 +616,21 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { updateAddressesByMatch(); } + @action + void addMwebAddresses(Iterable addresses) { + final addressesSet = this.mwebAddresses.toSet(); + addressesSet.addAll(addresses); + this.mwebAddresses.clear(); + this.mwebAddresses.addAll(addressesSet); + updateAddressesByMatch(); + } + void _validateAddresses() { _addresses.forEach((element) async { + if (element.type == SegwitAddresType.mweb) { + // this would add a ton of startup lag for mweb addresses since we have 1000 of them + return; + } if (!element.isHidden && element.address != await getAddressAsync(index: element.index, hd: mainHd, addressType: element.type)) { diff --git a/cw_bitcoin/lib/electrum_wallet_snapshot.dart b/cw_bitcoin/lib/electrum_wallet_snapshot.dart index fa58be238..25cc5637e 100644 --- a/cw_bitcoin/lib/electrum_wallet_snapshot.dart +++ b/cw_bitcoin/lib/electrum_wallet_snapshot.dart @@ -23,6 +23,7 @@ class ElectrumWalletSnapshot { required this.addressPageType, required this.silentAddresses, required this.silentAddressIndex, + required this.mwebAddresses, this.passphrase, this.derivationType, this.derivationPath, @@ -44,6 +45,8 @@ class ElectrumWalletSnapshot { List addresses; List silentAddresses; + List mwebAddresses; + ElectrumBalance balance; Map regularAddressIndex; Map changeAddressIndex; @@ -56,10 +59,11 @@ class ElectrumWalletSnapshot { final path = await pathForWallet(name: name, type: type); final jsonSource = await encryptionFileUtils.read(path: path, password: password); final data = json.decode(jsonSource) as Map; - final addressesTmp = data['addresses'] as List? ?? []; final mnemonic = data['mnemonic'] as String?; final xpub = data['xpub'] as String?; final passphrase = data['passphrase'] as String? ?? ''; + + final addressesTmp = data['addresses'] as List? ?? []; final addresses = addressesTmp .whereType() .map((addr) => BitcoinAddressRecord.fromJSON(addr, network: network)) @@ -71,6 +75,12 @@ class ElectrumWalletSnapshot { .map((addr) => BitcoinSilentPaymentAddressRecord.fromJSON(addr, network: network)) .toList(); + final mwebAddressTmp = data['mweb_addresses'] as List? ?? []; + final mwebAddresses = mwebAddressTmp + .whereType() + .map((addr) => BitcoinAddressRecord.fromJSON(addr, network: network)) + .toList(); + final balance = ElectrumBalance.fromJSON(data['balance'] as String?) ?? ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0); var regularAddressIndexByType = {SegwitAddresType.p2wpkh.toString(): 0}; @@ -113,6 +123,7 @@ class ElectrumWalletSnapshot { derivationPath: derivationPath, silentAddresses: silentAddresses, silentAddressIndex: silentAddressIndex, + mwebAddresses: mwebAddresses, ); } } diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index f0934c090..f33bfc701 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -57,6 +57,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { String? passphrase, String? addressPageType, List? initialAddresses, + List? initialMwebAddresses, ElectrumBalance? initialBalance, Map? initialRegularAddressIndex, Map? initialChangeAddressIndex, @@ -81,6 +82,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { initialAddresses: initialAddresses, initialRegularAddressIndex: initialRegularAddressIndex, initialChangeAddressIndex: initialChangeAddressIndex, + initialMwebAddresses: initialMwebAddresses, mainHd: hd, sideHd: accountHD.childKey(Bip32KeyIndex(1)), network: network, @@ -111,6 +113,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { String? passphrase, String? addressPageType, List? initialAddresses, + List? initialMwebAddresses, ElectrumBalance? initialBalance, Map? initialRegularAddressIndex, Map? initialChangeAddressIndex}) async { @@ -134,6 +137,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfo, initialAddresses: initialAddresses, + initialMwebAddresses: initialMwebAddresses, initialBalance: initialBalance, encryptionFileUtils: encryptionFileUtils, passphrase: passphrase, @@ -213,6 +217,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfo, initialAddresses: snp?.addresses, + initialMwebAddresses: snp?.mwebAddresses, initialBalance: snp?.balance, seedBytes: seedBytes!, passphrase: passphrase, @@ -267,10 +272,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { _syncTimer?.cancel(); // delay the timer by a second so we don't overrride the restoreheight if one is set - Timer(const Duration(seconds: 1), () async { + Timer(const Duration(seconds: 2), () async { _syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async { if (syncStatus is FailedSyncStatus) return; - final nodeHeight = await electrumClient.getCurrentBlockChainTip() ?? 0; + + final nodeHeight = + await electrumClient.getCurrentBlockChainTip() ?? 0; // current block height of our node final resp = await _stub.status(StatusRequest()); if (resp.blockHeaderHeight < nodeHeight) { @@ -303,6 +310,26 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { } } }); + + // setup a watch dog to restart the sync process if it gets stuck: + List lastFewProgresses = []; + Timer.periodic(const Duration(seconds: 10), (timer) async { + if (syncStatus is! SyncingSyncStatus) return; + if (syncStatus.progress() > 0.98) return; + lastFewProgresses.add(syncStatus.progress()); + if (lastFewProgresses.length < 4) return; + // limit list size to 4: + while(lastFewProgresses.length > 4) { + lastFewProgresses.removeAt(0); + } + // if the progress is the same over the last 40 seconds, restart the sync: + if (lastFewProgresses.every((p) => p == lastFewProgresses.first)) { + print("mweb syncing is stuck, restarting..."); + await stopSync(); + startSync(); + timer.cancel(); + } + }); }); // this runs in the background and processes new utxos as they come in: processMwebUtxos(); diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart index 04a7ab5cc..0bdfafdcd 100644 --- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart @@ -25,15 +25,20 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with required this.mwebHd, required this.mwebEnabled, super.initialAddresses, + super.initialMwebAddresses, super.initialRegularAddressIndex, super.initialChangeAddressIndex, - }) : super(walletInfo) {} + }) : super(walletInfo) { + for (int i = 0; i < mwebAddresses.length; i++) { + mwebAddrs.add(mwebAddresses[i].address); + } + print("initialized with ${mwebAddrs.length} mweb addresses"); + } final Bip32Slip10Secp256k1 mwebHd; bool mwebEnabled; int mwebTopUpIndex = 1000; List mwebAddrs = []; - static Timer? mwebTopUpTimer; List get scanSecret => mwebHd.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw; List get spendPubkey => @@ -41,59 +46,52 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with @override Future init() async { + await initMwebAddresses(); await super.init(); - initMwebAddresses(); + } + + @computed + @override + List get allAddresses { + return List.from(super.allAddresses)..addAll(mwebAddresses); } Future ensureMwebAddressUpToIndexExists(int index) async { Uint8List scan = Uint8List.fromList(scanSecret); Uint8List spend = Uint8List.fromList(spendPubkey); + int count = 0; while (mwebAddrs.length <= (index + 1)) { final address = await CwMweb.address(scan, spend, mwebAddrs.length); mwebAddrs.add(address!); - } - } - - Future generateNumAddresses(int num) async { - Uint8List scan = Uint8List.fromList(scanSecret); - Uint8List spend = Uint8List.fromList(spendPubkey); - for (int i = 0; i < num; i++) { - final address = await CwMweb.address(scan, spend, mwebAddrs.length); - mwebAddrs.add(address!); - await Future.delayed(Duration.zero); + count++; + // sleep for a bit to avoid making the main thread unresponsive: + if (count > 50) { + count = 0; + await Future.delayed(Duration(milliseconds: 100)); + } } } Future initMwebAddresses() async { - print("Initializing MWEB address timer!"); - Timer.periodic(const Duration(seconds: 2), (timer) async { - if (super.allAddresses.length > 1000) { - timer.cancel(); - return; - } + if (mwebAddrs.length < 1000) { print("Generating MWEB addresses..."); - await generateNumAddresses(250); - await Future.delayed(const Duration(milliseconds: 1500)); - - if (mwebAddrs.length > 1000) { - // convert mwebAddrs to BitcoinAddressRecords: - List mwebAddresses = mwebAddrs - .asMap() - .entries - .map((e) => BitcoinAddressRecord( - e.value, - index: e.key, - type: SegwitAddresType.mweb, - network: network, - )) - .toList(); - // add them to the list of all addresses: - addAddresses(mwebAddresses); - print("MWEB addresses initialized ${mwebAddrs.length}"); - timer.cancel(); - return; - } - }); + await ensureMwebAddressUpToIndexExists(1020); + print("done generating MWEB addresses"); + List addressRecords = mwebAddrs + .asMap() + .entries + .map((e) => BitcoinAddressRecord( + e.value, + index: e.key, + type: SegwitAddresType.mweb, + network: network, + )) + .toList(); + print("converted to list"); + addMwebAddresses(addressRecords); + print("added ${addressRecords.length} mweb addresses"); + return; + } } @override @@ -114,6 +112,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with required Bip32Slip10Secp256k1 hd, BitcoinAddressType? addressType, }) async { + print("getting address for index $index"); if (addressType == SegwitAddresType.mweb) { await ensureMwebAddressUpToIndexExists(index); } diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index b6a9777d2..61495ba71 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -319,18 +319,18 @@ packages: dependency: transitive description: name: ffigen - sha256: d3e76c2ad48a4e7f93a29a162006f00eba46ce7c08194a77bb5c5e97d1b5ff0a + sha256: "3e12e80ccb6539bb3917217bb6f32709220efb737de0d0fa8736da0b7cb507da" url: "https://pub.dev" source: hosted - version: "8.0.2" + version: "12.0.0" file: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" fixnum: dependency: transitive description: @@ -886,8 +886,8 @@ packages: description: path: "." ref: "sp_v4.0.0" - resolved-ref: "3b8ae38592c0584f53560071dc18bc570758fe13" - url: "https://github.com/rafael-xmr/sp_scanner" + resolved-ref: "9b04f4b0af80dd7dae9274b496a53c23dcc80ea5" + url: "https://github.com/cake-tech/sp_scanner" source: git version: "0.0.1" stack_trace: diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml index 8588969c4..8756a4e3d 100644 --- a/cw_bitcoin/pubspec.yaml +++ b/cw_bitcoin/pubspec.yaml @@ -39,7 +39,7 @@ dependencies: grpc: ^3.2.4 sp_scanner: git: - url: https://github.com/rafael-xmr/sp_scanner + url: https://github.com/cake-tech/sp_scanner ref: sp_v4.0.0 bech32: git: diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock index e905af2d9..c2bdda5f1 100644 --- a/cw_core/pubspec.lock +++ b/cw_core/pubspec.lock @@ -230,10 +230,10 @@ packages: dependency: "direct main" description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" fixnum: dependency: transitive description: diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml index 4497a709d..070779caa 100644 --- a/cw_core/pubspec.yaml +++ b/cw_core/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: flutter: sdk: flutter http: ^1.1.0 - file: ^6.1.4 + file: ^7.0.0 path_provider: ^2.0.11 mobx: ^2.0.7+4 flutter_mobx: ^2.0.6+1 diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock index 6e840224c..1369675f5 100644 --- a/cw_haven/pubspec.lock +++ b/cw_haven/pubspec.lock @@ -237,10 +237,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" fixnum: dependency: transitive description: diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index cf9da9455..360d33ae3 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -237,10 +237,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" fixnum: dependency: transitive description: @@ -463,8 +463,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: 3cb38bee9385faf46b03fd73aab85f3ac4115bf7 - resolved-ref: 3cb38bee9385faf46b03fd73aab85f3ac4115bf7 + ref: "3cb38bee9385faf46b03fd73aab85f3ac4115bf7" + resolved-ref: "3cb38bee9385faf46b03fd73aab85f3ac4115bf7" url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" diff --git a/cw_wownero/pubspec.lock b/cw_wownero/pubspec.lock index b68e9ce74..0e97b3214 100644 --- a/cw_wownero/pubspec.lock +++ b/cw_wownero/pubspec.lock @@ -237,10 +237,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" fixnum: dependency: transitive description: @@ -463,8 +463,8 @@ packages: dependency: "direct main" description: path: "impls/monero.dart" - ref: 3cb38bee9385faf46b03fd73aab85f3ac4115bf7 - resolved-ref: 3cb38bee9385faf46b03fd73aab85f3ac4115bf7 + ref: "3cb38bee9385faf46b03fd73aab85f3ac4115bf7" + resolved-ref: "3cb38bee9385faf46b03fd73aab85f3ac4115bf7" url: "https://github.com/mrcyjanek/monero_c" source: git version: "0.0.0" diff --git a/lib/entities/erc20_token_info_explorers.dart b/lib/entities/erc20_token_info_explorers.dart new file mode 100644 index 000000000..386db5a50 --- /dev/null +++ b/lib/entities/erc20_token_info_explorers.dart @@ -0,0 +1,80 @@ +class Erc20TokenInfoExplorers { + String? contractAddress; + String? tokenName; + String? symbol; + String? divisor; + String? tokenType; + String? totalSupply; + String? blueCheckmark; + String? description; + String? website; + String? email; + String? blog; + String? reddit; + String? slack; + String? facebook; + String? twitter; + String? bitcointalk; + String? github; + String? telegram; + String? wechat; + String? linkedin; + String? discord; + String? whitepaper; + String? tokenPriceUSD; + String? image; + + Erc20TokenInfoExplorers({ + this.contractAddress, + this.tokenName, + this.symbol, + this.divisor, + this.tokenType, + this.totalSupply, + this.blueCheckmark, + this.description, + this.website, + this.email, + this.blog, + this.reddit, + this.slack, + this.facebook, + this.twitter, + this.bitcointalk, + this.github, + this.telegram, + this.wechat, + this.linkedin, + this.discord, + this.whitepaper, + this.tokenPriceUSD, + this.image, + }); + + Erc20TokenInfoExplorers.fromJson(Map json) { + contractAddress = json['contractAddress'] as String?; + tokenName = json['tokenName'] as String?; + symbol = json['symbol'] as String?; + divisor = json['divisor'] as String?; + tokenType = json['tokenType'] as String?; + totalSupply = json['totalSupply'] as String?; + blueCheckmark = json['blueCheckmark'] as String?; + description = json['description'] as String?; + website = json['website'] as String?; + email = json['email'] as String?; + blog = json['blog'] as String?; + reddit = json['reddit'] as String?; + slack = json['slack'] as String?; + facebook = json['facebook'] as String?; + twitter = json['twitter'] as String?; + bitcointalk = json['bitcointalk'] as String?; + github = json['github'] as String?; + telegram = json['telegram'] as String?; + wechat = json['wechat'] as String?; + linkedin = json['linkedin'] as String?; + discord = json['discord'] as String?; + whitepaper = json['whitepaper'] as String?; + tokenPriceUSD = json['tokenPriceUSD'] as String?; + image = json['image'] as String?; + } +} diff --git a/lib/entities/erc20_token_info_moralis.dart b/lib/entities/erc20_token_info_moralis.dart new file mode 100644 index 000000000..517ff9712 --- /dev/null +++ b/lib/entities/erc20_token_info_moralis.dart @@ -0,0 +1,85 @@ +class Erc20TokenInfoMoralis { + String? address; + String? addressLabel; + String? name; + String? symbol; + String? decimals; + String? logo; + String? logoHash; + String? thumbnail; + String? totalSupply; + String? totalSupplyFormatted; + String? fullyDilutedValuation; + String? blockNumber; + int? validated; + String? createdAt; + bool? possibleSpam; + bool? verifiedContract; + Links? links; + int? securityScore; + + Erc20TokenInfoMoralis({ + this.address, + this.addressLabel, + this.name, + this.symbol, + this.decimals, + this.logo, + this.logoHash, + this.thumbnail, + this.totalSupply, + this.totalSupplyFormatted, + this.fullyDilutedValuation, + this.blockNumber, + this.validated, + this.createdAt, + this.possibleSpam, + this.verifiedContract, + this.links, + this.securityScore, + }); + + Erc20TokenInfoMoralis.fromJson(Map json) { + address = json['address'] as String?; + addressLabel = json['address_label'] as String?; + name = json['name'] as String?; + symbol = json['symbol'] as String?; + decimals = json['decimals'] as String?; + logo = json['logo'] as String?; + logoHash = json['logo_hash'] as String?; + thumbnail = json['thumbnail'] as String?; + totalSupply = json['total_supply'] as String?; + totalSupplyFormatted = json['total_supply_formatted'] as String?; + fullyDilutedValuation = json['fully_diluted_valuation'] as String?; + blockNumber = json['block_number'] as String?; + validated = json['validated'] as int?; + createdAt = json['created_at'] as String?; + possibleSpam = json['possible_spam'] as bool?; + verifiedContract = json['verified_contract'] as bool; + links = + json['links'] != null ? new Links.fromJson(json['links'] as Map) : null; + securityScore = json['security_score'] as int?; + } +} + +class Links { + String? twitter; + String? website; + String? facebook; + String? reddit; + String? github; + String? linkedin; + String? telegram; + + Links({this.twitter, this.website, this.facebook, this.reddit}); + + Links.fromJson(Map json) { + twitter = json['twitter'] as String?; + website = json['website'] as String?; + facebook = json['facebook'] as String?; + reddit = json['reddit'] as String?; + github = json['github'] as String?; + linkedin = json['linkedin'] as String?; + telegram = json['telegram'] as String?; + } +} diff --git a/lib/src/screens/dashboard/edit_token_page.dart b/lib/src/screens/dashboard/edit_token_page.dart index dbb5f1aae..6f662e2be 100644 --- a/lib/src/screens/dashboard/edit_token_page.dart +++ b/lib/src/screens/dashboard/edit_token_page.dart @@ -2,16 +2,19 @@ import 'package:cake_wallet/core/address_validator.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/address_text_field.dart'; +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/checkbox_widget.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart'; import 'package:cw_core/crypto_currency.dart'; -import 'package:cw_core/erc20_token.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; class EditTokenPage extends BasePage { EditTokenPage({ @@ -79,7 +82,7 @@ class _EditTokenPageBodyState extends State { if (widget.token != null) { address = widget.homeSettingsViewModel.getTokenAddressBasedOnWallet(widget.token!); - + _contractAddressController.text = address ?? ''; _tokenNameController.text = widget.token!.name; _tokenSymbolController.text = widget.token!.title; @@ -135,8 +138,8 @@ class _EditTokenPageBodyState extends State { S.of(context).warning, style: TextStyle( fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).dialogTheme.backgroundColor, + fontWeight: FontWeight.bold, + color: Theme.of(context).extension()!.titleColor, ), ), Padding( @@ -145,7 +148,7 @@ class _EditTokenPageBodyState extends State { S.of(context).add_token_warning, style: TextStyle( fontSize: 14, - fontWeight: FontWeight.normal, + fontWeight: FontWeight.bold, color: Theme.of(context) .extension()! .detailsTitlesColor, @@ -167,6 +170,15 @@ class _EditTokenPageBodyState extends State { bottomSection: Column( children: [ if (_showDisclaimer) ...[ + Text( + S.current.do_not_send_funds_to_contract_address_warning, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14.0, + color: Theme.of(context).extension()!.titleColor, + ), + ), + SizedBox(height: 20), CheckboxWidget( value: _disclaimerChecked, caption: S.of(context).add_token_disclaimer_check, @@ -176,47 +188,84 @@ class _EditTokenPageBodyState extends State { ), SizedBox(height: 20), ], - Row( - children: [ - Expanded( - child: PrimaryButton( - onPressed: () async { - if (widget.token != null) { - await widget.homeSettingsViewModel.deleteToken(widget.token!); - } - Navigator.pop(context); - }, - text: widget.token != null ? S.of(context).delete : S.of(context).cancel, - color: Colors.red, - textColor: Colors.white, - ), - ), - SizedBox(width: 20), - Expanded( - child: PrimaryButton( - onPressed: () async { - if (_formKey.currentState!.validate() && - (!_showDisclaimer || _disclaimerChecked)) { - await widget.homeSettingsViewModel.addToken( - token: CryptoCurrency( - name: _tokenNameController.text, - title: _tokenSymbolController.text.toUpperCase(), - decimals: int.parse(_tokenDecimalController.text), - iconPath: _tokenIconPathController.text, - ), - contractAddress: _contractAddressController.text, - ); - if (mounted) { + Observer( + builder: (context) { + return Row( + children: [ + Expanded( + child: LoadingPrimaryButton( + isLoading: widget.homeSettingsViewModel.isDeletingToken, + onPressed: () async { + if (widget.token != null) { + await widget.homeSettingsViewModel.deleteToken(widget.token!); + } Navigator.pop(context); - } - } - }, - text: S.of(context).save, - color: Theme.of(context).primaryColor, - textColor: Colors.white, - ), - ), - ], + }, + text: widget.token != null ? S.of(context).delete : S.of(context).cancel, + color: Colors.red, + textColor: Colors.white, + ), + ), + SizedBox(width: 20), + Expanded( + child: LoadingPrimaryButton( + isLoading: widget.homeSettingsViewModel.isAddingToken || + widget.homeSettingsViewModel.isValidatingContractAddress, + onPressed: () async { + if (_formKey.currentState!.validate() && + (!_showDisclaimer || _disclaimerChecked)) { + final hasPotentialError = await widget.homeSettingsViewModel + .checkIfERC20TokenContractAddressIsAPotentialScamAddress( + _contractAddressController.text, + ); + final actionCall = () async { + await widget.homeSettingsViewModel.addToken( + token: CryptoCurrency( + name: _tokenNameController.text, + title: _tokenSymbolController.text.toUpperCase(), + decimals: int.parse(_tokenDecimalController.text), + iconPath: _tokenIconPathController.text, + ), + contractAddress: _contractAddressController.text, + ); + }; + + if (hasPotentialError) { + showPopUp( + context: context, + builder: (dialogContext) { + return AlertWithTwoActions( + alertTitle: S.current.warning, + alertContent: S.current.contract_warning, + rightButtonText: S.of(context).continue_text, + leftButtonText: S.of(context).cancel, + actionRightButton: () async { + Navigator.of(dialogContext).pop(); + await actionCall(); + if (mounted) { + Navigator.pop(context); + } + }, + actionLeftButton: () => Navigator.of(dialogContext).pop(), + ); + }, + ); + } else { + await actionCall(); + if (mounted) { + Navigator.pop(context); + } + } + } + }, + text: S.of(context).save, + color: Theme.of(context).primaryColor, + textColor: Colors.white, + ), + ), + ], + ); + }, ), ], ), diff --git a/lib/view_model/dashboard/home_settings_view_model.dart b/lib/view_model/dashboard/home_settings_view_model.dart index 5778f1e19..bb21f20ef 100644 --- a/lib/view_model/dashboard/home_settings_view_model.dart +++ b/lib/view_model/dashboard/home_settings_view_model.dart @@ -1,8 +1,14 @@ +import 'dart:convert'; +import 'dart:developer'; + import 'package:cake_wallet/core/fiat_conversion_service.dart'; +import 'package:cake_wallet/entities/erc20_token_info_explorers.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart'; +import 'package:cake_wallet/entities/erc20_token_info_moralis.dart'; import 'package:cake_wallet/entities/sort_balance_types.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/polygon/polygon.dart'; +import 'package:cake_wallet/reactions/wallet_connect.dart'; import 'package:cake_wallet/solana/solana.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/tron/tron.dart'; @@ -11,6 +17,8 @@ import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/erc20_token.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:mobx/mobx.dart'; +import 'package:http/http.dart' as http; +import 'package:cake_wallet/.secrets.g.dart' as secrets; part 'home_settings_view_model.g.dart'; @@ -18,7 +26,10 @@ class HomeSettingsViewModel = HomeSettingsViewModelBase with _$HomeSettingsViewM abstract class HomeSettingsViewModelBase with Store { HomeSettingsViewModelBase(this._settingsStore, this._balanceViewModel) - : tokens = ObservableSet() { + : tokens = ObservableSet(), + isAddingToken = false, + isDeletingToken = false, + isValidatingContractAddress = false { _updateTokensList(); } @@ -27,6 +38,15 @@ abstract class HomeSettingsViewModelBase with Store { final ObservableSet tokens; + @observable + bool isAddingToken; + + @observable + bool isDeletingToken; + + @observable + bool isValidatingContractAddress; + @observable String searchText = ''; @@ -45,66 +65,263 @@ abstract class HomeSettingsViewModelBase with Store { @action void setPinNativeToken(bool value) => _settingsStore.pinNativeTokenAtTop = value; + @action Future addToken({ required String contractAddress, required CryptoCurrency token, }) async { - if (_balanceViewModel.wallet.type == WalletType.ethereum) { - final erc20token = Erc20Token( - name: token.name, - symbol: token.title, - decimal: token.decimals, - contractAddress: contractAddress, - iconPath: token.iconPath, - ); + try { + isAddingToken = true; + if (_balanceViewModel.wallet.type == WalletType.ethereum) { + final erc20token = Erc20Token( + name: token.name, + symbol: token.title, + decimal: token.decimals, + contractAddress: contractAddress, + iconPath: token.iconPath, + ); - await ethereum!.addErc20Token(_balanceViewModel.wallet, erc20token); + await ethereum!.addErc20Token(_balanceViewModel.wallet, erc20token); + } + + if (_balanceViewModel.wallet.type == WalletType.polygon) { + final polygonToken = Erc20Token( + name: token.name, + symbol: token.title, + decimal: token.decimals, + contractAddress: contractAddress, + iconPath: token.iconPath, + ); + await polygon!.addErc20Token(_balanceViewModel.wallet, polygonToken); + } + + if (_balanceViewModel.wallet.type == WalletType.solana) { + await solana!.addSPLToken( + _balanceViewModel.wallet, + token, + contractAddress, + ); + } + + if (_balanceViewModel.wallet.type == WalletType.tron) { + await tron!.addTronToken(_balanceViewModel.wallet, token, contractAddress); + } + + _updateTokensList(); + _updateFiatPrices(token); + } finally { + isAddingToken = false; } - - if (_balanceViewModel.wallet.type == WalletType.polygon) { - final polygonToken = Erc20Token( - name: token.name, - symbol: token.title, - decimal: token.decimals, - contractAddress: contractAddress, - iconPath: token.iconPath, - ); - await polygon!.addErc20Token(_balanceViewModel.wallet, polygonToken); - } - - if (_balanceViewModel.wallet.type == WalletType.solana) { - await solana!.addSPLToken( - _balanceViewModel.wallet, - token, - contractAddress, - ); - } - - if (_balanceViewModel.wallet.type == WalletType.tron) { - await tron!.addTronToken(_balanceViewModel.wallet, token, contractAddress); - } - - _updateTokensList(); - _updateFiatPrices(token); } + @action Future deleteToken(CryptoCurrency token) async { - if (_balanceViewModel.wallet.type == WalletType.ethereum) { - await ethereum!.deleteErc20Token(_balanceViewModel.wallet, token as Erc20Token); - } + try { + isDeletingToken = true; + if (_balanceViewModel.wallet.type == WalletType.ethereum) { + await ethereum!.deleteErc20Token(_balanceViewModel.wallet, token as Erc20Token); + } - if (_balanceViewModel.wallet.type == WalletType.polygon) { - await polygon!.deleteErc20Token(_balanceViewModel.wallet, token as Erc20Token); - } + if (_balanceViewModel.wallet.type == WalletType.polygon) { + await polygon!.deleteErc20Token(_balanceViewModel.wallet, token as Erc20Token); + } - if (_balanceViewModel.wallet.type == WalletType.solana) { - await solana!.deleteSPLToken(_balanceViewModel.wallet, token); - } + if (_balanceViewModel.wallet.type == WalletType.solana) { + await solana!.deleteSPLToken(_balanceViewModel.wallet, token); + } - if (_balanceViewModel.wallet.type == WalletType.tron) { - await tron!.deleteTronToken(_balanceViewModel.wallet, token); + if (_balanceViewModel.wallet.type == WalletType.tron) { + await tron!.deleteTronToken(_balanceViewModel.wallet, token); + } + _updateTokensList(); + } finally { + isDeletingToken = false; + } + } + + Future checkIfERC20TokenContractAddressIsAPotentialScamAddress( + String contractAddress, + ) async { + try { + isValidatingContractAddress = true; + + if (!isEVMCompatibleChain(_balanceViewModel.wallet.type)) { + return false; + } + + bool isEthereum = _balanceViewModel.wallet.type == WalletType.ethereum; + + bool isPotentialScamViaMoralis = await _isPotentialScamTokenViaMoralis( + contractAddress, + isEthereum ? 'eth' : 'polygon', + ); + + bool isPotentialScamViaExplorers = await _isPotentialScamTokenViaExplorers( + contractAddress, + isEthereum: isEthereum, + ); + + bool isUnverifiedContract = await _isContractUnverified( + contractAddress, + isEthereum: isEthereum, + ); + + final showWarningForContractAddress = + isPotentialScamViaMoralis || isUnverifiedContract || isPotentialScamViaExplorers; + + return showWarningForContractAddress; + } finally { + isValidatingContractAddress = false; + } + } + + Future _isPotentialScamTokenViaMoralis( + String contractAddress, + String chainName, + ) async { + final uri = Uri.https( + 'deep-index.moralis.io', + '/api/v2.2/erc20/metadata', + { + "chain": chainName, + "addresses": contractAddress, + }, + ); + + try { + final response = await http.get( + uri, + headers: { + "Accept": "application/json", + "X-API-Key": secrets.moralisApiKey, + }, + ); + + final decodedResponse = jsonDecode(response.body); + + final tokenInfo = Erc20TokenInfoMoralis.fromJson(decodedResponse[0] as Map); + + // Based on analysis using Moralis internal metrics + if (tokenInfo.possibleSpam == true) { + return true; + } + + // Tokens whose contract have not been verified are potentially risky tokens. + if (tokenInfo.verifiedContract == false) { + return true; + } + + // Tokens with a security score less than 40 are potentially risky, requiring caution when dealing with them. + if (tokenInfo.securityScore == null || tokenInfo.securityScore! < 40) { + return true; + } + + // Absence of a website URL for an ERC-20 token can be a potential red flag. A legitimate ERC-20 projects should have a well-maintained website that provides information about the token, its purpose, team, and roadmap. + if (tokenInfo.links?.website == null || tokenInfo.links!.website!.isEmpty) { + return true; + } + + // Having a Fully Diluted Valiuation of 0 is a significant red flag that could signify: + // - An abandoned/unlaunched project + // - Incorrect/missing token data + // - Suspicious manipulation of token data + if (tokenInfo.fullyDilutedValuation == '0') { + return true; + } + + // I mean, a logo is the most basic of all the potential causes, but why does your fully functional project not have a logo? + if (tokenInfo.logo == null) { + return true; + } + + return false; + } catch (e) { + return true; + } + } + + Future _isPotentialScamTokenViaExplorers( + String contractAddress, { + required bool isEthereum, + }) async { + final uri = Uri.https( + isEthereum ? "api.etherscan.io" : "api.polygonscan.com", + "/api", + { + "module": "token", + "action": "tokeninfo", + "contractaddress": contractAddress, + "apikey": isEthereum ? secrets.etherScanApiKey : secrets.polygonScanApiKey, + }, + ); + + try { + final response = await http.get(uri); + + final decodedResponse = jsonDecode(response.body) as Map; + + if (decodedResponse['status'] != '1') { + log('${decodedResponse['result']}'); + return true; + } + + final tokenInfo = + Erc20TokenInfoExplorers.fromJson(decodedResponse['result'][0] as Map); + + // A token without an email to reach its creators is a potential red flag + if (tokenInfo.email?.isEmpty == true) { + return true; + } + + // A token without a website is a potential red flag + if (tokenInfo.website?.isEmpty == true) { + return true; + } + + // if (tokenInfo.whitepaper == null) { + // return true; + // } + + return false; + } catch (e) { + return true; + } + } + + Future _isContractUnverified( + String contractAddress, { + required bool isEthereum, + }) async { + final uri = Uri.https( + isEthereum ? "api.etherscan.io" : "api.polygonscan.com", + "/api", + { + "module": "contract", + "action": "getsourcecode", + "contractaddress": contractAddress, + "apikey": isEthereum ? secrets.etherScanApiKey : secrets.polygonScanApiKey, + }, + ); + + try { + final response = await http.get(uri); + + final decodedResponse = jsonDecode(response.body) as Map; + + if (decodedResponse['status'] == '0') { + log('${decodedResponse['result']}'); + return true; + } + + if (decodedResponse['status'] == '1' && + decodedResponse['result'][0]['ABI'] == 'Contract source code not verified') { + return true; // Contract is not verified + } else { + return false; // Contract is verified + } + } catch (e) { + return true; } - _updateTokensList(); } Future getToken(String contractAddress) async { diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index c66424080..ae4344222 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -160,6 +160,7 @@ "contact_name": "اسم جهة الاتصال", "contact_support": "اتصل بالدعم", "continue_text": "التالي", + "contract_warning": "تم وضع علامة على عنوان العقد هذا على أنه احتيالي محتمل. يرجى المعالجة بحذر.", "contractName": "ﺪﻘﻌﻟﺍ ﻢﺳﺍ", "contractSymbol": "ﺪﻘﻌﻟﺍ ﺰﻣﺭ", "copied_key_to_clipboard": "تم نسخ ${key} إلى الحافظة", @@ -219,6 +220,7 @@ "displayable": "قابل للعرض", "do_not_have_enough_gas_asset": "ليس لديك ما يكفي من ${currency} لإجراء معاملة وفقًا لشروط شبكة blockchain الحالية. أنت بحاجة إلى المزيد من ${currency} لدفع رسوم شبكة blockchain، حتى لو كنت ترسل أصلًا مختلفًا.", "do_not_send": "لا ترسل", + "do_not_send_funds_to_contract_address_warning": "لا ترسل أموالًا إلى هذا العنوان \n\n هذا مجرد معرف للرمز المميز ، فستضيع أي أموال تم إرسالها إلى هذا العنوان. \n\n ملاحظة: لن تطلب منك Cake إضافة عنوان عقد أبدًا", "do_not_share_warning_text": "لا تشارك هذه مع أي شخص آخر ، بما في ذلك الدعم.\n\nيمكن أن تتم سرقة أموالك!", "do_not_show_me": "لا ترني هذا مجددا", "domain_looks_up": "ﻝﺎﺠﻤﻟﺍ ﺚﺤﺑ ﺕﺎﻴﻠﻤﻋ", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index fe1aa2dcb..5a4fe8d6d 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -160,6 +160,7 @@ "contact_name": "Име на контакт", "contact_support": "Свържи се с отдел поддръжка", "continue_text": "Напред", + "contract_warning": "Този адрес на договора е маркиран като потенциално измамник. Моля, обработете с повишено внимание.", "contractName": "Име на договора", "contractSymbol": "Договор Символ", "copied_key_to_clipboard": "Копиран ключ: ${key}", @@ -219,6 +220,7 @@ "displayable": "Възможност за показване", "do_not_have_enough_gas_asset": "Нямате достатъчно ${currency}, за да извършите транзакция с текущите условия на блокчейн мрежата. Имате нужда от повече ${currency}, за да платите таксите за блокчейн мрежа, дори ако изпращате различен актив.", "do_not_send": "Не изпращай", + "do_not_send_funds_to_contract_address_warning": "Не изпращайте средства на този адрес \n\n Това е само идентификатор за токена, всички средства, изпратени на този адрес", "do_not_share_warning_text": "Не споделяйте това с никого, дори и отдел поддръжка.\n\nПарите Ви могат и ще бъдат откраднати!", "do_not_show_me": "Не показвай повече това", "domain_looks_up": "Търсене на домейни", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 76c3450c8..7469233f1 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -160,6 +160,7 @@ "contact_name": "Jméno kontaktu", "contact_support": "Kontaktovat podporu", "continue_text": "Pokračovat", + "contract_warning": "Tato adresa smlouvy byla označena jako potenciálně podvodná. Zpracovejte prosím opatrně.", "contractName": "Název smlouvy", "contractSymbol": "Symbol smlouvy", "copied_key_to_clipboard": "Zkopírován ${key} do schránky", @@ -219,6 +220,7 @@ "displayable": "Zobrazitelné", "do_not_have_enough_gas_asset": "Nemáte dostatek ${currency} k provedení transakce s aktuálními podmínkami blockchainové sítě. K placení poplatků za blockchainovou síť potřebujete více ${currency}, i když posíláte jiné aktivum.", "do_not_send": "Neodesílat", + "do_not_send_funds_to_contract_address_warning": "Neposílejte finanční prostředky na tuto adresu \n\n Toto je pouze identifikátor pro token, jakékoli prostředky zaslané na tuto adresu budou ztraceny.", "do_not_share_warning_text": "Toto nesdílejte s nikým jiným, ani s podporou.\n\nJinak mohou být Vaše prostředky ukradeny!", "do_not_show_me": "Příště nezobrazovat", "domain_looks_up": "Vyhledávání domén", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 8cc37b584..558e2ccf8 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -160,6 +160,7 @@ "contact_name": "Name des Kontakts", "contact_support": "Support kontaktieren", "continue_text": "Weiter", + "contract_warning": "Diese Vertragsadresse wurde als potenziell betrügerisch gekennzeichnet. Bitte verarbeiten Sie mit Vorsicht.", "contractName": "Vertragsname", "contractSymbol": "Vertragssymbol", "copied_key_to_clipboard": "${key} in Zwischenablage kopiert", @@ -219,6 +220,7 @@ "displayable": "Anzeigebar", "do_not_have_enough_gas_asset": "Sie verfügen nicht über genügend ${currency}, um eine Transaktion unter den aktuellen Bedingungen des Blockchain-Netzwerks durchzuführen. Sie benötigen mehr ${currency}, um die Gebühren für das Blockchain-Netzwerk zu bezahlen, auch wenn Sie einen anderen Vermögenswert senden.", "do_not_send": "Nicht senden", + "do_not_send_funds_to_contract_address_warning": "Senden Sie keine Mittel an diese Adresse \n\n Dies ist nur eine Kennung für das Token. Alle an diese Adresse gesendeten Mittel gehen verloren. \n\n Hinweis: Kuchen würde Sie niemals auffordern, eine Vertragsadresse hinzuzufügen", "do_not_share_warning_text": "Teilen Sie diese nicht mit anderen, einschließlich Support.\n\nIhr Geld kann und wird gestohlen werden!", "do_not_show_me": "Zeig mir das nicht noch einmal", "domain_looks_up": "Domain-Suchen", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index d6029ec23..0fc657cbd 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -160,6 +160,7 @@ "contact_name": "Contact Name", "contact_support": "Contact Support", "continue_text": "Continue", + "contract_warning": "This contract address has been flagged as potentially fraudulent. Please process with caution.", "contractName": "Contract Name", "contractSymbol": "Contract Symbol", "copied_key_to_clipboard": "Copied ${key} to Clipboard", @@ -219,6 +220,7 @@ "displayable": "Displayable", "do_not_have_enough_gas_asset": "You do not have enough ${currency} to make a transaction with the current blockchain network conditions. You need more ${currency} to pay blockchain network fees, even if you are sending a different asset.", "do_not_send": "Don't send", + "do_not_send_funds_to_contract_address_warning": "Do not send funds to this address\n\n This is just an identifier for the token, any funds sent to this address will be lost.\n\n NOTE: Cake would never ask you to add a contract address", "do_not_share_warning_text": "Do not share these with anyone else, including support.\n\nYour funds can and will be stolen!", "do_not_show_me": "Do not show me this again", "domain_looks_up": "Domain lookups", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 5b598563d..4eba22456 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -160,6 +160,7 @@ "contact_name": "Nombre de contacto", "contact_support": "Contactar con Soporte", "continue_text": "Continuar", + "contract_warning": "Esta dirección de contrato ha sido marcada como potencialmente fraudulenta. Por favor, procese con precaución.", "contractName": "Nombre del contrato", "contractSymbol": "Símbolo de contrato", "copied_key_to_clipboard": "Copiado ${key} al portapapeles", @@ -219,6 +220,7 @@ "displayable": "Visualizable", "do_not_have_enough_gas_asset": "No tienes suficiente ${currency} para realizar una transacción con las condiciones actuales de la red blockchain. Necesita más ${currency} para pagar las tarifas de la red blockchain, incluso si envía un activo diferente.", "do_not_send": "no enviar", + "do_not_send_funds_to_contract_address_warning": "No envíe fondos a esta dirección \n\n Esto es solo un identificador para el token, se perderán los fondos enviados a esta dirección. \n\n Nota: Cake nunca le pediría que agregue una dirección de contrato", "do_not_share_warning_text": "No comparta estos con nadie más, incluido el soporte.\n\n¡Sus fondos pueden ser y serán robados!", "do_not_show_me": "no me muestres esto otra vez", "domain_looks_up": "Búsquedas de dominio", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index d39203177..e01a97ea2 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -160,6 +160,7 @@ "contact_name": "Nom de Contact", "contact_support": "Contacter l'assistance", "continue_text": "Continuer", + "contract_warning": "Cette adresse contractuelle a été signalée comme potentiellement frauduleuse. Veuillez traiter avec prudence.", "contractName": "Nom du contrat", "contractSymbol": "Symbole du contrat", "copied_key_to_clipboard": "${key} copiée vers le presse-papier", @@ -219,6 +220,7 @@ "displayable": "Visible", "do_not_have_enough_gas_asset": "Vous n'avez pas assez de ${currency} pour effectuer une transaction avec les conditions actuelles du réseau blockchain. Vous avez besoin de plus de ${currency} pour payer les frais du réseau blockchain, même si vous envoyez un actif différent.", "do_not_send": "Ne pas envoyer", + "do_not_send_funds_to_contract_address_warning": "N'envoyez pas de fonds à cette adresse \n\n Ceci est juste un identifiant pour le jeton, tous les fonds envoyés à cette adresse seront perdus. \n\n Remarque: Le gâteau ne vous demanderait jamais d'ajouter une adresse de contrat", "do_not_share_warning_text": "Ne les partagez avec personne, y compris avec l'assistance.\n\nVos fonds seraient inmanquablement volés !", "do_not_show_me": "Ne plus me montrer ceci à l'avenir", "domain_looks_up": "Résolution de nom", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 5daf81857..0a5192803 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -160,6 +160,7 @@ "contact_name": "Sunan Tuntuɓi", "contact_support": "Tuntuɓi Support", "continue_text": "Ci gaba", + "contract_warning": "An kafa wannan adireshin kwantaragin kwangilar yayin da yuwuwar zamba. Da fatan za a aiwatar da taka tsantsan.", "contractName": "Sunan Kwangila", "contractSymbol": "Alamar Kwangila", "copied_key_to_clipboard": "An kwafa ${key} a cikin kwafin", @@ -219,6 +220,7 @@ "displayable": "Ana iya nunawa", "do_not_have_enough_gas_asset": "Ba ku da isassun ${currency} don yin ma'amala tare da yanayin cibiyar sadarwar blockchain na yanzu. Kuna buƙatar ƙarin ${currency} don biyan kuɗaɗen cibiyar sadarwar blockchain, koda kuwa kuna aika wata kadara daban.", "do_not_send": "Kada ka aika", + "do_not_send_funds_to_contract_address_warning": "Kada ku aika da kudade zuwa wannan adireshin \n\n Wannan kawai mai ganowa ne kawai don token, kowane asusu da aka aiko zuwa wannan adireshin za a rasa. # Lafazin ba zai taba tambayar ka ƙara adireshin kwangila", "do_not_share_warning_text": "Kada ku raba waɗannan ga kowa, gami da tallafi.\n\nZa a iya sace kuɗin ku kuma za a sace!", "do_not_show_me": "Kar ka sake nuna min wannan", "domain_looks_up": "Binciken yanki", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 7d5632acb..f56c11b20 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -160,6 +160,7 @@ "contact_name": "संपर्क नाम", "contact_support": "सहायता से संपर्क करें", "continue_text": "जारी रहना", + "contract_warning": "इस अनुबंध के पते को संभावित रूप से धोखाधड़ी के रूप में चिह्नित किया गया है। कृपया सावधानी के साथ प्रक्रिया करें।", "contractName": "अनुबंध का नाम", "contractSymbol": "अनुबंध चिह्न", "copied_key_to_clipboard": "की नकल की ${key} क्लिपबोर्ड पर", @@ -219,6 +220,7 @@ "displayable": "प्रदर्शन योग्य", "do_not_have_enough_gas_asset": "वर्तमान ब्लॉकचेन नेटवर्क स्थितियों में लेनदेन करने के लिए आपके पास पर्याप्त ${currency} नहीं है। ब्लॉकचेन नेटवर्क शुल्क का भुगतान करने के लिए आपको अधिक ${currency} की आवश्यकता है, भले ही आप एक अलग संपत्ति भेज रहे हों।", "do_not_send": "मत भेजो", + "do_not_send_funds_to_contract_address_warning": "इस पते पर धन न भेजें \n\n यह सिर्फ टोकन के लिए एक पहचानकर्ता है, इस पते पर भेजे गए किसी भी धन को खो दिया जाएगा। \n\n नोट: केक आपको एक अनुबंध पता जोड़ने के लिए कभी नहीं कहेगा", "do_not_share_warning_text": "समर्थन सहित, इन्हें किसी और के साथ साझा न करें।\n\nआपके धन की चोरी हो सकती है और होगी!", "do_not_show_me": "मुझे यह फिर न दिखाएं", "domain_looks_up": "डोमेन लुकअप", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index bdd116283..fd78fcc6a 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -160,6 +160,7 @@ "contact_name": "Ime kontakta", "contact_support": "Kontaktirajte podršku", "continue_text": "Nastavak", + "contract_warning": "Ova adresa ugovora označena je kao potencijalno lažna. Molimo obradite s oprezom.", "contractName": "Naziv ugovora", "contractSymbol": "Simbol ugovora", "copied_key_to_clipboard": "${key} kopiran u međuspremnik", @@ -219,6 +220,7 @@ "displayable": "Dostupno za prikaz", "do_not_have_enough_gas_asset": "Nemate dovoljno ${currency} da izvršite transakciju s trenutačnim uvjetima blockchain mreže. Trebate više ${currency} da platite naknade za blockchain mrežu, čak i ako šaljete drugu imovinu.", "do_not_send": "Ne šalji", + "do_not_send_funds_to_contract_address_warning": "Ne šaljite sredstva na ovu adresu \n\n Ovo je samo identifikator za token, izgubit će se bilo koja sredstva poslana na ovu adresu. \n\n Napomena: Torta nikad ne bi tražila da dodate adresu ugovora", "do_not_share_warning_text": "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nVaša sredstva mogu i bit će ukradena!", "do_not_show_me": "Ne pokazuj mi ovo više", "domain_looks_up": "Pretraga domena", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 178254bba..21b940a63 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -160,6 +160,7 @@ "contact_name": "Կոնտակտի անուն", "contact_support": "Հետադարձ կապ", "continue_text": "Շարունակել", + "contract_warning": "Պայմանագրի այս հասցեն դրոշմել է որպես հնարավոր կեղծ: Խնդրում ենք զգուշությամբ մշակել:", "contractName": "Գործարքի անուն", "contractSymbol": "Գործարքի Նշան", "copied_key_to_clipboard": "${key} պատճենված է տեքստի բուֆերում", @@ -218,6 +219,7 @@ "displayable": "Ցուցադրվող", "do_not_have_enough_gas_asset": "Դուք չունեք բավարար ${currency} տրանզակցիան կատարելու համար ընթացիկ բլոկչեյն ցանցի պայմաններում: Դուք պետք է ունենաք ավելի շատ ${currency} blockchain ցանցի միջնորդավճարները վճարելու համար, նույնիսկ եթե դուք այլ ակտիվ եք ուղարկում:", "do_not_send": "Մի ուղարկեք", + "do_not_send_funds_to_contract_address_warning": "Այս հասցեին գումարներ մի ուղարկեք \n\n Սա պարզապես նույնականացն է նշանի համար, այս հասցեով ուղարկված ցանկացած միջոց կկորչի: \n\n Նշում. Տորթը երբեք չի խնդրի ձեզ ավելացնել պայմանագրի հասցե", "do_not_share_warning_text": "Մի կիսեք այս տեղեկատվությունը որևէ մեկի հետ, այդ թվում նաև աջակցության հետ: \n\nՁեր միջոցները կարող են գողանալ կորցնել!", "do_not_show_me": "Մի ցուցադրեք ինձ նորից", "domain_looks_up": "Դոմեյնի որոնում", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index 81e39ffc3..97265a641 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -160,6 +160,7 @@ "contact_name": "Nama Kontak", "contact_support": "Hubungi Dukungan", "continue_text": "Lanjutkan", + "contract_warning": "Alamat kontrak ini telah ditandai sebagai berpotensi curang. Silakan memproses dengan hati -hati.", "contractName": "Nama Kontrak", "contractSymbol": "Simbol Kontrak", "copied_key_to_clipboard": "Kunci ${key} disalin ke Clipboard", @@ -219,6 +220,7 @@ "displayable": "Dapat ditampilkan", "do_not_have_enough_gas_asset": "Anda tidak memiliki cukup ${currency} untuk melakukan transaksi dengan kondisi jaringan blockchain saat ini. Anda memerlukan lebih banyak ${currency} untuk membayar biaya jaringan blockchain, meskipun Anda mengirimkan aset yang berbeda.", "do_not_send": "Jangan kirim", + "do_not_send_funds_to_contract_address_warning": "Jangan mengirim dana ke alamat ini \n\n Ini hanya pengidentifikasi untuk token, dana apa pun yang dikirim ke alamat ini akan hilang. \n\n Catatan: Kue tidak akan pernah meminta Anda untuk menambahkan alamat kontrak", "do_not_share_warning_text": "Jangan berikan ini pada siapapun, termasuk dukungan.\n\nDana Anda bisa dan akan dicuri!", "do_not_show_me": "Jangan tampilkan ini lagi", "domain_looks_up": "Pencarian domain", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index b79457817..268a1c748 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -161,6 +161,7 @@ "contact_name": "Nome Contatto", "contact_support": "Contatta l'assistenza", "continue_text": "Continua", + "contract_warning": "Questo indirizzo del contratto è stato contrassegnato come potenzialmente fraudolento. Si prega di elaborare con cautela.", "contractName": "Nome del contratto", "contractSymbol": "Simbolo del contratto", "copied_key_to_clipboard": " ${key} copiata negli Appunti", @@ -220,6 +221,7 @@ "displayable": "Visualizzabile", "do_not_have_enough_gas_asset": "Non hai abbastanza ${currency} per effettuare una transazione con le attuali condizioni della rete blockchain. Hai bisogno di più ${currency} per pagare le commissioni della rete blockchain, anche se stai inviando una risorsa diversa.", "do_not_send": "Non inviare", + "do_not_send_funds_to_contract_address_warning": "Non inviare fondi a questo indirizzo \n\n Questo è solo un identificatore per il token, qualsiasi fondi inviati a questo indirizzo andrà perso. \n\n Nota: la torta non ti chiederebbe mai di aggiungere un indirizzo contrattuale", "do_not_share_warning_text": "Non condividerli con nessun altro, incluso il supporto.\n\nI tuoi fondi possono e saranno rubati!", "do_not_show_me": "Non mostrarmelo di nuovo", "domain_looks_up": "Ricerche di domini", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 076f28d1b..be1b822be 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -160,6 +160,7 @@ "contact_name": "連絡先", "contact_support": "サポートに連絡する", "continue_text": "持続する", + "contract_warning": "この契約住所は、潜在的に不正としてフラグが立てられています。注意して処理してください。", "contractName": "契約名", "contractSymbol": "契約記号", "copied_key_to_clipboard": "コピー済み ${key} クリップボードへ", @@ -219,6 +220,7 @@ "displayable": "表示可能", "do_not_have_enough_gas_asset": "現在のブロックチェーン ネットワークの状況では、トランザクションを行うのに十分な ${currency} がありません。別のアセットを送信する場合でも、ブロックチェーン ネットワーク料金を支払うにはさらに ${currency} が必要です。", "do_not_send": "送信しない", + "do_not_send_funds_to_contract_address_warning": "この住所に資金を送らないでください\n\nこれはトークンの識別子であり、この住所に送られた資金は失われます。", "do_not_share_warning_text": "サポートを含め、これらを他の誰とも共有しないでください。\n\nあなたの資金は盗まれる可能性があります!", "do_not_show_me": "また僕にこれを見せないでください", "domain_looks_up": "ドメイン検索", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index b4c32e9b6..bf0229ed2 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -160,6 +160,7 @@ "contact_name": "담당자 이름", "contact_support": "지원팀에 문의", "continue_text": "잇다", + "contract_warning": "이 계약 주소는 잠재적으로 사기성으로 표시되었습니다. 주의해서 처리하십시오.", "contractName": "계약명", "contractSymbol": "계약 기호", "copied_key_to_clipboard": "복사 ${key} 클립 보드로", @@ -219,6 +220,7 @@ "displayable": "표시 가능", "do_not_have_enough_gas_asset": "현재 블록체인 네트워크 조건으로 거래를 하기에는 ${currency}이(가) 충분하지 않습니다. 다른 자산을 보내더라도 블록체인 네트워크 수수료를 지불하려면 ${currency}가 더 필요합니다.", "do_not_send": "보내지 마세요", + "do_not_send_funds_to_contract_address_warning": "이 주소로 자금을 보내지 마십시오 \n\n 이것은 토큰의 식별자 일뿐입니다.이 주소로 전송 된 모든 자금은 손실됩니다. \n\n 참고 : Cake는 계약서 주소를 추가하도록 요구하지 않습니다.", "do_not_share_warning_text": "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n귀하의 자금은 도난당할 수 있고 도난당할 수 있습니다!", "do_not_show_me": "나를 다시 표시하지 않음", "domain_looks_up": "도메인 조회", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index a07cd2121..cfd6569c1 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -160,6 +160,7 @@ "contact_name": "ဆက်သွယ်ရန်အမည်", "contact_support": "ပံ့ပိုးကူညီမှုထံ ဆက်သွယ်ပါ။", "continue_text": "ဆက်လက်", + "contract_warning": "ဒီစာချုပ်လိပ်စာအလားအလာအလားအလာအလားအလာအလံများကိုအလံလွှင့်တင်ခဲ့သည်။ ကျေးဇူးပြုပြီးသတိဖြင့်လုပ်ငန်းစဉ်။", "contractName": "စာချုပ်အမည်", "contractSymbol": "စာချုပ်သင်္ကေတ", "copied_key_to_clipboard": "${key} ကို Clipboard သို့ ကူးယူထားသည်။", @@ -219,6 +220,7 @@ "displayable": "ပြသနိုင်သည်။", "do_not_have_enough_gas_asset": "လက်ရှိ blockchain ကွန်ရက်အခြေအနေများနှင့် အရောင်းအဝယ်ပြုလုပ်ရန် သင့်တွင် ${currency} လုံလောက်မှုမရှိပါ။ သင်သည် မတူညီသော ပိုင်ဆိုင်မှုတစ်ခုကို ပေးပို့နေသော်လည်း blockchain ကွန်ရက်အခကြေးငွေကို ပေးဆောင်ရန် သင်သည် နောက်ထပ် ${currency} လိုအပ်ပါသည်။", "do_not_send": "မပို့ပါနှင့်", + "do_not_send_funds_to_contract_address_warning": "ဒီလိပ်စာကိုရန်ပုံငွေမပို့ပါနဲ့။ ဒီလိပ်စာကိုအမှတ်အသားမပို့ပါနဲ့, ဒီလိပ်စာကိုပို့တဲ့ရန်ပုံငွေမဆိုဆုံးရှုံးသွားမှာပါ။ \n\n မှတ်ချက်။ ။ \n\n မှတ်ချက်။ ။", "do_not_share_warning_text": "ပံ့ပိုးကူညီမှုအပါအဝင် ဤအရာများကို အခြားမည်သူနှင့်မျှ မမျှဝေပါနှင့်။\n\nသင့်ငွေများကို ခိုးယူခံရနိုင်သည်!", "do_not_show_me": "ဒါကို ထပ်မပြနဲ့", "domain_looks_up": "ဒိုမိန်းရှာဖွေမှုများ", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index ae39cff4e..b244f4017 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -160,6 +160,7 @@ "contact_name": "Contactnaam", "contact_support": "Contact opnemen met ondersteuning", "continue_text": "Doorgaan met", + "contract_warning": "Dit contractadres is gemarkeerd als mogelijk frauduleus. Verwerk met voorzichtigheid.", "contractName": "Contractnaam", "contractSymbol": "Contractsymbool", "copied_key_to_clipboard": "Gekopieerd ${key} naar het klembord", @@ -219,6 +220,7 @@ "displayable": "Weer te geven", "do_not_have_enough_gas_asset": "U heeft niet genoeg ${currency} om een transactie uit te voeren met de huidige blockchain-netwerkomstandigheden. U heeft meer ${currency} nodig om blockchain-netwerkkosten te betalen, zelfs als u een ander item verzendt.", "do_not_send": "Niet sturen", + "do_not_send_funds_to_contract_address_warning": "Stuur geen fondsen naar dit adres \n\n Dit is slechts een identificatie voor het token, alle fondsen die naar dit adres zijn verzonden, gaan verloren. \n\n Opmerking: cake zou u nooit vragen om een ​​contractadres toe te voegen", "do_not_share_warning_text": "Deel deze met niemand anders, ook niet met support.\n\nUw geld kan en zal worden gestolen!", "do_not_show_me": "laat me dit niet opnieuw zien", "domain_looks_up": "Domein opzoeken", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 93da7a5c0..8763afe9c 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -160,6 +160,7 @@ "contact_name": "Nazwa Kontaktu", "contact_support": "Skontaktuj się z pomocą techniczną", "continue_text": "Dalej", + "contract_warning": "Ten adres umowy został oznaczony jako potencjalnie nieuczciwy. Prosimy o ostrożność.", "contractName": "Nazwa umowy", "contractSymbol": "Symbol kontraktu", "copied_key_to_clipboard": "Skopiowaneo ${key} do schowka", @@ -219,6 +220,7 @@ "displayable": "Wyświetlane", "do_not_have_enough_gas_asset": "Nie masz wystarczającej ilości ${currency}, aby dokonać transakcji przy bieżących warunkach sieci blockchain. Potrzebujesz więcej ${currency}, aby uiścić opłaty za sieć blockchain, nawet jeśli wysyłasz inny zasób.", "do_not_send": "Nie wysyłaj", + "do_not_send_funds_to_contract_address_warning": "Nie wysyłaj środków na ten adres \n\n To jest tylko identyfikator tokena, wszelkie środki wysłane na ten adres zostaną utracone. \n\n", "do_not_share_warning_text": "NIE udostępniaj ich nikomu innemu, w tym pomocy technicznej.\n\nTwoje środki wtedy prawdopodobnie zostaną skradzione!", "do_not_show_me": "Nie pokazuj mi tego ponownie", "domain_looks_up": "Wyszukiwanie domen", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 326b287ad..e470e66de 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -160,6 +160,7 @@ "contact_name": "Nome do contato", "contact_support": "Contatar Suporte", "continue_text": "Continuar", + "contract_warning": "Este endereço do contrato foi sinalizado como potencialmente fraudulento. Por favor, processe com cautela.", "contractName": "Nome do contrato", "contractSymbol": "Símbolo do Contrato", "copied_key_to_clipboard": "${key} copiada para a área de transferência", @@ -219,6 +220,7 @@ "displayable": "Exibível", "do_not_have_enough_gas_asset": "Você não tem ${currency} suficiente para fazer uma transação com as condições atuais da rede blockchain. Você precisa de mais ${currency} para pagar as taxas da rede blockchain, mesmo se estiver enviando um ativo diferente.", "do_not_send": "não envie", + "do_not_send_funds_to_contract_address_warning": "Não envie fundos para este endereço \n\n Este é apenas um identificador para o token, quaisquer fundos enviados para este endereço serão perdidos. \n\n NOTA: O bolo nunca solicitaria que você adicione um endereço de contrato", "do_not_share_warning_text": "Não os compartilhe com mais ninguém, incluindo suporte.\n\nSeus fundos podem e serão roubados!", "do_not_show_me": "não me mostre isso novamente", "domain_looks_up": "Pesquisas de domínio", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index f07d31a97..6453d012f 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -160,6 +160,7 @@ "contact_name": "Имя контакта", "contact_support": "Связаться со службой поддержки", "continue_text": "Продолжить", + "contract_warning": "Этот адрес контракта был отмечен как потенциально мошеннический. Пожалуйста, обработайтесь с осторожностью.", "contractName": "Название контракта", "contractSymbol": "Символ контракта", "copied_key_to_clipboard": "Скопировано ${key} в буфер обмена", @@ -219,6 +220,7 @@ "displayable": "Отображаемый", "do_not_have_enough_gas_asset": "У вас недостаточно ${currency} для совершения транзакции при текущих условиях сети блокчейн. Вам нужно больше ${currency} для оплаты комиссий за сеть блокчейна, даже если вы отправляете другой актив.", "do_not_send": "Не отправлять", + "do_not_send_funds_to_contract_address_warning": "Не отправляйте средства на этот адрес \n\n Это просто идентификатор для токена, любые средства, отправленные на этот адрес, будут потеряны. \n\n Примечание: торт никогда не попросит вас добавить адрес контракта", "do_not_share_warning_text": "Не сообщайте их никому, включая техподдержку.\n\nВаши средства могут и будут украдены!", "do_not_show_me": "Не показывай мне это больше", "domain_looks_up": "Поиск доменов", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index d7dc23da6..cde37e3b2 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -160,6 +160,7 @@ "contact_name": "ชื่อผู้ติดต่อ", "contact_support": "ติดต่อฝ่ายสนับสนุน", "continue_text": "ดำเนินการต่อ", + "contract_warning": "ที่อยู่สัญญานี้ได้รับการตั้งค่าสถานะว่าเป็นการฉ้อโกง กรุณาดำเนินการด้วยความระมัดระวัง", "contractName": "ชื่อสัญญา", "contractSymbol": "สัญลักษณ์สัญญา", "copied_key_to_clipboard": "คัดลอก ${key} ไปยัง Clipboard แล้ว", @@ -219,6 +220,7 @@ "displayable": "สามารถแสดงได้", "do_not_have_enough_gas_asset": "คุณมี ${currency} ไม่เพียงพอที่จะทำธุรกรรมกับเงื่อนไขเครือข่ายบล็อคเชนในปัจจุบัน คุณต้องมี ${currency} เพิ่มขึ้นเพื่อชำระค่าธรรมเนียมเครือข่ายบล็อคเชน แม้ว่าคุณจะส่งสินทรัพย์อื่นก็ตาม", "do_not_send": "อย่าส่ง", + "do_not_send_funds_to_contract_address_warning": "อย่าส่งเงินไปยังที่อยู่นี้ \n\n นี่เป็นเพียงตัวระบุสำหรับโทเค็นเงินทุนใด ๆ ที่ส่งไปยังที่อยู่นี้จะหายไป \n\n หมายเหตุ: เค้กจะไม่ขอให้คุณเพิ่มที่อยู่สัญญา", "do_not_share_warning_text": "อย่าแชร์ข้อมูลนี้กับใครอื่น รวมถึงฝ่ายสนับสนุนด้วย\n\nการเงินของคุณอาจถูกขโมยโดยไม่หวังดี!", "do_not_show_me": "อย่าแสดงข้อความนี้อีก", "domain_looks_up": "การค้นหาโดเมน", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 9806c8149..c8d4262ce 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -160,6 +160,7 @@ "contact_name": "Pangalan ng Contact", "contact_support": "Makipag-ugnay sa Suporta", "continue_text": "Magpatuloy", + "contract_warning": "Ang address ng kontrata na ito ay na -flag bilang potensyal na mapanlinlang. Mangyaring iproseso nang may pag -iingat.", "contractName": "Pangalan ng Kontrata", "contractSymbol": "Simbolo ng Kontrata", "copied_key_to_clipboard": "Kinopya ang ${key} sa Clipboard", @@ -219,6 +220,7 @@ "displayable": "Maipapakita", "do_not_have_enough_gas_asset": "Wala kang sapat na ${currency} para gumawa ng transaksyon sa kasalukuyang kundisyon ng network ng blockchain. Kailangan mo ng higit pang ${currency} upang magbayad ng mga fee sa network ng blockchain, kahit na nagpapadala ka ng ibang asset.", "do_not_send": "Huwag ipadala", + "do_not_send_funds_to_contract_address_warning": "Huwag magpadala ng pondo sa address na ito\n\n Ito ay isang identifier lamang para sa token, ang anumang pondo na ipinadala sa address na ito ay mawawala.\n\n Tandaan: Ang cake ay hindi hihilingin sa iyo na magdagdag ng isang address ng kontrata", "do_not_share_warning_text": "Huwag ibahagi ang mga ito sa sinuman kasama ang tagatustos.\n\nMaaaring manakaw ang iyong mga pondo!", "do_not_show_me": "Huwag mo itong ipakita muli", "domain_looks_up": "Mga paghahanap ng domain", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 2ec3ac116..3fe0a91be 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -160,6 +160,7 @@ "contact_name": "Kişi ismi", "contact_support": "Destek ile İletişime Geç", "continue_text": "Devam et", + "contract_warning": "Bu sözleşme adresi potansiyel olarak hileli olarak işaretlenmiştir. Lütfen dikkatle işleyin.", "contractName": "Sözleşme Adı", "contractSymbol": "Sözleşme Sembolü", "copied_key_to_clipboard": "${key} panoya kopyalandı", @@ -219,6 +220,7 @@ "displayable": "Gösterilebilir", "do_not_have_enough_gas_asset": "Mevcut blockchain ağ koşullarıyla işlem yapmak için yeterli ${currency} paranız yok. Farklı bir varlık gönderiyor olsanız bile blockchain ağ ücretlerini ödemek için daha fazla ${currency} miktarına ihtiyacınız var.", "do_not_send": "Gönderme", + "do_not_send_funds_to_contract_address_warning": "Bu adrese fon göndermeyin \n\n Bu sadece jeton için bir tanımlayıcıdır, bu adrese gönderilen fonlar kaybolacaktır. \n\n Not: Kekten asla bir sözleşme adresi eklemenizi istemez", "do_not_share_warning_text": "Bunları destek de dahil olmak üzere başka kimseyle paylaşma.\n\nParan çalınabilir ve çalınacaktır!", "do_not_show_me": "Bana bunu bir daha gösterme", "domain_looks_up": "Etki alanı aramaları", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 4801f2666..4c7d7b1e0 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -160,6 +160,7 @@ "contact_name": "Ім'я контакту", "contact_support": "Звернутися до служби підтримки", "continue_text": "Продовжити", + "contract_warning": "Ця адреса контракту була позначена як потенційно шахрайська. Будь ласка, обробляйте обережно.", "contractName": "Назва контракту", "contractSymbol": "Контракт символ", "copied_key_to_clipboard": "Скопійовано ${key} в буфер обміну", @@ -219,6 +220,7 @@ "displayable": "Відображуваний", "do_not_have_enough_gas_asset": "У вас недостатньо ${currency}, щоб здійснити трансакцію з поточними умовами мережі блокчейн. Вам потрібно більше ${currency}, щоб сплатити комісію мережі блокчейн, навіть якщо ви надсилаєте інший актив.", "do_not_send": "Не надсилайте", + "do_not_send_funds_to_contract_address_warning": "Не надсилайте кошти на цю адресу \n\n Це лише ідентифікатор для маркера, будь -які кошти, надіслані на цю адресу", "do_not_share_warning_text": "Не діліться цим нікому, включно зі службою підтримки.\n\nВаші кошти можуть і будуть вкрадені!", "do_not_show_me": "Не показуй мені це знову", "domain_looks_up": "Пошук доменів", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 397809e08..50f191d82 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -160,6 +160,7 @@ "contact_name": "رابطے کا نام", "contact_support": "سپورٹ سے رابطہ کریں۔", "continue_text": "جاری رہے", + "contract_warning": "اس معاہدے کے پتے کو ممکنہ طور پر جعلی قرار دیا گیا ہے۔ براہ کرم احتیاط کے ساتھ کارروائی کریں۔", "contractName": "ﻡﺎﻧ ﺎﮐ ﮦﺪﮨﺎﻌﻣ", "contractSymbol": "ﺖﻣﻼﻋ ﯽﮐ ﮦﺪﮨﺎﻌﻣ", "copied_key_to_clipboard": "${key} کو کلپ بورڈ پر کاپی کیا گیا۔", @@ -219,6 +220,7 @@ "displayable": "قابل نمائش", "do_not_have_enough_gas_asset": "آپ کے پاس موجودہ بلاکچین نیٹ ورک کی شرائط کے ساتھ لین دین کرنے کے لیے کافی ${currency} نہیں ہے۔ آپ کو بلاکچین نیٹ ورک کی فیس ادا کرنے کے لیے مزید ${currency} کی ضرورت ہے، چاہے آپ کوئی مختلف اثاثہ بھیج رہے ہوں۔", "do_not_send": "مت بھیجیں۔", + "do_not_send_funds_to_contract_address_warning": "اس پتے پر فنڈز نہ بھیجیں \n\n یہ ٹوکن کے لئے صرف ایک شناخت کنندہ ہے ، اس پتے پر بھیجے گئے کوئی بھی فنڈز ضائع ہوجائیں گے۔ \n\n نوٹ: کیک آپ کو کبھی بھی معاہدہ کا پتہ شامل کرنے کے لئے نہیں کہے گا۔", "do_not_share_warning_text": "سپورٹ سمیت کسی اور کے ساتھ ان کا اشتراک نہ کریں۔\\n\\nآپ کے فنڈز چوری ہو سکتے ہیں اور ہو جائیں گے!", "do_not_show_me": "مجھے یہ دوبارہ مت دکھانا", "domain_looks_up": "ڈومین تلاش کرنا", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index 9ac03f890..2da577e8c 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -160,6 +160,7 @@ "contact_name": "Orúkọ olùbásọ̀rọ̀", "contact_support": "Bá ìranlọ́wọ́ sọ̀rọ̀", "continue_text": "Tẹ̀síwájú", + "contract_warning": "Adirẹsi adehun adehun yii ti samisi bi arekereke. Jọwọ ṣe ilana pẹlu iṣọra.", "contractName": "Orukọ adehun", "contractSymbol": "Aami adehun", "copied_key_to_clipboard": "Ti ṣeda ${key} sí àtẹ àkọsílẹ̀", @@ -219,6 +220,7 @@ "displayable": "A lè ṣàfihàn ẹ̀", "do_not_have_enough_gas_asset": "O ko ni to ${currency} lati ṣe idunadura kan pẹlu awọn ipo nẹtiwọki blockchain lọwọlọwọ. O nilo diẹ sii ${currency} lati san awọn owo nẹtiwọọki blockchain, paapaa ti o ba nfi dukia miiran ranṣẹ.", "do_not_send": "Ẹ kò ránṣ", + "do_not_send_funds_to_contract_address_warning": "Maṣe fi owo ranṣẹ si adirẹsi yii \n\n Eyi jẹ idamọ fun àmi, eyikeyi awọn owo ti a firanṣẹ si adirẹsi yii yoo ko beere lọwọ rẹ lati ṣafikun adirẹsi adehun kan", "do_not_share_warning_text": "Ẹ kò pín wọnyìí sí ẹnikẹ́ni. Ẹ sì kò pin wọnyìí sí ìranlọ́wọ́. Ẹnikẹ́ni lè jí owó yín! Wọ́n máa jí owó yín!", "do_not_show_me": "Kò fi eléyìí hàn mi mọ́", "domain_looks_up": "Awọn wiwa agbegbe", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index a6577b6b6..837d4162f 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -160,6 +160,7 @@ "contact_name": "联系人姓名", "contact_support": "联系支持", "continue_text": "继续", + "contract_warning": "该合同地址已被标记为潜在的欺诈性。请谨慎处理。", "contractName": "合约名称", "contractSymbol": "合约符号", "copied_key_to_clipboard": "复制 ${key} 到剪贴板", @@ -219,6 +220,7 @@ "displayable": "可显示", "do_not_have_enough_gas_asset": "您没有足够的 ${currency} 来在当前的区块链网络条件下进行交易。即使您发送的是不同的资产,您也需要更多的 ${currency} 来支付区块链网络费用。", "do_not_send": "不要发送", + "do_not_send_funds_to_contract_address_warning": "请勿将资金发送到此地址\n\n这只是令牌的标识符,任何发送到此地址的资金都将丢失。\n\n注意:蛋糕永远不会要求您添加合同地址", "do_not_share_warning_text": "请勿与其他任何人分享这些信息,包括支持人员。\n\n您的资金可能而且将会被盗!", "do_not_show_me": "不再提示", "domain_looks_up": "域名查找", diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index 96787a403..3084af07c 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -43,6 +43,8 @@ class SecretKey { SecretKey('cakePayApiKey', () => ''), SecretKey('CSRFToken', () => ''), SecretKey('authorization', () => ''), + SecretKey('etherScanApiKey', () => ''), + SecretKey('polygonScanApiKey', () => ''), SecretKey('letsExchangeBearerToken', () => ''), SecretKey('letsExchangeAffiliateId', () => ''), SecretKey('stealthExBearerToken', () => ''),