mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 12:09:43 +00:00
Merge pull request #235 from cake-tech/CW-4-update-open-alias-resolver
update logic for Crypto address resolving
This commit is contained in:
commit
505c568a57
4 changed files with 81 additions and 45 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue