Add DAS name lookup #3284

pull/3288/head
Vladyslav Shepitko 3 years ago committed by Hwee-Boon Yar
parent 62c4c87369
commit 5bd15e0bab
  1. 8
      AlphaWallet.xcodeproj/project.pbxproj
  2. 13
      AlphaWallet/Core/DomainResolver.swift
  3. 78
      AlphaWallet/EtherClient/Requests/DASLookupRequest.swift
  4. 8
      AlphaWallet/Settings/Types/Constants.swift
  5. 37
      AlphaWallet/Tokens/Coordinators/DASNameLookupCoordinator.swift

@ -895,6 +895,8 @@
87D175ED24AF1565002130D2 /* KeyboardChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D175EC24AF1565002130D2 /* KeyboardChecker.swift */; };
87D457F526677CBF00BA1442 /* ERC20BalanceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D457F426677CBE00BA1442 /* ERC20BalanceViewModel.swift */; };
87D457F726677CD300BA1442 /* NativecryptoBalanceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D457F626677CD300BA1442 /* NativecryptoBalanceViewModel.swift */; };
87D949BB2710553000A96A85 /* DASLookupRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D949BA2710553000A96A85 /* DASLookupRequest.swift */; };
87D949BD2710559700A96A85 /* DASNameLookupCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D949BC2710559700A96A85 /* DASNameLookupCoordinator.swift */; };
87DB61C1264A94CD009FBDDE /* ABI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87DB61C0264A94CD009FBDDE /* ABI.swift */; };
87DB61C3264A9611009FBDDE /* ERC20.json in Resources */ = {isa = PBXBuildFile; fileRef = 87DB61C2264A9611009FBDDE /* ERC20.json */; };
87DCCB51266F655D003E8EA0 /* WalletSummaryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87DCCB50266F655D003E8EA0 /* WalletSummaryViewModel.swift */; };
@ -1897,6 +1899,8 @@
87D175EC24AF1565002130D2 /* KeyboardChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardChecker.swift; sourceTree = "<group>"; };
87D457F426677CBE00BA1442 /* ERC20BalanceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ERC20BalanceViewModel.swift; sourceTree = "<group>"; };
87D457F626677CD300BA1442 /* NativecryptoBalanceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativecryptoBalanceViewModel.swift; sourceTree = "<group>"; };
87D949BA2710553000A96A85 /* DASLookupRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DASLookupRequest.swift; sourceTree = "<group>"; };
87D949BC2710559700A96A85 /* DASNameLookupCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DASNameLookupCoordinator.swift; sourceTree = "<group>"; };
87DB61C0264A94CD009FBDDE /* ABI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ABI.swift; sourceTree = "<group>"; };
87DB61C2264A9611009FBDDE /* ERC20.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ERC20.json; sourceTree = "<group>"; };
87DCCB50266F655D003E8EA0 /* WalletSummaryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletSummaryViewModel.swift; sourceTree = "<group>"; };
@ -2280,6 +2284,7 @@
664D11A02007D59F0041A0B0 /* EstimateGasRequest.swift */,
5E7C7ADC229B4038964F417C /* EthCalllRequest.swift */,
5E7C7DA5F3C065F96CCB34B4 /* EthChainIdRequest.swift */,
87D949BA2710553000A96A85 /* DASLookupRequest.swift */,
);
path = Requests;
sourceTree = "<group>";
@ -3117,6 +3122,7 @@
5E7C769E7A78811BDF9463A3 /* GetWalletNameCoordinator.swift */,
5E7C777C420B7E1C1E6FCF00 /* GetIsERC1155ContractCoordinator.swift */,
87A97D7626FE01B7000C2F38 /* GetENSTextRecordsCoordinator.swift */,
87D949BC2710559700A96A85 /* DASNameLookupCoordinator.swift */,
);
path = Coordinators;
sourceTree = "<group>";
@ -5427,6 +5433,7 @@
29BB94951F6FC54C009B09CC /* EthereumUnit.swift in Sources */,
29C70C712016C7780072E454 /* SentTransaction.swift in Sources */,
87ED8F99248541380005C69B /* AdvancedSettingsViewModel.swift in Sources */,
87D949BB2710553000A96A85 /* DASLookupRequest.swift in Sources */,
AAEF2CAB2050A68A0038BE0D /* SignatureHelper.swift in Sources */,
29E9CFD21FE737FE00017744 /* TrustRealmConfiguration.swift in Sources */,
2959961C1FAE3EDF00DB66A8 /* AlphaWalletService.swift in Sources */,
@ -5783,6 +5790,7 @@
5E7C749615D227B91E40B274 /* TokenViewControllerHeaderView.swift in Sources */,
5E7C72EECA8154CEB7D9F46C /* ContainerViewWithShadow.swift in Sources */,
5E7C7A9628548EB8AB8B7A26 /* TokenCollection.swift in Sources */,
87D949BD2710559700A96A85 /* DASNameLookupCoordinator.swift in Sources */,
878EE951255BEC20000210DE /* ItemType.swift in Sources */,
5E7C75862ABD367EF101DF9C /* SingleChainTokenCoordinator.swift in Sources */,
5E7C70F550D982833859D8B4 /* MigrationInitializer.swift in Sources */,

