Add DAS name lookup #3284
parent
62c4c87369
commit
5bd15e0bab
@ -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 |
||||
} |
||||
} |
@ -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…
Reference in new issue