|
|
|
@ -21,7 +21,7 @@ extension String { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class GetENSOwnerCoordinator { |
|
|
|
|
class GetENSAddressCoordinator { |
|
|
|
|
private struct ENSLookupKey: Hashable { |
|
|
|
|
let name: String |
|
|
|
|
let server: RPCServer |
|
|
|
@ -37,7 +37,7 @@ class GetENSOwnerCoordinator { |
|
|
|
|
self.server = server |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getENSOwner( |
|
|
|
|
func getENSAddressFromResolver( |
|
|
|
|
for input: String, |
|
|
|
|
completion: @escaping (Result<EthereumAddress, AnyError>) -> Void |
|
|
|
|
) { |
|
|
|
@ -60,21 +60,34 @@ class GetENSOwnerCoordinator { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let function = GetENSOwnerEncode() |
|
|
|
|
let function = GetENSResolverEncode() |
|
|
|
|
guard let ensRegistrarContract = Address(string: server.ensRegistrarContract.address) else { |
|
|
|
|
completion(.failure(AnyError(Web3Error(description: "Error converting contract address: \(server.ensRegistrarContract.address)")))) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
callSmartContract(withServer: server, contract: ensRegistrarContract, functionName: function.name, abiString: "[\(function.abi)]", parameters: [node] as [AnyObject]).done { result in |
|
|
|
|
callSmartContract(withServer: server, contract: ensRegistrarContract, functionName: function.name, abiString: function.abi, parameters: [node] as [AnyObject]).done { result in |
|
|
|
|
//if null address is returned (as 0) we count it as invalid |
|
|
|
|
//this is because it is not assigned to an ENS and puts the user in danger of sending funds to null |
|
|
|
|
if let owner = result["0"] as? EthereumAddress { |
|
|
|
|
if owner.address == Constants.nullAddress { |
|
|
|
|
if let resolver = result["0"] as? EthereumAddress { |
|
|
|
|
if resolver.address == Constants.nullAddress { |
|
|
|
|
completion(.failure(AnyError(Web3Error(description: "Null address returned")))) |
|
|
|
|
} else { |
|
|
|
|
//Retain self because it's useful to cache the results even if we don't immediately need it now |
|
|
|
|
self.cache(forNode: node, result: owner) |
|
|
|
|
completion(.success(owner)) |
|
|
|
|
let function = GetENSRecordFromResolverEncode() |
|
|
|
|
//TODO remove Address as a type because EthereumAddress co-exists or vice versa |
|
|
|
|
callSmartContract(withServer: self.server, contract: Address(string: resolver.address)!, functionName: function.name, abiString: function.abi, parameters: [node] as [AnyObject]).done { result in |
|
|
|
|
if let ensAddress = result["0"] as? EthereumAddress { |
|
|
|
|
if ensAddress.address == Constants.nullAddress { |
|
|
|
|
completion(.failure(AnyError(Web3Error(description: "Null address returned")))) |
|
|
|
|
} else { |
|
|
|
|
//Retain self because it's useful to cache the results even if we don't immediately need it now |
|
|
|
|
self.cache(forNode: node, result: ensAddress) |
|
|
|
|
completion(.success(ensAddress)) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
completion(.failure(AnyError(Web3Error(description: "Incorrect data output from ENS resolver")))) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
completion(.failure(AnyError(Web3Error(description: "Error extracting result from \(ensRegistrarContract).\(function.name)()")))) |
|
|
|
@ -92,19 +105,19 @@ class GetENSOwnerCoordinator { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
toStartResolvingEnsNameTimer?.invalidate() |
|
|
|
|
toStartResolvingEnsNameTimer = Timer.scheduledTimer(withTimeInterval: GetENSOwnerCoordinator.DELAY_AFTER_STOP_TYPING_TO_START_RESOLVING_ENS_NAME, repeats: false) { _ in |
|
|
|
|
toStartResolvingEnsNameTimer = Timer.scheduledTimer(withTimeInterval: GetENSAddressCoordinator.DELAY_AFTER_STOP_TYPING_TO_START_RESOLVING_ENS_NAME, repeats: false) { _ in |
|
|
|
|
//Retain self because it's useful to cache the results even if we don't immediately need it now |
|
|
|
|
self.getENSOwner(for: input) { result in |
|
|
|
|
self.getENSAddressFromResolver(for: input) { result in |
|
|
|
|
completion(result) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func cachedResult(forNode node: String) -> EthereumAddress? { |
|
|
|
|
return GetENSOwnerCoordinator.resultsCache[ENSLookupKey(name: node, server: server)] |
|
|
|
|
return GetENSAddressCoordinator.resultsCache[ENSLookupKey(name: node, server: server)] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func cache(forNode node: String, result: EthereumAddress) { |
|
|
|
|
GetENSOwnerCoordinator.resultsCache[ENSLookupKey(name: node, server: server)] = result |
|
|
|
|
GetENSAddressCoordinator.resultsCache[ENSLookupKey(name: node, server: server)] = result |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|