Merge pull request #235 from cake-tech/CW-4-update-open-alias-resolver

update logic for Crypto address resolving
This commit is contained in:
mkyq 2022-01-19 12:58:50 +02:00 committed by GitHub
commit 505c568a57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 45 deletions

View file

@ -1,11 +1,17 @@
import 'package:basic_utils/basic_utils.dart'; import 'package:basic_utils/basic_utils.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
class OpenaliasRecord { class OpenaliasRecord {
OpenaliasRecord({
OpenaliasRecord({this.address, this.name}); this.address,
this.name,
this.description,
});
final String name; final String name;
final String address; final String address;
final String description;
static String formatDomainName(String name) { static String formatDomainName(String name) {
String formattedName = name; String formattedName = name;
@ -17,35 +23,60 @@ class OpenaliasRecord {
return formattedName; return formattedName;
} }
static Future<OpenaliasRecord> fetchAddressAndName(String formattedName) async { static Future<OpenaliasRecord> fetchAddressAndName({
@required String formattedName,
@required String ticker,
}) async {
String address = formattedName; String address = formattedName;
String name = formattedName; String name = formattedName;
String note = '';
if (formattedName.contains(".")) { if (formattedName.contains(".")) {
try { try {
final txtRecord = await DnsUtils.lookupRecord(formattedName, RRecordType.TXT, dnssec: true); final txtRecord = await DnsUtils.lookupRecord(
formattedName, RRecordType.TXT,
dnssec: true);
if (txtRecord != null) { if (txtRecord != null) {
for (RRecord element in txtRecord) { for (RRecord element in txtRecord) {
String record = element.data; String record = element.data;
if (record.contains("oa1:xmr") && record.contains("recipient_address")) { if (record.contains("oa1:$ticker") &&
record.contains("recipient_address")) {
record = record.replaceAll('\"', ""); record = record.replaceAll('\"', "");
final dataList = record.split(";"); final dataList = record.split(";");
address = dataList.where((item) => (item.contains("recipient_address"))) address = dataList
.toString().replaceAll("oa1:xmr recipient_address=", "") .where((item) => (item.contains("recipient_address")))
.replaceAll("(", "").replaceAll(")", "").trim(); .toString()
.replaceAll("oa1:$ticker recipient_address=", "")
.replaceAll("(", "")
.replaceAll(")", "")
.trim();
final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString() final recipientName = dataList
.replaceAll("(", "").replaceAll(")", "").trim(); .where((item) => (item.contains("recipient_name")))
.toString()
.replaceAll("(", "")
.replaceAll(")", "")
.trim();
if (recipientName.isNotEmpty) { if (recipientName.isNotEmpty) {
name = recipientName.replaceAll("recipient_name=", ""); name = recipientName.replaceAll("recipient_name=", "");
} }
final description = dataList
.where((item) => (item.contains("tx_description")))
.toString()
.replaceAll("(", "")
.replaceAll(")", "")
.trim();
if (description.isNotEmpty) {
note = description.replaceAll("tx_description=", "");
}
break; break;
} }
} }
@ -55,8 +86,6 @@ class OpenaliasRecord {
} }
} }
return OpenaliasRecord(address: address, name: name); return OpenaliasRecord(address: address, name: name, description: note);
} }
} }

View file

@ -2,6 +2,7 @@ import 'package:cake_wallet/entities/openalias_record.dart';
import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/parsed_address.dart';
import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/entities/unstoppable_domain_address.dart';
import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cw_core/wallet_type.dart';
const unstoppableDomains = [ const unstoppableDomains = [
'crypto', 'crypto',
@ -13,7 +14,8 @@ const unstoppableDomains = [
'888', '888',
'nft', 'nft',
'dao', 'dao',
'blockchain']; 'blockchain'
];
Future<ParsedAddress> parseAddressFromDomain( Future<ParsedAddress> parseAddressFromDomain(
String domain, String ticker) async { String domain, String ticker) async {
@ -28,22 +30,18 @@ Future<ParsedAddress> parseAddressFromDomain(
if (addresses?.isEmpty ?? true) { if (addresses?.isEmpty ?? true) {
return ParsedAddress( return ParsedAddress(
addresses: [domain], addresses: [domain], parseFrom: ParseFrom.yatRecord);
parseFrom: ParseFrom.yatRecord);
} }
return ParsedAddress( return ParsedAddress(
addresses: addresses, addresses: addresses, name: domain, parseFrom: ParseFrom.yatRecord);
name: domain,
parseFrom: ParseFrom.yatRecord);
} catch (e) { } catch (e) {
return ParsedAddress(addresses: [domain]); return ParsedAddress(addresses: [domain]);
} }
} }
if (unstoppableDomains.any((domain) => name.contains(domain))) { if (unstoppableDomains.any((domain) => name.contains(domain))) {
final address = final address = await fetchUnstoppableDomainAddress(domain, ticker);
await fetchUnstoppableDomainAddress(domain, ticker);
if (address?.isEmpty ?? true) { if (address?.isEmpty ?? true) {
return ParsedAddress(addresses: [domain]); return ParsedAddress(addresses: [domain]);
@ -55,7 +53,8 @@ Future<ParsedAddress> parseAddressFromDomain(
parseFrom: ParseFrom.unstoppableDomains); parseFrom: ParseFrom.unstoppableDomains);
} }
final record = await OpenaliasRecord.fetchAddressAndName(formattedName); final record = await OpenaliasRecord.fetchAddressAndName(
formattedName: formattedName, ticker: ticker);
if (record == null || record.address.contains(formattedName)) { if (record == null || record.address.contains(formattedName)) {
return ParsedAddress(addresses: [domain]); return ParsedAddress(addresses: [domain]);
@ -64,6 +63,7 @@ Future<ParsedAddress> parseAddressFromDomain(
return ParsedAddress( return ParsedAddress(
addresses: [record.address], addresses: [record.address],
name: record.name, name: record.name,
description: record.description,
parseFrom: ParseFrom.openAlias); parseFrom: ParseFrom.openAlias);
} catch (e) { } catch (e) {
print(e.toString()); print(e.toString());

View file

@ -1,12 +1,15 @@
enum ParseFrom {unstoppableDomains, openAlias, yatRecord, notParsed} enum ParseFrom { unstoppableDomains, openAlias, yatRecord, notParsed }
class ParsedAddress { class ParsedAddress {
ParsedAddress({ ParsedAddress({
this.addresses, this.addresses,
this.name = '', this.name = '',
this.parseFrom = ParseFrom.notParsed}); this.description = '',
this.parseFrom = ParseFrom.notParsed,
});
final List<String> addresses; final List<String> addresses;
final String name; final String name;
final String description;
final ParseFrom parseFrom; final ParseFrom parseFrom;
} }

View file

@ -22,7 +22,7 @@ class Output = OutputBase with _$Output;
abstract class OutputBase with Store { abstract class OutputBase with Store {
OutputBase(this._wallet, this._settingsStore, this._fiatConversationStore) OutputBase(this._wallet, this._settingsStore, this._fiatConversationStore)
:_cryptoNumberFormat = NumberFormat(cryptoNumberPattern) { : _cryptoNumberFormat = NumberFormat(cryptoNumberPattern) {
reset(); reset();
_setCryptoNumMaximumFractionDigits(); _setCryptoNumMaximumFractionDigits();
key = UniqueKey(); key = UniqueKey();
@ -52,8 +52,9 @@ abstract class OutputBase with Store {
String extractedAddress; String extractedAddress;
@computed @computed
bool get isParsedAddress => parsedAddress.parseFrom != ParseFrom.notParsed bool get isParsedAddress =>
&& parsedAddress.name.isNotEmpty; parsedAddress.parseFrom != ParseFrom.notParsed &&
parsedAddress.name.isNotEmpty;
@computed @computed
int get formattedCryptoAmount { int get formattedCryptoAmount {
@ -68,10 +69,12 @@ abstract class OutputBase with Store {
_amount = monero.formatterMoneroParseAmount(amount: _cryptoAmount); _amount = monero.formatterMoneroParseAmount(amount: _cryptoAmount);
break; break;
case WalletType.bitcoin: case WalletType.bitcoin:
_amount = bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount); _amount =
bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
break; break;
case WalletType.litecoin: case WalletType.litecoin:
_amount = bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount); _amount =
bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
break; break;
default: default:
break; break;
@ -81,7 +84,7 @@ abstract class OutputBase with Store {
amount = _amount; amount = _amount;
} }
} }
} catch(e) { } catch (e) {
amount = 0; amount = 0;
} }
@ -94,8 +97,8 @@ abstract class OutputBase with Store {
final fee = _wallet.calculateEstimatedFee( final fee = _wallet.calculateEstimatedFee(
_settingsStore.priority[_wallet.type], formattedCryptoAmount); _settingsStore.priority[_wallet.type], formattedCryptoAmount);
if (_wallet.type == WalletType.bitcoin if (_wallet.type == WalletType.bitcoin ||
|| _wallet.type == WalletType.litecoin) { _wallet.type == WalletType.litecoin) {
return bitcoin.formatterBitcoinAmountToDouble(amount: fee); return bitcoin.formatterBitcoinAmountToDouble(amount: fee);
} }
@ -215,5 +218,6 @@ abstract class OutputBase with Store {
final ticker = _wallet.currency.title.toLowerCase(); final ticker = _wallet.currency.title.toLowerCase();
parsedAddress = await parseAddressFromDomain(domain, ticker); parsedAddress = await parseAddressFromDomain(domain, ticker);
extractedAddress = await extractAddressFromParsed(context, parsedAddress); extractedAddress = await extractAddressFromParsed(context, parsedAddress);
note = parsedAddress.description;
} }
} }