diff --git a/README.md b/README.md index 375b69a..1a14834 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,14 @@ Resolution is primarily built and maintained by [Unstoppable Domains](https://un ## Cocoa Pods ```ruby -pod 'UnstoppableDomainsResolution', '~> 6.0.0' +pod 'UnstoppableDomainsResolution', '~> 6.1.0' ``` ## Swift Package Manager ```swift package.dependencies.append( - .package(url: "https://github.com/unstoppabledomains/resolution-swift", from: "6.0.0") + .package(url: "https://github.com/unstoppabledomains/resolution-swift", from: "6.1.0") ) ``` @@ -46,8 +46,8 @@ package.dependencies.append( # Using Resolution - - Create an instance of the Resolution class - - Call any method of the Resolution class asyncronously +- Create an instance of the Resolution class +- Call any method of the Resolution class asyncronously > NOTE: make sure an instance of the Resolution class is not deallocated until the asyncronous call brings in the result. Your code is the **only owner** of the instance so keep it as long as you need it. @@ -56,7 +56,7 @@ package.dependencies.append( ```swift import UnstoppableDomainsResolution -// obtain a key from https://unstoppabledomains.com/partner-api-dashboard if you are a partner +// obtain a key by following this document https://docs.unstoppabledomains.com/domain-distribution-and-management/quickstart/retrieve-an-api-key/#api-key guard let resolution = try? Resolution(apiKey: "") else { print ("Init of Resolution instance failed...") return @@ -68,7 +68,7 @@ guard let resolution = try? Resolution(apiKey: "") else { ```swift import UnstoppableDomainsResolution -// obtain a key from https://unstoppabledomains.com/partner-api-dashboard if you are a partner +// obtain a key by following this document https://docs.unstoppabledomains.com/domain-distribution-and-management/quickstart/retrieve-an-api-key/#api-key guard let resolution = try? Resolution( apiKey: "", znsLayer: NamingServiceConfig( @@ -108,6 +108,15 @@ let resolution = try Resolution(configs: Configurations( ## Examples ### Getting a domain's crypto address + +**`addr(domain: String, ticker: String)`** + +This API is used to retrieve wallet address for single address record. (See +[Cryptocurrency payment](https://docs.unstoppabledomains.com/resolution/guides/records-reference/#cryptocurrency-payments) +section for the record format) + +With `brad.crypto` has `crypto.ETH.address` on-chain: + ```swift resolution.addr(domain: "brad.crypto", ticker: "eth") { (result) in switch result { @@ -120,6 +129,164 @@ resolution.addr(domain: "brad.crypto", ticker: "eth") { (result) in } ``` +**`multiChainAddress(domain: String, ticker: String, chain: String)`** + +This API is used to retrieve wallet address for multi-chain address records. +(See +[multi-chain currency](https://docs.unstoppabledomains.com/resolution/guides/records-reference/#multi-chain-currencies)) + +With `brad.crypto` has `crypto.USDT.version.ERC20.address` and `crypto.USDT.version.OMNI.address` on-chain: + +```swift +resolution.multiChainAddress(domain: "brad.crypto", ticker: "USDT", chain: "ERC20") { (result) in + switch result { + case .success(let returnValue): + ethAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected Eth Address, but got \(error)") + } +} +``` + +**`addr(domain: String, network: String, token: String)`** + +This (Beta) API can be used to retrieve wallet address for single chain and multi-chain address records. + +With `brad.crypto` has `crypto.ETH.address` and `crypto.USDT.version.ERC20.address` on-chain: + +```swift +// single chain address +resolution.addr(domain: "brad.crypto", network: "eth", token: "eth") { (result) in + switch result { + case .success(let returnValue): + ethAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected Eth Address, but got \(error)") + } +} + +// multi-chain address +resolution.multiChainAddress(domain: "brad.crypto", ticker: "ETH", chain: "USDT") { (result) in + switch result { + case .success(let returnValue): + usdtAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected USDT Address, but got \(error)") + } +} +``` + +> **Note** that the API will infer `ERC20` standard as `ETH` network. + +The API can also be used by crypto exchanges to infer wallet addresses. In +centralized exchanges, users have same wallet addresses on different networks +with same wallet family. + +With `brad.crypto` only has `token.EVM.address` record on-chain. +The API resolves to same wallet address for tokens live on EVM compatible networks. + +```swift +// infer USDT on ETH network +resolution.multiChainAddress(domain: "brad.crypto", network: "ETH", token: "USDT") { (result) in + switch result { + case .success(let returnValue): + usdtOnEthAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected USDT Address, but got \(error)") + } +} + +// infer ETH token on ETH network +resolution.multiChainAddress(domain: "brad.crypto", network: "ETH", token: "ETH") { (result) in + switch result { + case .success(let returnValue): + ethTokenOnEthAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected Eth Address, but got \(error)") + } +} + +// infer USDT token on ETH network +resolution.multiChainAddress(domain: "brad.crypto", network: "AVAX", token: "USDT") { (result) in + switch result { + case .success(let returnValue): + usdtOnAvaxAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected USDT Address, but got \(error)") + } +} + +``` + +With `brad.crypto` only has `token.EVM.ETH.address` +record on chain. The API resolves to the same wallet address for tokens +specifically on Ethereum network. + +```swift +// infer USDT on ETH network +resolution.multiChainAddress(domain: "brad.crypto", network: "ETH", token: "USDT") { (result) in + switch result { + case .success(let returnValue): + usdtOnEthAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected USDT Address, but got \(error)") + } +} + +// infer ETH token on ETH network +resolution.multiChainAddress(domain: "brad.crypto", network: "ETH", token: "ETH") { (result) in + switch result { + case .success(let returnValue): + ethTokenOnEthAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected Eth Address, but got \(error)") + } +} + +// the API try to derive address for Avalanche network +resolution.multiChainAddress(domain: "brad.crypto", network: "AVAX", token: "USDT") { (result) in + switch result { + case .success(let returnValue): + usdtOnAvaxAddress = returnValue + domainReceived.fulfill() + case .failure(let error): + XCTFail("Expected USDT Address, but got \(error)") + } +} + +``` + +The API is compatible with other address formats. If a domain has multiple +address formats set, it will follow the algorithm described as follow: + +if a domain has following records set: + +``` +token.EVM.address +crypto.USDC.version.ERC20.address +token.EVM.ETH.USDC.address +crypto.USDC.address +token.EVM.ETH.address +``` + +`getAddress(domain, 'ETH', 'USDC')` will lookup records in the following order: + +``` +1. token.EVM.ETH.USDC.address +2. crypto.USDC.address +3. crypto.USDC.version.ERC20.address +4. token.EVM.ETH.address +5. token.EVM.address +``` + ### Batch requesting of owners the `batchOwners(domains: _, completion: _ )` method adds additional convenience when making multiple domain owner queries. @@ -156,10 +323,11 @@ resolution.locations(domains: ["brad.crypto", "homecakes.crypto"]) { result in ### Custom Networking Layer -By default, this library uses the native iOS networking API to connect to the internet. If you want the library to use your own networking layer instead, you must conform your networking layer to the `NetworkingLayer` protocol. This protocol requires three methods to be implemented: -* `func makeHttpPostRequest(url:, httpMethod:, httpHeaderContentType:, httpBody:, completion:)` -* `func makeHttpGetRequest(url: URL, completion:)` -* `mutating func addHeader(header: String, value: String)` +By default, this library uses the native iOS networking API to connect to the internet. If you want the library to use your own networking layer instead, you must conform your networking layer to the `NetworkingLayer` protocol. This protocol requires three methods to be implemented: + +- `func makeHttpPostRequest(url:, httpMethod:, httpHeaderContentType:, httpBody:, completion:)` +- `func makeHttpGetRequest(url: URL, completion:)` +- `mutating func addHeader(header: String, value: String)` Using these methods will bypass the default behavior and delegate the request to your own networking code. @@ -223,8 +391,8 @@ Contributions to this library are more than welcome. The easiest way to contribu Resolution library relies on environment variables to load TestNet RPC Urls. This way, our keys don't expose directly to the code. These environment variables are: -* L1_TEST_NET_RPC_URL -* L2_TEST_NET_RPC_URL +- L1_TEST_NET_RPC_URL +- L2_TEST_NET_RPC_URL Use `swift build` to build, and `swift test -v` to run the tests @@ -235,6 +403,7 @@ Once your app has a working Unstoppable Domains integration, [register it here]( Also, every week we select a newly-integrated app to feature in the Unstoppable Update newsletter. This newsletter is delivered to straight into the inbox of ~100,000 crypto fanatics — all of whom could be new customers to grow your business. # Get help + [Join our discord community](https://discord.gg/unstoppabledomains) and ask questions. # Help us improve diff --git a/Resolution.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Resolution.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 61b5206..61aef68 100644 --- a/Resolution.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Resolution.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -7,7 +7,7 @@ "state": { "branch": null, "revision": "889a1ecacd73ccc189c5cb29288048f186c44ed9", - "version": "6.0.0" + "version": "6.1.0" } }, { diff --git a/Sources/UnstoppableDomainsResolution/Configurations.swift b/Sources/UnstoppableDomainsResolution/Configurations.swift index 79c962f..5244989 100644 --- a/Sources/UnstoppableDomainsResolution/Configurations.swift +++ b/Sources/UnstoppableDomainsResolution/Configurations.swift @@ -86,6 +86,6 @@ public struct Configurations { } static public func getLibVersion() -> String { - return "UnstoppableDomains/resolution-swift/6.0.0" + return "UnstoppableDomains/resolution-swift/6.1.0" } } diff --git a/Sources/UnstoppableDomainsResolution/NamingServices/UNS.swift b/Sources/UnstoppableDomainsResolution/NamingServices/UNS.swift index feafdc1..6609451 100644 --- a/Sources/UnstoppableDomainsResolution/NamingServices/UNS.swift +++ b/Sources/UnstoppableDomainsResolution/NamingServices/UNS.swift @@ -120,6 +120,19 @@ internal class UNS: CommonNamingService, NamingService { ) } + func addr(domain: String, network: String, token: String) throws -> String { + return try asyncResolver.safeResolve( + listOfFunc: [{try self.layer1.addr(domain: domain, network: network, token: token)}, + {try self.layer2.addr(domain: domain, network: network, token: token)}, + { + if self.znsLayer.isSupported(domain: domain) { + return try self.znsLayer.addr(domain: domain, network: network, token: token) + } + throw ResolutionError.unregisteredDomain + }] + ) + } + func resolver(domain: String) throws -> String { return try asyncResolver.safeResolve( listOfFunc: [{try self.layer1.resolver(domain: domain)}, diff --git a/Sources/UnstoppableDomainsResolution/NamingServices/UNSLayer.swift b/Sources/UnstoppableDomainsResolution/NamingServices/UNSLayer.swift index 234e5f5..916a0dc 100644 --- a/Sources/UnstoppableDomainsResolution/NamingServices/UNSLayer.swift +++ b/Sources/UnstoppableDomainsResolution/NamingServices/UNSLayer.swift @@ -14,6 +14,7 @@ internal class UNSLayer: CommonNamingService { static let NewURIEventSignature = "0xc5beef08f693b11c316c0c8394a377a0033c9cf701b8cd8afd79cecef60c3952" static let getDataForManyMethodName = "getDataForMany" static let reverseOfMethodName = "reverseOf" + static let getAddressMethodName: String = "getAddress" static let tokenURIMethodName = "tokenURI" static let registryOfMethodName = "registryOf" static let existName = "exists" @@ -143,6 +144,41 @@ internal class UNSLayer: CommonNamingService { return result } + func addr(domain: String, network: String, token: String) throws -> String { + let tokenId = super.namehash(domain: domain) + let ownerRes: Any + do { + ownerRes = try self.getDataForMany(keys: [Contract.resolversKey, Contract.ownersKey], for: [tokenId]) + guard let owners = self.unfoldForMany(contractResult: ownerRes, key: Contract.ownersKey), + Utillities.isNotEmpty(owners[0]) else { + throw ResolutionError.unregisteredDomain + } + } catch { + if error is ABICoderError { + throw ResolutionError.unspecifiedResolver(self.layer.rawValue) + } + throw error + } + let res = try getAddress(domain: domain, network: network, token: token) as? [String: Any] + + if let val = res?["0"] as? String { + if (!val.isEmpty) { + return val + } + } + return "" + } + + func getAddress(domain: String, network: String, token: String) throws -> Any { + let tokenId = super.namehash(domain: domain) + if let result = try proxyReaderContract? + .callMethod(methodName: Self.getAddressMethodName, + args: [network, token, tokenId]) { + return result + } + throw ResolutionError.proxyReaderNonInitialized + } + // MARK: - Get Record func record(domain: String, key: String) throws -> String { let tokenId = super.namehash(domain: domain) @@ -154,7 +190,6 @@ internal class UNSLayer: CommonNamingService { } func allRecords(domain: String) throws -> [String: String] { - let tokenId = super.namehash(domain: domain) let commonRecordsKeys = try Self.parseRecordKeys() let mergedRecords = Array(Set(commonRecordsKeys!)) return try self.records(keys: mergedRecords, for: domain).filter { !$0.value.isEmpty } diff --git a/Sources/UnstoppableDomainsResolution/NamingServices/ZNS.swift b/Sources/UnstoppableDomainsResolution/NamingServices/ZNS.swift index 8277c9a..8b789bd 100644 --- a/Sources/UnstoppableDomainsResolution/NamingServices/ZNS.swift +++ b/Sources/UnstoppableDomainsResolution/NamingServices/ZNS.swift @@ -56,6 +56,10 @@ internal class ZNS: CommonNamingService, NamingService { return result } + func addr(domain: String, network: String, token: String) throws -> String { + throw ResolutionError.methodNotSupported + } + func record(domain: String, key: String) throws -> String { let records = try self.records(keys: [key], for: domain) diff --git a/Sources/UnstoppableDomainsResolution/Protocols/NamingService.swift b/Sources/UnstoppableDomainsResolution/Protocols/NamingService.swift index b639254..a3d6fca 100644 --- a/Sources/UnstoppableDomainsResolution/Protocols/NamingService.swift +++ b/Sources/UnstoppableDomainsResolution/Protocols/NamingService.swift @@ -18,6 +18,7 @@ protocol NamingService { func owner(domain: String) throws -> String func addr(domain: String, ticker: String) throws -> String + func addr(domain: String, network: String, token: String) throws -> String func resolver(domain: String) throws -> String func batchOwners(domains: [String]) throws -> [String: String?] diff --git a/Sources/UnstoppableDomainsResolution/Resolution.swift b/Sources/UnstoppableDomainsResolution/Resolution.swift index 3ed1e6b..a8aa40d 100644 --- a/Sources/UnstoppableDomainsResolution/Resolution.swift +++ b/Sources/UnstoppableDomainsResolution/Resolution.swift @@ -150,6 +150,21 @@ public class Resolution { } } + /// Resolves give `domain` name to a specific `currency address` if exists + /// - Parameter domain: - domain name to be resolved + /// - Parameter network: - blockchain network the token is created on + /// - Parameter ticker: - currency ticker USDT, MATIC + /// - Parameter completion: A callback that resolves `Result` with an `address` or `Error` + public func addr(domain: String, network: String, token: String, completion: @escaping StringResultConsumer ) { + do { + let preparedDomain = try self.prepare(domain: domain) + let result = try self.getServiceOf(domain: domain).addr(domain: preparedDomain, network: network, token: token) + completion(.success(result)) + } catch { + self.catchError(error, completion: completion) + } + } + /// Resolves a resolver address of a `domain` /// - Parameter domain: - domain name to be resolved /// - Parameter completion: A callback that resolves `Result` with a `resolver address` for a specific domain or `Error` diff --git a/Sources/UnstoppableDomainsResolution/Resources/UNS/resolver-keys.json b/Sources/UnstoppableDomainsResolution/Resources/UNS/resolver-keys.json index 7330240..1903157 100644 --- a/Sources/UnstoppableDomainsResolution/Resources/UNS/resolver-keys.json +++ b/Sources/UnstoppableDomainsResolution/Resources/UNS/resolver-keys.json @@ -1,5 +1,5 @@ { - "version": "2.1.23", + "version": "2.1.27", "information": { "description": "This file describes all resolver keys with a defined meaning and related metadata used by Unstoppable Domains UNS Registry", "documentation": "https://docs.unstoppabledomains.com/developer-toolkit/records-reference/", @@ -284,7 +284,7 @@ "crypto.LSK.address": { "deprecatedKeyName": "LSK", "deprecated": false, - "validationRegex": "^\\d{1,21}[L]$|^[0-9a-z]{3}[23456789abcdefghjkmnopqrstuvwxyz]{38}$" + "validationRegex": "^[0-9a-z]{3}[23456789abcdefghjkmnopqrstuvwxyz]{38}$" }, "crypto.ATOM.address": { "deprecatedKeyName": "ATOM", @@ -2301,6 +2301,16 @@ "validationRegex": "^0x[a-fA-F0-9]{40}$", "deprecated": false }, + "crypto.MCONTENT.version.ERC20.address": { + "deprecatedKeyName": "MCONTENT_ERC20", + "validationRegex": "^0x[a-fA-F0-9]{40}$", + "deprecated": false + }, + "crypto.MCONTENT.version.BEP20.address": { + "deprecatedKeyName": "MCONTENT_BEP20", + "validationRegex": "^0x[a-fA-F0-9]{40}$", + "deprecated": false + }, "crypto.DODO.version.ERC20.address": { "deprecatedKeyName": "DODO_ERC20", "validationRegex": "^0x[a-fA-F0-9]{40}$", @@ -2564,17 +2574,17 @@ "crypto.0ZK.version.ERC20.address": { "deprecatedKeyName": "0ZK_ERC20", "validationRegex": "(^0zk1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]{52})([qzyxg2vwsj5kc6u7])(unpd9kxwatwq)([qpzry9x8])([qpzry9x8gf2tvdw0s3jn54khce6mua7l]{57})", - "deprecated": true + "deprecated": false }, "crypto.0ZK.version.BEP20.address": { "deprecatedKeyName": "0ZK_BEP20", "validationRegex": "(^0zk1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]{52})([qzyxg2vwsj5kc6u7])(unpd9kxwatw8)([qpzry9x8])([qpzry9x8gf2tvdw0s3jn54khce6mua7l]{57})", - "deprecated": true + "deprecated": false }, "crypto.0ZK.version.MATIC.address": { "deprecatedKeyName": "0ZK_MATIC", "validationRegex": "(^0zk1)([qpzry9x8gf2tvdw0s3jn54khce6mua7l]{52})([qzyxg2vwsj5kc6u7])(unpd9kxwatw3)([qpzry9x8])([qpzry9x8gf2tvdw0s3jn54khce6mua7l]{57})", - "deprecated": true + "deprecated": false }, "crypto.0ZK.version.0ZK.address": { "deprecatedKeyName": "0ZK_0ZK", @@ -2625,6 +2635,21 @@ "deprecatedKeyName": "GTH", "validationRegex": "^0x[a-fA-F0-9]{40}$", "deprecated": false + }, + "crypto.HI.version.ERC20.address": { + "deprecatedKeyName": "HI_ERC20", + "validationRegex": "^0x[a-fA-F0-9]{40}$", + "deprecated": false + }, + "crypto.HI.version.BEP20.address": { + "deprecatedKeyName": "HI_BEP20", + "validationRegex": "^0x[a-fA-F0-9]{40}$", + "deprecated": false + }, + "crypto.VERSE.address": { + "deprecatedKeyName": "VERSE", + "validationRegex": "^0x[a-fA-F0-9]{40}$", + "deprecated": false } } } diff --git a/Sources/UnstoppableDomainsResolution/Resources/UNS/uns-config.json b/Sources/UnstoppableDomainsResolution/Resources/UNS/uns-config.json index e0b5297..c2af146 100644 --- a/Sources/UnstoppableDomainsResolution/Resources/UNS/uns-config.json +++ b/Sources/UnstoppableDomainsResolution/Resources/UNS/uns-config.json @@ -1,531 +1,543 @@ { - "version": "0.6.8", - "networks": { - "1": { - "contracts": { - "UNSRegistry": { - "address": "0x049aba7510f45BA5b64ea9E658E342F904DB358D", - "implementation": "0x952254Ca7925ABAdd9E141AAbcCD6e1cF684147F", - "legacyAddresses": [], - "deploymentBlock": "0xc2fede", - "forwarder": "0x049aba7510f45BA5b64ea9E658E342F904DB358D" - }, - "CNSRegistry": { - "address": "0xD1E5b0FF1287aA9f9A268759062E4Ab08b9Dacbe", - "legacyAddresses": [], - "deploymentBlock": "0x8a958b", - "forwarder": "0x97B0E89fC1B7eD4A8B237D9d8Fcce9b234f25A37" - }, - "MintingManager": { - "address": "0x2a7084870bB724175a3C96Da8FaA55128fa3E19D", - "implementation": "0x347Fbb51Aa74c531472995884cC4B8116feFA0ef", - "legacyAddresses": [], - "deploymentBlock": "0xc2fee0", - "forwarder": "0xb970fbCF52cd8111c76c379D4f2FE12E7f8AE7fb" - }, - "ProxyAdmin": { - "address": "0xAA16DA78110D9A9742c760a1a064F28654Ab93de", - "legacyAddresses": [], - "deploymentBlock": "0xc2fedc" - }, - "SignatureController": { - "address": "0x82EF94294C95aD0930055f31e53A34509227c5f7", - "legacyAddresses": [], - "deploymentBlock": "0x8a95a6" - }, - "MintingController": { - "address": "0xb0EE56339C3253361730F50c08d3d7817ecD60Ca", - "legacyAddresses": [], - "deploymentBlock": "0x8a95aa", - "deprecated": true - }, - "WhitelistedMinter": { - "address": "0xd3fF3377b0ceade1303dAF9Db04068ef8a650757", - "legacyAddresses": [], - "deploymentBlock": "0xa76ad3", - "deprecated": true - }, - "URIPrefixController": { - "address": "0x09B091492759737C03da9dB7eDF1CD6BCC3A9d91", - "legacyAddresses": [], - "deploymentBlock": "0x8a95ae", - "deprecated": true - }, - "DomainZoneController": { - "address": "0xeA70777e28E00E81f58b8921fC47F78B8a72eFE7", - "legacyAddresses": [], - "deploymentBlock": "0x98ca20", - "deprecated": true - }, - "Resolver": { - "address": "0xb66DcE2DA6afAAa98F2013446dBCB0f4B0ab2842", - "legacyAddresses": [ - "0xa1cac442be6673c49f8e74ffc7c4fd746f3cbd0d", - "0x878bc2f3f717766ab69c0a5f9a6144931e61aed3" - ], - "deploymentBlock": "0x960844", - "forwarder": "0x486eb10E4F48C038513ECAf11585Ca2779768CF2" - }, - "ProxyReader": { - "address": "0x578853aa776Eef10CeE6c4dd2B5862bdcE767A8B", - "implementation": "0xfE97D99558BDe54FB9Cb20F0C45f9199bB8df0a0", - "legacyAddresses": [ - "0x6E68f3EaAD2CC946C6CC7f4859251d8D70Dd3EDB", - "0x1BDc0fD4fbABeed3E611fd6195fCd5d41dcEF393", - "0x58034A288D2E56B661c9056A0C27273E5460B63c", - "0xc3C2BAB5e3e52DBF311b2aAcEf2e40344f19494E", - "0xfEe4D4F0aDFF8D84c12170306507554bC7045878", - "0xa6E7cEf2EDDEA66352Fd68E5915b60BDbb7309f5", - "0x7ea9Ee21077F84339eDa9C80048ec6db678642B1" - ], - "deploymentBlock": "0xf2f03c" - }, - "TwitterValidationOperator": { - "address": "0x2F659766E3D08561CA3408FbAba7C0749ab2c402", - "legacyAddresses": [ - "0xbb486C6E9cF1faA86a6E3eAAFE2e5665C0507855" - ], - "deploymentBlock": "0xc300b5" - }, - "FreeMinter": { - "address": "0x1fC985cAc641ED5846b631f96F35d9b48Bc3b834", - "legacyAddresses": [], - "deploymentBlock": "0xacc390", - "deprecated": true - }, - "MintableERC721Predicate": { - "address": "0x932532aA4c0174b8453839A6E44eE09Cc615F2b7", - "legacyAddresses": [], - "deploymentBlock": "0xa3cf69" - }, - "RootChainManager": { - "address": "0xA0c68C638235ee32657e8f720a23ceC1bFc77C77", - "legacyAddresses": [], - "deploymentBlock": "0xa3cf4d" - }, - "DotCoinBurner": { - "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", - "legacyAddresses": [], - "deploymentBlock": "0xf335e0" - } - } - }, - "5": { - "contracts": { - "UNSRegistry": { - "address": "0x070e83FCed225184E67c86302493ffFCDB953f71", - "implementation": "0x21cb8483557dcF7638496f6389b7f9E074429aB8", - "legacyAddresses": [], - "deploymentBlock": "0x5b57ea", - "forwarder": "0x070e83FCed225184E67c86302493ffFCDB953f71" - }, - "CNSRegistry": { - "address": "0x801452cFAC27e79a11c6b185986fdE09e8637589", - "legacyAddresses": [], - "deploymentBlock": "0x5b57d7", - "forwarder": "0x00443017FFaa4C840Caf5Dc7d3CB59147f363080" - }, - "MintingManager": { - "address": "0x9ee42D3EB042e06F8Cd241890C4fA0d51e4DA345", - "implementation": "0xA46EBC92D5ff97684d966D2ccD7E3980fEF14E05", - "legacyAddresses": [], - "deploymentBlock": "0x5b57ec", - "forwarder": "0x7F9F48cF94C69ce91D4b442DA186F31118ac0185" - }, - "UNSOperator": { - "address": "0xd484eF427E87462F8ee816B0eA219c841f802eF6", - "legacyAddresses": [], - "deploymentBlock": "0x7ff335", - "implementation": "0x7DB4481290635743721FbDB9f96b1b0Cdf5CaE69" - }, - "ProxyAdmin": { - "address": "0xf4906E210523F9dA79E33811A44EE000441F4E04", - "legacyAddresses": [], - "deploymentBlock": "0x5b57e8" - }, - "SignatureController": { - "address": "0x5199dAE4B24B987ba18FcE1b64664D1B798d372B", - "legacyAddresses": [], - "deploymentBlock": "0x5b57d8" - }, - "MintingController": { - "address": "0xCEC41677be322049cC885c0DAe2fE0D52CA195ca", - "legacyAddresses": [], - "deploymentBlock": "0x5b57d9", - "deprecated": true - }, - "WhitelistedMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "URIPrefixController": { - "address": "0x29465e3d2daA588E62375977bCe9b3f51406a794", - "legacyAddresses": [], - "deploymentBlock": "0x5b57da", - "deprecated": true - }, - "DomainZoneController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "Resolver": { - "address": "0x0555344A5F440Bd1d8cb6B42db46c5e5D4070437", - "legacyAddresses": [], - "deploymentBlock": "0x5b57dc", - "forwarder": "0xFCc1A95B7287Ae7a8B7cA813F12991dF5714d4C7" - }, - "ProxyReader": { - "address": "0x76007c52C73972A441aFA1A0E1016B140ffdE689", - "implementation": "0x0B0A42A7FeA63e75396D0dcD77626F706AB9Fdfb", - "legacyAddresses": [ - "0x77cb0e7503Ea82315421BcF0eE9603451cd285F6", - "0xE3b961856C417d081a02cBa0161a051268F52677", - "0x9A70ff906D422C2FD0F7B94244D6b36DB62Ee982", - "0xFc5f608149f4D9e2Ed0733efFe9DD57ee24BCF68" - ], - "deploymentBlock": "0x78b972" - }, - "TwitterValidationOperator": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "FreeMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "MintableERC721Predicate": { - "address": "0x56E14C4C1748a818a5564D33cF774c59EB3eDF59", - "legacyAddresses": [], - "deploymentBlock": "0x2fc240" - }, - "RootChainManager": { - "address": "0xBbD7cBFA79faee899Eaf900F13C9065bF03B1A74", - "legacyAddresses": [], - "deploymentBlock": "0x2dc9b9" - }, - "DotCoinBurner": { - "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", - "legacyAddresses": [], - "deploymentBlock": "0x78f5ac" - } - } - }, - "137": { - "contracts": { - "UNSRegistry": { - "address": "0xa9a6A3626993D487d2Dbda3173cf58cA1a9D9e9f", - "implementation": "0x3F72a5647295e857C6a90a071Aed99B2A0534fE2", - "legacyAddresses": [], - "deploymentBlock": "0x01272eb5", - "forwarder": "0xa9a6A3626993D487d2Dbda3173cf58cA1a9D9e9f" - }, - "CNSRegistry": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "forwarder": "0x0000000000000000000000000000000000000000" - }, - "MintingManager": { - "address": "0x7be83293BeeDc9Eba1bd76c66A65F10F3efaeC26", - "implementation": "0x61bEFAe878d7066Ffad4b90615C18665460eE558", - "legacyAddresses": [], - "deploymentBlock": "0x01272f41", - "forwarder": "0xC37d3c4326ab0E1D2b9D8b916bBdf5715f780fcF" - }, - "ProxyAdmin": { - "address": "0xe1D668052D52388F52b90f4d1798DB2b04bC3b88", - "legacyAddresses": [], - "deploymentBlock": "0x01272d15" - }, - "SignatureController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "MintingController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "WhitelistedMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "URIPrefixController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "DomainZoneController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "Resolver": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "forwarder": "0x0000000000000000000000000000000000000000" - }, - "ProxyReader": { - "address": "0x91EDd8708062bd4233f4Dd0FCE15A7cb4d500091", - "implementation": "0x9D0F27232b5c364488083e3B10F6963F635Ae521", - "legacyAddresses": [ - "0x68Af8fFFCdC6218836C62Bc2Fd2D35dA544471dD", - "0x3E67b8c702a1292d1CEb025494C84367fcb12b45", - "0x423F2531bd5d3C3D4EF7C318c2D1d9BEDE67c680", - "0xA3f32c8cd786dc089Bd1fC175F2707223aeE5d00" - ], - "deploymentBlock": "0x021b1c05" - }, - "TwitterValidationOperator": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "FreeMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "MintableERC721Predicate": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "RootChainManager": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "DotCoinBurner": { - "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", - "legacyAddresses": [], - "deploymentBlock": "0x021cac00" - } - } - }, - "1337": { - "contracts": { - "UNSRegistry": { - "address": "0x107733feD96C4Cd390c944a31F5425A7FB98Ae5e", - "implementation": "0x62b11ad5F582a5C5d378fB310125b030042554F1", - "legacyAddresses": [], - "deploymentBlock": "0x15", - "forwarder": "0x107733feD96C4Cd390c944a31F5425A7FB98Ae5e" - }, - "CNSRegistry": { - "address": "0xC58206842E4030a3B2CaBC78780Ae7635173C533", - "legacyAddresses": [], - "deploymentBlock": "0x01", - "forwarder": "0xAc52F68f31577E44aE0C7E95A42dC9eb574B9383" - }, - "MintingManager": { - "address": "0x39a27956B78d00a4E00EA8833Ff0947410A2933F", - "implementation": "0x229C56b7805aB5935a883207F6a6bD5847E65Aee", - "legacyAddresses": [], - "deploymentBlock": "0x17", - "forwarder": "0x7c3c91245769c8B7450aD522792deC4bd4bf797f" - }, - "UNSOperator": { - "address": "0xCE4bb7Dc1Eb9DCe75743dE6a4B48534fD427Ef51", - "legacyAddresses": [], - "deploymentBlock": "0x19", - "implementation": "0xe85541865Bbb62A05064ce5C9F41cC293A8eA996" - }, - "ProxyAdmin": { - "address": "0x4e44E79e0cEc05D9e62e952B2088c02A3C450aeC", - "legacyAddresses": [], - "deploymentBlock": "0x01" - }, - "SignatureController": { - "address": "0x7bB6Cd9be29fab783c0b494A06FED8b2E2596B7a", - "legacyAddresses": [], - "deploymentBlock": "0x02" - }, - "MintingController": { - "address": "0x4a3C194eB88966178bfDD81744ddDafED611B830", - "legacyAddresses": [], - "deploymentBlock": "0x03", - "deprecated": true - }, - "WhitelistedMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "URIPrefixController": { - "address": "0x4872CC1be60A9DB9c880A0A437Da7a6AF134F08f", - "legacyAddresses": [], - "deploymentBlock": "0x04", - "deprecated": true - }, - "DomainZoneController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "Resolver": { - "address": "0xF8C26340C1eAeA6c7fF1760B25005e1306953572", - "legacyAddresses": [], - "deploymentBlock": "0x08", - "forwarder": "0x11dD97b7Ca847DfB6504e61B7B9Eb30F55E554a0" - }, - "ProxyReader": { - "address": "0x5CC819C9915eADfcEBd76952B8C1BC36CADd7376", - "implementation": "0xBDeFCF6429D0AC68236A6BEb321cBD2Ce66B463C", - "legacyAddresses": [], - "deploymentBlock": "0x1f" - }, - "TwitterValidationOperator": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "FreeMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "MintableERC721Predicate": { - "address": "0x58a175BEbc8ec21A94ea63Aa5a28743945940EE6", - "legacyAddresses": [], - "deploymentBlock": "0x0d" - }, - "RootChainManager": { - "address": "0x27935e7e85db3c4e7885eB828B9e889BA69a4e7f", - "legacyAddresses": [], - "deploymentBlock": "0x0f" - }, - "DotCoinBurner": { - "address": "0x54563a9e1cD2dCBD0BCA90D3CFA4A647e02C404a", - "legacyAddresses": [], - "deploymentBlock": "0x27" - } - } - }, - "80001": { - "contracts": { - "UNSRegistry": { - "address": "0x2a93C52E7B6E7054870758e15A1446E769EdfB93", - "implementation": "0x4fec01ba3a4E0Df28c1A54b488be36370E0Bef85", - "legacyAddresses": [], - "deploymentBlock": "0x01213f43", - "forwarder": "0x2a93C52E7B6E7054870758e15A1446E769EdfB93" - }, - "CNSRegistry": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "forwarder": "0x0000000000000000000000000000000000000000" - }, - "MintingManager": { - "address": "0x428189346bb3CC52f031A1092fd47C919AC30A9f", - "implementation": "0xcAe1B2CC867F53C2355dfcF4D98B359b1AdD94e1", - "legacyAddresses": [], - "deploymentBlock": "0x01213f4a", - "forwarder": "0xEf3a491A8750BEC2Dff5339CF6Df94436d432C4d" - }, - "UNSOperator": { - "address": "0x576a376832181ddD19d17CD4505F6BF8FEdb428E", - "legacyAddresses": [], - "deploymentBlock": "0x01e03592", - "implementation": "0xaBB7934fFD76282dc9d5126A5549C2695C9b52A2" - }, - "ProxyAdmin": { - "address": "0x460d63117c7Ab1624b7474C45BF46eC6702f57ce", - "legacyAddresses": [], - "deploymentBlock": "0x01213b22" - }, - "SignatureController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "MintingController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "WhitelistedMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "URIPrefixController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "DomainZoneController": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "Resolver": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "forwarder": "0x0000000000000000000000000000000000000000" - }, - "ProxyReader": { - "address": "0xBD4674F11d512120dFc8BAe5f84963d7419A5db2", - "implementation": "0xacE4C348E1703657201082Ba449aA45ADf8F936a", - "legacyAddresses": [ - "0x71f7C0A978A541aB13Bd5783470f38b0dd71Cf78", - "0x6fe7c857C1B0E54492C8762f27e0a45CA7ff264B", - "0xbd9e01F6513E7C05f71Bf21d419a3bDF1EA9104b", - "0x332A8191905fA8E6eeA7350B5799F225B8ed30a9" - ], - "deploymentBlock": "0x01bb07d3" - }, - "TwitterValidationOperator": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "FreeMinter": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0", - "deprecated": true - }, - "MintableERC721Predicate": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "RootChainManager": { - "address": "0x0000000000000000000000000000000000000000", - "legacyAddresses": [], - "deploymentBlock": "0x0" - }, - "DotCoinBurner": { - "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", - "legacyAddresses": [], - "deploymentBlock": "0x01bbafc7" - } - } + "version": "0.8.3", + "networks": { + "1": { + "contracts": { + "UNSRegistry": { + "address": "0x049aba7510f45BA5b64ea9E658E342F904DB358D", + "implementation": "0xCd451149ffa9d059030528917842bcE14327DfD6", + "legacyAddresses": [], + "deploymentBlock": "0xc2fede", + "forwarder": "0x049aba7510f45BA5b64ea9E658E342F904DB358D" + }, + "CNSRegistry": { + "address": "0xD1E5b0FF1287aA9f9A268759062E4Ab08b9Dacbe", + "legacyAddresses": [], + "deploymentBlock": "0x8a958b", + "forwarder": "0x97B0E89fC1B7eD4A8B237D9d8Fcce9b234f25A37" + }, + "MintingManager": { + "address": "0x2a7084870bB724175a3C96Da8FaA55128fa3E19D", + "implementation": "0xc2729efaBe5746C0875AE8969ce386a02A19fB13", + "legacyAddresses": [], + "deploymentBlock": "0xc2fee0", + "forwarder": "0xb970fbCF52cd8111c76c379D4f2FE12E7f8AE7fb" + }, + "UNSOperator": { + "address": "0x28400c6e89f11a99fD7145a24d39c19f949Ab86e", + "implementation": "0x4f78Db4b434128a45C6236bd61dFf2258637cd7f", + "legacyAddresses": [], + "deploymentBlock": "0xfdd3a7" + }, + "ProxyAdmin": { + "address": "0xAA16DA78110D9A9742c760a1a064F28654Ab93de", + "legacyAddresses": [], + "deploymentBlock": "0xc2fedc" + }, + "SignatureController": { + "address": "0x82EF94294C95aD0930055f31e53A34509227c5f7", + "legacyAddresses": [], + "deploymentBlock": "0x8a95a6" + }, + "MintingController": { + "address": "0xb0EE56339C3253361730F50c08d3d7817ecD60Ca", + "legacyAddresses": [], + "deploymentBlock": "0x8a95aa", + "deprecated": true + }, + "WhitelistedMinter": { + "address": "0xd3fF3377b0ceade1303dAF9Db04068ef8a650757", + "legacyAddresses": [], + "deploymentBlock": "0xa76ad3", + "deprecated": true + }, + "URIPrefixController": { + "address": "0x09B091492759737C03da9dB7eDF1CD6BCC3A9d91", + "legacyAddresses": [], + "deploymentBlock": "0x8a95ae", + "deprecated": true + }, + "DomainZoneController": { + "address": "0xeA70777e28E00E81f58b8921fC47F78B8a72eFE7", + "legacyAddresses": [], + "deploymentBlock": "0x98ca20", + "deprecated": true + }, + "Resolver": { + "address": "0xb66DcE2DA6afAAa98F2013446dBCB0f4B0ab2842", + "legacyAddresses": [ + "0xa1cac442be6673c49f8e74ffc7c4fd746f3cbd0d", + "0x878bc2f3f717766ab69c0a5f9a6144931e61aed3" + ], + "deploymentBlock": "0x960844", + "forwarder": "0x486eb10E4F48C038513ECAf11585Ca2779768CF2" + }, + "ProxyReader": { + "address": "0x578853aa776Eef10CeE6c4dd2B5862bdcE767A8B", + "implementation": "0xF83b08F90C1d5eEf255E8DB50b3Ab158A37a9AD4", + "legacyAddresses": [ + "0x6E68f3EaAD2CC946C6CC7f4859251d8D70Dd3EDB", + "0x1BDc0fD4fbABeed3E611fd6195fCd5d41dcEF393", + "0x58034A288D2E56B661c9056A0C27273E5460B63c", + "0xc3C2BAB5e3e52DBF311b2aAcEf2e40344f19494E", + "0xfEe4D4F0aDFF8D84c12170306507554bC7045878", + "0xa6E7cEf2EDDEA66352Fd68E5915b60BDbb7309f5", + "0x7ea9Ee21077F84339eDa9C80048ec6db678642B1" + ], + "deploymentBlock": "0xf2f03c" + }, + "TwitterValidationOperator": { + "address": "0x2F659766E3D08561CA3408FbAba7C0749ab2c402", + "legacyAddresses": [ + "0xbb486C6E9cF1faA86a6E3eAAFE2e5665C0507855" + ], + "deploymentBlock": "0xc300b5" + }, + "FreeMinter": { + "address": "0x1fC985cAc641ED5846b631f96F35d9b48Bc3b834", + "legacyAddresses": [], + "deploymentBlock": "0xacc390", + "deprecated": true + }, + "MintableERC721Predicate": { + "address": "0x932532aA4c0174b8453839A6E44eE09Cc615F2b7", + "legacyAddresses": [], + "deploymentBlock": "0xa3cf69" + }, + "RootChainManager": { + "address": "0xA0c68C638235ee32657e8f720a23ceC1bFc77C77", + "legacyAddresses": [], + "deploymentBlock": "0xa3cf4d" + }, + "DotCoinBurner": { + "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", + "legacyAddresses": [], + "deploymentBlock": "0xf335e0" + } + } + }, + "5": { + "contracts": { + "UNSRegistry": { + "address": "0x070e83FCed225184E67c86302493ffFCDB953f71", + "implementation": "0x2ab164829617D51cD8c29848b8DcE163bFAF70aa", + "legacyAddresses": [], + "deploymentBlock": "0x5b57ea", + "forwarder": "0x070e83FCed225184E67c86302493ffFCDB953f71" + }, + "CNSRegistry": { + "address": "0x801452cFAC27e79a11c6b185986fdE09e8637589", + "legacyAddresses": [], + "deploymentBlock": "0x5b57d7", + "forwarder": "0x00443017FFaa4C840Caf5Dc7d3CB59147f363080" + }, + "MintingManager": { + "address": "0x9ee42D3EB042e06F8Cd241890C4fA0d51e4DA345", + "implementation": "0xe72E170CeA8F6665DcF6B8c350511F9771f21800", + "legacyAddresses": [], + "deploymentBlock": "0x5b57ec", + "forwarder": "0x7F9F48cF94C69ce91D4b442DA186F31118ac0185" + }, + "UNSOperator": { + "address": "0xd484eF427E87462F8ee816B0eA219c841f802eF6", + "legacyAddresses": [], + "deploymentBlock": "0x7ff335", + "implementation": "0x7DB4481290635743721FbDB9f96b1b0Cdf5CaE69" + }, + "ProxyAdmin": { + "address": "0xf4906E210523F9dA79E33811A44EE000441F4E04", + "legacyAddresses": [], + "deploymentBlock": "0x5b57e8" + }, + "SignatureController": { + "address": "0x5199dAE4B24B987ba18FcE1b64664D1B798d372B", + "legacyAddresses": [], + "deploymentBlock": "0x5b57d8" + }, + "MintingController": { + "address": "0xCEC41677be322049cC885c0DAe2fE0D52CA195ca", + "legacyAddresses": [], + "deploymentBlock": "0x5b57d9", + "deprecated": true + }, + "WhitelistedMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "URIPrefixController": { + "address": "0x29465e3d2daA588E62375977bCe9b3f51406a794", + "legacyAddresses": [], + "deploymentBlock": "0x5b57da", + "deprecated": true + }, + "DomainZoneController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "Resolver": { + "address": "0x0555344A5F440Bd1d8cb6B42db46c5e5D4070437", + "legacyAddresses": [], + "deploymentBlock": "0x5b57dc", + "forwarder": "0xFCc1A95B7287Ae7a8B7cA813F12991dF5714d4C7" + }, + "ProxyReader": { + "address": "0x76007c52C73972A441aFA1A0E1016B140ffdE689", + "implementation": "0xAa61dBf197646Bd01747f0AFf4Fa24135B4568Fb", + "legacyAddresses": [ + "0x77cb0e7503Ea82315421BcF0eE9603451cd285F6", + "0xE3b961856C417d081a02cBa0161a051268F52677", + "0x9A70ff906D422C2FD0F7B94244D6b36DB62Ee982", + "0xFc5f608149f4D9e2Ed0733efFe9DD57ee24BCF68" + ], + "deploymentBlock": "0x78b972" + }, + "TwitterValidationOperator": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "FreeMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "MintableERC721Predicate": { + "address": "0x56E14C4C1748a818a5564D33cF774c59EB3eDF59", + "legacyAddresses": [], + "deploymentBlock": "0x2fc240" + }, + "RootChainManager": { + "address": "0xBbD7cBFA79faee899Eaf900F13C9065bF03B1A74", + "legacyAddresses": [], + "deploymentBlock": "0x2dc9b9" + }, + "DotCoinBurner": { + "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", + "legacyAddresses": [], + "deploymentBlock": "0x78f5ac" + } + } + }, + "137": { + "contracts": { + "UNSRegistry": { + "address": "0xa9a6A3626993D487d2Dbda3173cf58cA1a9D9e9f", + "implementation": "0xC4999E1daef4ecBd4E0F71A00B4a78B53e617922", + "legacyAddresses": [], + "deploymentBlock": "0x01272eb5", + "forwarder": "0xa9a6A3626993D487d2Dbda3173cf58cA1a9D9e9f" + }, + "CNSRegistry": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "forwarder": "0x0000000000000000000000000000000000000000" + }, + "MintingManager": { + "address": "0x7be83293BeeDc9Eba1bd76c66A65F10F3efaeC26", + "implementation": "0xfd27d20F8eABAE006Dae997460344b3C0CB81bD9", + "legacyAddresses": [], + "deploymentBlock": "0x01272f41", + "forwarder": "0xC37d3c4326ab0E1D2b9D8b916bBdf5715f780fcF" + }, + "UNSOperator": { + "address": "0x8f0c61C9BD21d3a5c078FB03eCA01AE2Ff5380dB", + "implementation": "0xbB101ae4B5Df5F9375112D38D9f5a3394916EA97", + "legacyAddresses": [], + "deploymentBlock": "0x025809c0" + }, + "ProxyAdmin": { + "address": "0xe1D668052D52388F52b90f4d1798DB2b04bC3b88", + "legacyAddresses": [], + "deploymentBlock": "0x01272d15" + }, + "SignatureController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "MintingController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "WhitelistedMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "URIPrefixController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "DomainZoneController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "Resolver": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "forwarder": "0x0000000000000000000000000000000000000000" + }, + "ProxyReader": { + "address": "0x91EDd8708062bd4233f4Dd0FCE15A7cb4d500091", + "implementation": "0x989730eAe394d0415eaB088e0C1d83aCD40A66A1", + "legacyAddresses": [ + "0x68Af8fFFCdC6218836C62Bc2Fd2D35dA544471dD", + "0x3E67b8c702a1292d1CEb025494C84367fcb12b45", + "0x423F2531bd5d3C3D4EF7C318c2D1d9BEDE67c680", + "0xA3f32c8cd786dc089Bd1fC175F2707223aeE5d00" + ], + "deploymentBlock": "0x021b1c05" + }, + "TwitterValidationOperator": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "FreeMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "MintableERC721Predicate": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "RootChainManager": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "DotCoinBurner": { + "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", + "legacyAddresses": [], + "deploymentBlock": "0x021cac00" + } + } + }, + "1337": { + "contracts": { + "UNSRegistry": { + "address": "0x107733feD96C4Cd390c944a31F5425A7FB98Ae5e", + "implementation": "0x62b11ad5F582a5C5d378fB310125b030042554F1", + "legacyAddresses": [], + "deploymentBlock": "0x15", + "forwarder": "0x107733feD96C4Cd390c944a31F5425A7FB98Ae5e" + }, + "CNSRegistry": { + "address": "0xC58206842E4030a3B2CaBC78780Ae7635173C533", + "legacyAddresses": [], + "deploymentBlock": "0x01", + "forwarder": "0xAc52F68f31577E44aE0C7E95A42dC9eb574B9383" + }, + "MintingManager": { + "address": "0x39a27956B78d00a4E00EA8833Ff0947410A2933F", + "implementation": "0x229C56b7805aB5935a883207F6a6bD5847E65Aee", + "legacyAddresses": [], + "deploymentBlock": "0x17", + "forwarder": "0x7c3c91245769c8B7450aD522792deC4bd4bf797f" + }, + "UNSOperator": { + "address": "0xCE4bb7Dc1Eb9DCe75743dE6a4B48534fD427Ef51", + "legacyAddresses": [], + "deploymentBlock": "0x19", + "implementation": "0xe85541865Bbb62A05064ce5C9F41cC293A8eA996" + }, + "ProxyAdmin": { + "address": "0x4e44E79e0cEc05D9e62e952B2088c02A3C450aeC", + "legacyAddresses": [], + "deploymentBlock": "0x01" + }, + "SignatureController": { + "address": "0x7bB6Cd9be29fab783c0b494A06FED8b2E2596B7a", + "legacyAddresses": [], + "deploymentBlock": "0x02" + }, + "MintingController": { + "address": "0x4a3C194eB88966178bfDD81744ddDafED611B830", + "legacyAddresses": [], + "deploymentBlock": "0x03", + "deprecated": true + }, + "WhitelistedMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "URIPrefixController": { + "address": "0x4872CC1be60A9DB9c880A0A437Da7a6AF134F08f", + "legacyAddresses": [], + "deploymentBlock": "0x04", + "deprecated": true + }, + "DomainZoneController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "Resolver": { + "address": "0xF8C26340C1eAeA6c7fF1760B25005e1306953572", + "legacyAddresses": [], + "deploymentBlock": "0x08", + "forwarder": "0x11dD97b7Ca847DfB6504e61B7B9Eb30F55E554a0" + }, + "ProxyReader": { + "address": "0x5CC819C9915eADfcEBd76952B8C1BC36CADd7376", + "implementation": "0xBDeFCF6429D0AC68236A6BEb321cBD2Ce66B463C", + "legacyAddresses": [], + "deploymentBlock": "0x1f" + }, + "TwitterValidationOperator": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "FreeMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "MintableERC721Predicate": { + "address": "0x58a175BEbc8ec21A94ea63Aa5a28743945940EE6", + "legacyAddresses": [], + "deploymentBlock": "0x0d" + }, + "RootChainManager": { + "address": "0x27935e7e85db3c4e7885eB828B9e889BA69a4e7f", + "legacyAddresses": [], + "deploymentBlock": "0x0f" + }, + "DotCoinBurner": { + "address": "0x54563a9e1cD2dCBD0BCA90D3CFA4A647e02C404a", + "legacyAddresses": [], + "deploymentBlock": "0x27" + } + } + }, + "80001": { + "contracts": { + "UNSRegistry": { + "address": "0x2a93C52E7B6E7054870758e15A1446E769EdfB93", + "implementation": "0x010aEA2d9a25B0E0f05C27946e6FFFE0b88ad721", + "legacyAddresses": [], + "deploymentBlock": "0x01213f43", + "forwarder": "0x2a93C52E7B6E7054870758e15A1446E769EdfB93" + }, + "CNSRegistry": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "forwarder": "0x0000000000000000000000000000000000000000" + }, + "MintingManager": { + "address": "0x428189346bb3CC52f031A1092fd47C919AC30A9f", + "implementation": "0x78DB6F11a5bA8Ee61D1e5Ee25880212747ffB46F", + "legacyAddresses": [], + "deploymentBlock": "0x01213f4a", + "forwarder": "0xEf3a491A8750BEC2Dff5339CF6Df94436d432C4d" + }, + "UNSOperator": { + "address": "0x576a376832181ddD19d17CD4505F6BF8FEdb428E", + "legacyAddresses": [], + "deploymentBlock": "0x01e03592", + "implementation": "0xaBB7934fFD76282dc9d5126A5549C2695C9b52A2" + }, + "ProxyAdmin": { + "address": "0x460d63117c7Ab1624b7474C45BF46eC6702f57ce", + "legacyAddresses": [], + "deploymentBlock": "0x01213b22" + }, + "SignatureController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "MintingController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "WhitelistedMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "URIPrefixController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "DomainZoneController": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "Resolver": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "forwarder": "0x0000000000000000000000000000000000000000" + }, + "ProxyReader": { + "address": "0xBD4674F11d512120dFc8BAe5f84963d7419A5db2", + "implementation": "0x952e0E876ad3a47F503Fb53eB04dD89aA1e6B8Da", + "legacyAddresses": [ + "0x71f7C0A978A541aB13Bd5783470f38b0dd71Cf78", + "0x6fe7c857C1B0E54492C8762f27e0a45CA7ff264B", + "0xbd9e01F6513E7C05f71Bf21d419a3bDF1EA9104b", + "0x332A8191905fA8E6eeA7350B5799F225B8ed30a9" + ], + "deploymentBlock": "0x01bb07d3" + }, + "TwitterValidationOperator": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "FreeMinter": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0", + "deprecated": true + }, + "MintableERC721Predicate": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "RootChainManager": { + "address": "0x0000000000000000000000000000000000000000", + "legacyAddresses": [], + "deploymentBlock": "0x0" + }, + "DotCoinBurner": { + "address": "0x65c6abdf52aD08A53A77488D1Acc5c666ada840F", + "legacyAddresses": [], + "deploymentBlock": "0x01bbafc7" } + } } -} + } +} \ No newline at end of file diff --git a/Sources/UnstoppableDomainsResolution/Resources/UNS/unsProxyReader.json b/Sources/UnstoppableDomainsResolution/Resources/UNS/unsProxyReader.json index 55573de..ce072bd 100644 --- a/Sources/UnstoppableDomainsResolution/Resources/UNS/unsProxyReader.json +++ b/Sources/UnstoppableDomainsResolution/Resources/UNS/unsProxyReader.json @@ -12,6 +12,51 @@ "name": "Initialized", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "tokenKey", + "type": "string" + } + ], + "name": "SetLegacyRecords", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "network", + "type": "string" + } + ], + "name": "SetNetworkFamily", + "type": "event" + }, { "inputs": [], "name": "NAME", @@ -38,6 +83,60 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "networks", + "type": "string[]" + }, + { + "internalType": "string[]", + "name": "families", + "type": "string[]" + } + ], + "name": "addBlockchainNetworks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "networks", + "type": "string[]" + }, + { + "internalType": "string", + "name": "family", + "type": "string" + } + ], + "name": "addBlockchainNetworks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "keys", + "type": "string[]" + }, + { + "internalType": "string[][]", + "name": "legacyKeys", + "type": "string[][]" + } + ], + "name": "addLegacyRecords", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -100,6 +199,88 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "string", + "name": "network", + "type": "string" + }, + { + "internalType": "string", + "name": "token", + "type": "string" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getAddress", + "outputs": [ + { + "internalType": "string", + "name": "addr", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "network", + "type": "string" + }, + { + "internalType": "string", + "name": "token", + "type": "string" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getAddressKey", + "outputs": [ + { + "internalType": "string", + "name": "key", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "network", + "type": "string" + }, + { + "internalType": "string", + "name": "token", + "type": "string" + } + ], + "name": "getAddressKeys", + "outputs": [ + { + "internalType": "string[]", + "name": "keys", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -451,6 +632,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -508,6 +702,13 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -527,6 +728,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "reverseNameOf", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -546,6 +766,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -583,5 +816,18 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] \ No newline at end of file diff --git a/Tests/ResolutionTests/ResolutionTests.swift b/Tests/ResolutionTests/ResolutionTests.swift index 03eb9f0..8959a5e 100644 --- a/Tests/ResolutionTests/ResolutionTests.swift +++ b/Tests/ResolutionTests/ResolutionTests.swift @@ -420,6 +420,63 @@ class ResolutionTests: XCTestCase { TestHelpers.checkError(result: unregisteredResult, expectedError: ResolutionError.unregisteredDomain) } + func testNewAddrBeta() throws { + // Given + let l2AddressReceived = expectation(description: "Exist UNS L2 address should be received") + let l1AddressReceived = expectation(description: "Exist UNS L1 address should be received") + let emptyAddressReceived = expectation(description: "Exist UNS L2 address should be received") + let unregisteredReceived = expectation(description: "Unregistered domain should be received") + + var l1Address: String = "" + var l2Address = "" + var emptyAddress = "" + var unregisteredResult: Result! + + // When + resolution.addr(domain: TestHelpers.getTestDomain(.WALLET_DOMAIN), network: "ETH", token: "ETH" ) { (result) in + switch result { + case .success(let returnValue): + l2Address = returnValue + l2AddressReceived.fulfill() + case .failure(let error): + XCTFail("Expected Eth Address, but got \(error.localizedDescription)") + } + } + + resolution.addr(domain: TestHelpers.getTestDomain(.DOMAIN), network: "ETH", token: "ETH" ) { (result) in + switch result { + case .success(let returnValue): + l1Address = returnValue + l1AddressReceived.fulfill() + case .failure(let error): + XCTFail("Expected Eth Address, but got \(error.localizedDescription)") + } + } + + resolution.addr(domain: TestHelpers.getTestDomain(.LAYER2_DOMAIN), network: "ETH", token: "ETH") { (result) in + switch result { + case .success(let returnValue): + emptyAddress = returnValue + emptyAddressReceived.fulfill() + case .failure(let error): + XCTFail("Expected Eth Address, but got \(error.localizedDescription)") + } + } + + resolution.addr(domain: TestHelpers.getTestDomain(.UNREGISTERED_DOMAIN), network: "ETH", token: "unknown") { + unregisteredResult = $0 + unregisteredReceived.fulfill() + } + + waitForExpectations(timeout: timeout, handler: nil) + + // Then + assert(l2Address == "0x8aaD44321A86b170879d7A244c1e8d360c99DdA8") + assert(l1Address == "0x084Ac37CDEfE1d3b68a63c08B203EFc3ccAB9742") + assert(emptyAddress == "") + TestHelpers.checkError(result: unregisteredResult, expectedError: ResolutionError.unregisteredDomain) + } + func testAddr() throws { // Given let domainReceived = expectation(description: "Exist UNS domain should be received") @@ -551,92 +608,92 @@ class ResolutionTests: XCTestCase { TestHelpers.checkError(result: unregisteredResult, expectedError: ResolutionError.recordNotFound("layer1")) } - func testTokenUri() throws { - // Given - let domainReceived = expectation(description: "Exist domain should be received") - let unregisteredReceived = expectation(description: "Unregistered domain should be received") - - var tokenURI = "" - var unregisteredResult: Result! - - // When - resolution.tokenURI(domain: TestHelpers.getTestDomain(.WALLET_DOMAIN)) { (result) in - switch result { - case .success(let returnValue): - domainReceived.fulfill() - tokenURI = returnValue - case .failure(let error): - XCTFail("Expected tokenURI, but got \(error)") - } - } - - resolution.tokenURI(domain: TestHelpers.getTestDomain(.UNREGISTERED_DOMAIN)) { - unregisteredResult = $0 - unregisteredReceived.fulfill() - } - - waitForExpectations(timeout: timeout, handler: nil) - - // Then - assert(tokenURI == "https://metadata.ud-staging.com/metadata/6304531997610998161237844647282663196661123000121147597890468333969432655810") - TestHelpers.checkError(result: unregisteredResult, expectedError: ResolutionError.unregisteredDomain) - } - - func testTokenUriMetadata() throws { - // Given - let domainReceived = expectation(description: "Exist domain should be received") - let unregisteredReceived = expectation(description: "Unregistered domain should be received") - - var tokenURIMetadata: TokenUriMetadata? = nil - var unregisteredResult: Result! - - // When - resolution.tokenURIMetadata(domain: TestHelpers.getTestDomain(.WALLET_DOMAIN)) { (result) in - switch result { - case .success(let returnValue): - tokenURIMetadata = returnValue - domainReceived.fulfill() - case .failure(let error): - XCTFail("Expected tokenURIMetadata, but got \(error)") - } - } - - resolution.tokenURIMetadata(domain: TestHelpers.getTestDomain(.UNREGISTERED_DOMAIN)) { - unregisteredResult = $0 - unregisteredReceived.fulfill() - } - - waitForExpectations(timeout: timeout, handler: nil) - - let domainNamehash = try resolution.namehash(domain: TestHelpers.getTestDomain(.WALLET_DOMAIN)) - // Then - assert(tokenURIMetadata?.name == TestHelpers.getTestDomain(.WALLET_DOMAIN)) - assert(tokenURIMetadata?.attributes.count == 5) - assert(tokenURIMetadata?.namehash == domainNamehash) - TestHelpers.checkError(result: unregisteredResult, expectedError: ResolutionError.unregisteredDomain) - } - - func testUnhash() throws { - // Given - let domainReceived = expectation(description: "Existing domain should be received") - var domainName: String = "" - - // When - resolution.unhash(hash: "0x684c51201935fdd42fbaebe43b1986f13984b94569c4c4827beda913232d066f", serviceName: .uns) { (result) in - switch result { - case .success(let returnValue): - domainReceived.fulfill() - domainName = returnValue - case .failure(let error): - XCTFail("Expected domainName, but got \(error)") - } - } - - waitForExpectations(timeout: timeout, handler: nil) - - // Then - assert(domainName == "udtestdev-johnnytest.wallet") - } + // func testTokenUri() throws { + // // Given + // let domainReceived = expectation(description: "Exist domain should be received") + // let unregisteredReceived = expectation(description: "Unregistered domain should be received") + + // var tokenURI = "" + // var unregisteredResult: Result! + + // // When + // resolution.tokenURI(domain: TestHelpers.getTestDomain(.WALLET_DOMAIN)) { (result) in + // switch result { + // case .success(let returnValue): + // domainReceived.fulfill() + // tokenURI = returnValue + // case .failure(let error): + // XCTFail("Expected tokenURI, but got \(error)") + // } + // } + + // resolution.tokenURI(domain: TestHelpers.getTestDomain(.UNREGISTERED_DOMAIN)) { + // unregisteredResult = $0 + // unregisteredReceived.fulfill() + // } + + // waitForExpectations(timeout: timeout, handler: nil) + + // // Then + // assert(tokenURI == "https://metadata.ud-staging.com/metadata/6304531997610998161237844647282663196661123000121147597890468333969432655810") + // TestHelpers.checkError(result: unregisteredResult, expectedError: ResolutionError.unregisteredDomain) + // } + + // func testTokenUriMetadata() throws { + // // Given + // let domainReceived = expectation(description: "Exist domain should be received") + // let unregisteredReceived = expectation(description: "Unregistered domain should be received") + + // var tokenURIMetadata: TokenUriMetadata? = nil + // var unregisteredResult: Result! + + // // When + // resolution.tokenURIMetadata(domain: TestHelpers.getTestDomain(.WALLET_DOMAIN)) { (result) in + // switch result { + // case .success(let returnValue): + // tokenURIMetadata = returnValue + // domainReceived.fulfill() + // case .failure(let error): + // XCTFail("Expected tokenURIMetadata, but got \(error)") + // } + // } + + // resolution.tokenURIMetadata(domain: TestHelpers.getTestDomain(.UNREGISTERED_DOMAIN)) { + // unregisteredResult = $0 + // unregisteredReceived.fulfill() + // } + + // waitForExpectations(timeout: timeout, handler: nil) + + // let domainNamehash = try resolution.namehash(domain: TestHelpers.getTestDomain(.WALLET_DOMAIN)) + // // Then + // assert(tokenURIMetadata?.name == TestHelpers.getTestDomain(.WALLET_DOMAIN)) + // assert(tokenURIMetadata?.attributes.count == 5) + // assert(tokenURIMetadata?.namehash == domainNamehash) + // TestHelpers.checkError(result: unregisteredResult, expectedError: ResolutionError.unregisteredDomain) + // } + + // func testUnhash() throws { + // // Given + // let domainReceived = expectation(description: "Existing domain should be received") + // var domainName: String = "" + + // // When + // resolution.unhash(hash: "0x684c51201935fdd42fbaebe43b1986f13984b94569c4c4827beda913232d066f", serviceName: .uns) { (result) in + // switch result { + // case .success(let returnValue): + // domainReceived.fulfill() + // domainName = returnValue + // case .failure(let error): + // XCTFail("Expected domainName, but got \(error)") + // } + // } + + // waitForExpectations(timeout: timeout, handler: nil) + + // // Then + // assert(domainName == "udtestdev-johnnytest.wallet") + // } func testGetMany() throws { // Given @@ -952,75 +1009,75 @@ class ResolutionTests: XCTestCase { assert(layer2Records["weirdrecord"] == ""); } - func testTokenUriMultiLayer() throws { - let tokenUriFromL2 = expectation(description: "TokenUri from layer2 domain should be receieved"); - let tokenUriFromL1 = expectation(description: "TokenUri from layer1 domain should be received"); - - var layer2TokenUri = ""; - var layer1TokenUri = ""; - - resolution.tokenURI(domain: TestHelpers.getTestDomain(.LAYER2_DOMAIN)) { result in - switch result { - case .success(let returnValue): - layer2TokenUri = returnValue; - tokenUriFromL2.fulfill(); - case .failure(let error): - XCTFail("Expected token URI from L2, but got \(error)"); - } - } - - resolution.tokenURI(domain: TestHelpers.getTestDomain(.DOMAIN)) { result in - switch result { - case .success(let returnValue): - layer1TokenUri = returnValue; - tokenUriFromL1.fulfill(); - case .failure(let error): - XCTFail("Expected token URI from L1, but got \(error)"); - } - } - - waitForExpectations(timeout: timeout, handler: nil); - - assert(layer1TokenUri == "https://metadata.ud-staging.com/metadata/reseller-test-udtesting-459239285.crypto"); - assert(layer2TokenUri == "https://metadata.ud-staging.com/metadata/29206072489201256414040015626327292653094949751666860355749665089956336890808"); - } - - func testUnhashMultiLayer() throws { - - let layer2Domain = expectation(description: "Layer 2 domain name should be received"); - let layer1Domain = expectation(description: "Layer 1 domain name should be received"); - - let layer2Hash = "0x684c51201935fdd42fbaebe43b1986f13984b94569c4c4827beda913232d066f"; - let layer1Hash = "0x8bbfa2d157c884c94ed35832a4c327a795c12b64bc4282e3521bcad1fc4d6a8d"; - - var layer2DomainName = ""; - var layer1DomainName = ""; - - resolution.unhash(hash: layer2Hash, serviceName: .uns) { result in - switch (result) { - case .success(let returnValue): - layer2DomainName = returnValue; - layer2Domain.fulfill(); - case .failure(let error): - XCTFail("Expected layer2 domain name, but got \(error)"); - } - } - - resolution.unhash(hash: layer1Hash, serviceName: .uns) { result in - switch (result) { - case .success(let returnValue): - layer1DomainName = returnValue; - layer1Domain.fulfill(); - case .failure(let error): - XCTFail("Expected layer1 domain name, but got \(error)"); - } - } - - waitForExpectations(timeout: timeout, handler: nil); - - assert(layer1DomainName == "johnnytestdev6357.crypto"); - assert(layer2DomainName == "udtestdev-johnnytest.wallet"); - } + // func testTokenUriMultiLayer() throws { + // let tokenUriFromL2 = expectation(description: "TokenUri from layer2 domain should be receieved"); + // let tokenUriFromL1 = expectation(description: "TokenUri from layer1 domain should be received"); + + // var layer2TokenUri = ""; + // var layer1TokenUri = ""; + + // resolution.tokenURI(domain: TestHelpers.getTestDomain(.LAYER2_DOMAIN)) { result in + // switch result { + // case .success(let returnValue): + // layer2TokenUri = returnValue; + // tokenUriFromL2.fulfill(); + // case .failure(let error): + // XCTFail("Expected token URI from L2, but got \(error)"); + // } + // } + + // resolution.tokenURI(domain: TestHelpers.getTestDomain(.DOMAIN)) { result in + // switch result { + // case .success(let returnValue): + // layer1TokenUri = returnValue; + // tokenUriFromL1.fulfill(); + // case .failure(let error): + // XCTFail("Expected token URI from L1, but got \(error)"); + // } + // } + + // waitForExpectations(timeout: timeout, handler: nil); + + // assert(layer1TokenUri == "https://metadata.ud-staging.com/metadata/reseller-test-udtesting-459239285.crypto"); + // assert(layer2TokenUri == "https://metadata.ud-staging.com/metadata/29206072489201256414040015626327292653094949751666860355749665089956336890808"); + // } + + // func testUnhashMultiLayer() throws { + + // let layer2Domain = expectation(description: "Layer 2 domain name should be received"); + // let layer1Domain = expectation(description: "Layer 1 domain name should be received"); + + // let layer2Hash = "0x684c51201935fdd42fbaebe43b1986f13984b94569c4c4827beda913232d066f"; + // let layer1Hash = "0x8bbfa2d157c884c94ed35832a4c327a795c12b64bc4282e3521bcad1fc4d6a8d"; + + // var layer2DomainName = ""; + // var layer1DomainName = ""; + + // resolution.unhash(hash: layer2Hash, serviceName: .uns) { result in + // switch (result) { + // case .success(let returnValue): + // layer2DomainName = returnValue; + // layer2Domain.fulfill(); + // case .failure(let error): + // XCTFail("Expected layer2 domain name, but got \(error)"); + // } + // } + + // resolution.unhash(hash: layer1Hash, serviceName: .uns) { result in + // switch (result) { + // case .success(let returnValue): + // layer1DomainName = returnValue; + // layer1Domain.fulfill(); + // case .failure(let error): + // XCTFail("Expected layer1 domain name, but got \(error)"); + // } + // } + + // waitForExpectations(timeout: timeout, handler: nil); + + // assert(layer1DomainName == "johnnytestdev6357.crypto"); + // assert(layer2DomainName == "udtestdev-johnnytest.wallet"); + // } func testReverseTokenId() { // Given @@ -1069,50 +1126,50 @@ class ResolutionTests: XCTestCase { TestHelpers.checkError(result: reverseDoesntExistResult, expectedError: ResolutionError.reverseResolutionNotSpecified) } - func testReverse() { - // Given - let reverseReceived = expectation(description: "Reverse resolution should be received"); - let reverseL2Received = expectation(description: "Reverse resolution should be received with explicit layer"); - let reverseDoesntExistReceived = expectation(description: "Error should be received for not existing reverse resolution"); - - let reverseAddress = "0xd92d2a749424a5181ad7d45f786a9ffe46c10a7c" - let reverseDoesntExist = "0x0000000000000000000000000000000000000001" - - var reverseResult = "" - var reverseL2Result = "" - var reverseDoesntExistResult: Result! - - // When - resolution.reverse(address: reverseAddress, location: nil) { (result) in - switch result { - case .success(let returnValue): - reverseReceived.fulfill() - reverseResult = returnValue - case .failure(let error): - XCTFail("Expected reverse resolution, but got \(error)") - } - } - - resolution.reverse(address: reverseAddress, location: .layer2) { (result) in - switch result { - case .success(let returnValue): - reverseL2Received.fulfill(); - reverseL2Result = returnValue; - case .failure(let error): - XCTFail("Expected reverse resolution from layer2, but got \(error)") - } - } - - resolution.reverse(address: reverseDoesntExist, location: nil) { - reverseDoesntExistResult = $0 - reverseDoesntExistReceived.fulfill() - } - - waitForExpectations(timeout: timeout, handler: nil) - - // Then - assert(reverseResult == "uns-devtest-265f8f.wallet") - assert(reverseL2Result == "uns-devtest-265f8f.wallet") - TestHelpers.checkError(result: reverseDoesntExistResult, expectedError: ResolutionError.reverseResolutionNotSpecified) - } + // func testReverse() { + // // Given + // let reverseReceived = expectation(description: "Reverse resolution should be received"); + // let reverseL2Received = expectation(description: "Reverse resolution should be received with explicit layer"); + // let reverseDoesntExistReceived = expectation(description: "Error should be received for not existing reverse resolution"); + + // let reverseAddress = "0xd92d2a749424a5181ad7d45f786a9ffe46c10a7c" + // let reverseDoesntExist = "0x0000000000000000000000000000000000000001" + + // var reverseResult = "" + // var reverseL2Result = "" + // var reverseDoesntExistResult: Result! + + // // When + // resolution.reverse(address: reverseAddress, location: nil) { (result) in + // switch result { + // case .success(let returnValue): + // reverseReceived.fulfill() + // reverseResult = returnValue + // case .failure(let error): + // XCTFail("Expected reverse resolution, but got \(error)") + // } + // } + + // resolution.reverse(address: reverseAddress, location: .layer2) { (result) in + // switch result { + // case .success(let returnValue): + // reverseL2Received.fulfill(); + // reverseL2Result = returnValue; + // case .failure(let error): + // XCTFail("Expected reverse resolution from layer2, but got \(error)") + // } + // } + + // resolution.reverse(address: reverseDoesntExist, location: nil) { + // reverseDoesntExistResult = $0 + // reverseDoesntExistReceived.fulfill() + // } + + // waitForExpectations(timeout: timeout, handler: nil) + + // // Then + // assert(reverseResult == "uns-devtest-265f8f.wallet") + // assert(reverseL2Result == "uns-devtest-265f8f.wallet") + // TestHelpers.checkError(result: reverseDoesntExistResult, expectedError: ResolutionError.reverseResolutionNotSpecified) + // } } diff --git a/UnstoppableDomainsResolution.podspec b/UnstoppableDomainsResolution.podspec index bf9dd53..cfa4d17 100644 --- a/UnstoppableDomainsResolution.podspec +++ b/UnstoppableDomainsResolution.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = "UnstoppableDomainsResolution" - spec.version = "6.0.0" + spec.version = "6.1.0" spec.summary = "Swift framework for resolving Unstoppable domains." spec.description = <<-DESC