@ -51,14 +51,23 @@ class DomainResolver {
return .value(value)
}
return DASNameLookupCoordinator()
.resolve(rpcURL: .forResolvingDAS, value: input)
.recover { _ -> Promise<AlphaWallet.Address> in
self.domainResolvation(domain: input)
}.get { address in
self.cache(forNode: node, result: address)
}
}
private func domainResolvation(domain: String) -> Promise<AlphaWallet.Address> {
guard let resolution = resolution else { return .init(error: AnyError.invalidAddress) }
return Promise { seal in
resolution.addr(domain: input, ticker: self.ticker) { result in
resolution.addr(domain: domain, ticker: self.ticker) { result in
switch result {
case .success(let value):
if let address = AlphaWallet.Address(string: value) {
self.cache(forNode: node, result: address)
seal.fulfill(address)
} else {

@ -0,0 +1,78 @@
//
// DASLookupRequest.swift
// AlphaWallet
//
// Created by Vladyslav Shepitko on 08.10.2021.
//
import JSONRPCKit
import Foundation
struct DASLookupRequest: JSONRPCKit.Request {
typealias Response = DASLookupResponse
let value: String
var method: String {
return "das_searchAccount"
}
var parameters: Any? {
return [value]
}
func response(from resultObject: Any) throws -> Response {
guard let data = try? JSONSerialization.data(withJSONObject: resultObject, options: []) else {
throw CastError(actualValue: resultObject, expectedType: Response.self)
}
if let data = try? JSONDecoder().decode(DASLookupResponse.self, from: data) {
return data
} else {
throw CastError(actualValue: resultObject, expectedType: Response.self)
}
}
}
struct DASLookupResponse: Decodable {
enum CodingKeys: String, CodingKey {
case errno, errmsg, data
}
let errno: Int
let errmsg: String
let records: [Record]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
errno = try container.decode(Int.self, forKey: .errno)
errmsg = try container.decode(String.self, forKey: .errmsg)
if let value = try? container.decodeIfPresent(DataClass.self, forKey: .data) {
records = value?.accountData.records ?? []
} else {
records = []
}
}
struct DataClass: Decodable {
let accountData: AccountData
enum CodingKeys: String, CodingKey {
case accountData = "account_data"
}
}
struct AccountData: Decodable {
enum CodingKeys: String, CodingKey {
case records
}
let records: [Record]
}
struct Record: Decodable {
enum CodingKeys: String, CodingKey {
case key, label, value, ttl
}
let key: String
let label: String
let value: String
let ttl: String
}
}

@ -103,6 +103,8 @@ public struct Constants {
static let gasNowEndpointBaseUrl = "https://www.gasnow.org"
static let highStandardGasThresholdGwei = BigInt(55)
//DAS
static let dasLookupURL = URL(string: "https://indexer.da.systems/")!
//Misc
public static let etherReceivedNotificationIdentifier = "etherReceivedNotificationIdentifier"
@ -199,3 +201,9 @@ public struct UnitConfiguration {
public static let gasFeeUnit: EthereumUnit = .ether
public static let finneyUnit: EthereumUnit = .finney
}
extension URL {
static var forResolvingDAS: URL {
return Constants.dasLookupURL
}
}

@ -0,0 +1,37 @@
//
// DASNameLookupCoordinator.swift
// AlphaWallet
//
// Created by Vladyslav Shepitko on 08.10.2021.
//
import JSONRPCKit
import APIKit
import PromiseKit
public final class DASNameLookupCoordinator {
enum DASNameLookupError: Error {
case ethRecordNotFound
case invalidInput
}
private static let ethAddressKey = "address.eth"
static func isValid(value: String) -> Bool {
return value.trimmed.hasSuffix(".bit")
}
func resolve(rpcURL: URL, value: String) -> Promise<AlphaWallet.Address> {
guard DASNameLookupCoordinator.isValid(value: value) else {
return .init(error: DASNameLookupError.invalidInput)
}
let request = EtherServiceRequest(rpcURL: rpcURL, batch: BatchFactory().create(DASLookupRequest(value: value)))
return Session.send(request).map { response -> AlphaWallet.Address in
if let record = response.records.first(where: { $0.key == DASNameLookupCoordinator.ethAddressKey }), let address = AlphaWallet.Address(string: record.value) {
return address
}
throw DASNameLookupError.ethRecordNotFound
}
}
}
Loading…
Cancel
Save