Edit this page

Resolution-Swift

This page details basic installation, configuration, and usage of the Swift Resolution Library.

Installation

Resolution Swift can be installed with either Cocoa Pods or Swift Package Manager dependency managers.

Cocoa PodsSwift Package Manager
Copy
Copied
pod 'UnstoppableDomainsResolution', '~> 5.0.0'
Copy
Copied
package.dependencies.append(
    .package(url: "https://github.com/unstoppabledomains/resolution-swift", from: "5.0.0")
)

Updating Resolution Swift

Resolution Swift can be updated with either Cocoa Pods or Swift Package Manager dependency managers.

Cocoa PodsSwift Package Manager
Copy
Copied
pod update UnstoppableDomainsResolution
Copy
Copied
package.dependencies.append(
    .package(url: "https://github.com/unstoppabledomains/resolution-swift", from: "<latest version number>")
)

Initialize with Unstoppable Domains' Proxy Provider

Copy
Copied
import UnstoppableDomainsResolution
// 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: "<api_key>") else {
  print ("Init of Resolution instance failed...")
  return
}

Initialize with Custom Ethereum Configuration

Configuration

The Resolution libraries require a connection to the Ethereum network to resolve domains (.crypto, .nft, etc.). To use these libraries, you must specify an Ethereum node service provider. Once you have created an instance of the library, you can begin resolving domains. Examples of how to initialize the library with different providers are provided below.

Provider URL

Each of the Resolution Libraries supports using an Ethereum provider URL for configuration. You can obtain this URL from a service like Alchemy, which offers a free API key to users who create an account. If you wish to use an alternative Ethereum provider, see the Nodes as a Service guide for more information.

Copy
Copied
import UnstoppableDomainsResolution

// obtain a key from https://www.infura.io
let resolution = try Resolution(configs: Configurations(
        uns: UnsLocations = UnsLocations(
            layer1: NamingServiceConfig(
                providerUrl: "https://mainnet.infura.io/v3/<infura_api_key>",
                network: "mainnet"),
            layer2: NamingServiceConfig(
                providerUrl: "https://polygon-mainnet.infura.io/v3/<infura_api_key>",
                network: "polygon-mainnet"),
            znsLayer: NamingServiceConfig(
                providerUrl: "https://api.zilliqa.com",
                network: "mainnet")
        )
);
warning

Make sure to allow eth-mainnet.g.alchemy.com and polygon-mainnet.g.alchemy.com or simply https://*.g.alchemy.com (if using the default configuration) as a connect-src in your Content Security Policy to allow these requests through.

Error Handling

Unstoppable Domains follows the error handling best practices specific to each library's language. Each error data structure contains an error code, a human-readable message, and extra details that may help you debug the error.

Copy
Copied
{
  code: string; // one of our custom error codes
  message?: string; // human-readable error summary
  providerMessage?: string; // internal error message from the provider (alchemy, infura, etc.)
  errorMessage?: string; // internal error message / nested error
  method?: ResolutionMethod; // resolution method (UNS L1, UNS L2, CNS, ZNS, UD API)
  methodName?: string; // resolution method that was used (e.g. Resolution.addr, Resolution.allRecords)
  domain?: string; // domain that caused the error
  currencyTicker?: string; // currency ticker that caused the error
  recordName?: string; // record that caused the error
  namingService?: string; // naming service (UNSL1, UNSL2, ZNS, ENS, CNS, etc.)
  location?: UnsLocation; // domain location (L1, L2)
  tokenUri?: string; // domain metadata link
}

The code snippet below shows how to handle the common error cases you may encounter during integration, including:

  • Resolving an unregistered domain
  • Resolving an undefined record of a domain
  • Resolving a misconfigured domain
  • Resolving a domain with an unsupported domain ending

We handle the errors thrown by the resolution library by switching on the error code and displaying custom messages to the user. You can then perform other actions to handle the error or show the error message value from the error data structure to the user.

Copy
Copied
import UnstoppableDomainsResolution

// 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: "<api_key>") else {
  print ("Init of Resolution instance failed...")
  return
}

resolution.addr(domain: "domain-with-error.crypto", ticker: "ETH") { result in
    switch result {
        case .success(let returnValue):
            // Success flow
        case .failure(let error):
            switch error {
                case ResolutionError.unregisteredDomain:
                    // Domain is not registered
                    break;

                case ResolutionError.recordNotFound:
                    // Crypto record is not found (or empty)
                    break;

                case ResolutionError.unspecifiedResolver:
                    // Domain is not configured (empty resolver)
                    break;

                case ResolutionError.unsupportedDomain:
                    // Domain is not supported
                    break;
            }
    }
}

Error Codes

Error Code Description
badRequestOrResponse Thrown by the RPC provider when the request or request is invalid.
contractNotInitialized Thrown when the proxy reader of the current resolution instance has not been initialized.
executionReverted Thrown by the json RPC when the smart contract call is reverted.
inconsistentDomainArray Thrown when you attempt to retrieve the locations of multiple domains with different naming services. The location of a domain contains the blockchain, networkId, and valuable metadata like owner, resolver, registry addresses, and provider URL of that domain.
invalidDomainName Thrown when you resolve an invalid domain address.
methodNotSupported Thrown when you use a method of the current resolution instance not supported by the naming service you're resolving from. For example, using the batchOwners(), getTokenUri(), locations(), and getDomainName() methods for the Zilliqa Name Service (ZNS).
proxyReaderNonInitialized Thrown when the registry address of the current resolution instance has not been initialized.
recordNotFound Thrown when you resolve an undefined record of a domain. For example, resolving the Twitter handle of a domain that doesn't have one.
recordNotSupported Thrown when you resolve an unsupported domain record.
registryAddressIsNotProvided Thrown when using an incorrect contract address with the current resolution instance.
reverseResolutionNotSpecified Thrown when reverse resolution is not configured for an address.
tooManyResponses Thrown when you have exceeded the rate limit of the RPC provider configured.
unregisteredDomain Thrown when you resolve a domain not owned by any address.
unknownError Thrown when an unknown error occurs while resolving a domain with the current resolution instance.
unspecifiedResolver Thrown when the domain resolver contract address is not found. For example, the domain doesn't have a specified resolver.
unsupportedDomain Thrown when you resolve a domain with an ending not supported by the current resolution instance.
unsupportedNetwork Thrown when you resolve a domain with an unsupported blockchain network (e.g. testnets).
unsupportedServiceName Thrown when using an unsupported naming service with the current resolution instance.

Use Case: Retrieve a Domain Record

Retrieve any record of a domain. Applications sometimes set custom records for a domain to use within their application. The code snippet below show how to do this in Swift.

Copy
Copied
// lookup specific records
resolution.record(domain: "ryan.crypto", record: "custom.record.value") { result in
  switch result {
    case .success(let returnValue):
      // example custom record value
      let recordValue = returnValue
    case .failure(let error):
      print("Expected record value, but got \(error)")
    }
}

Use Case: Resolve Addresses Existing on Multiple Blockchains

The resolution library provides a method for resolving the addresses of tickers for different blockchains (e.g. USDT exists on EOS, ERC20, OMNI, and TRON blockchains). The code snippet below show how to do this in Swift.

Copy
Copied
// resolve multichain address
resolution.multiChainAddress(domain: "udtestdev-usdt.crypto", ticker: "USDT", chain: "ERC20") { (result) in
  switch result {
  case .success(let returnValue):
     receiverUSDTAddress = returnValue;
     // receiverUSDTAddress consists address for receiving USDT on Ethereum (ERC20 version)
     // use this address as recipient of the payment
  case .failure(let error):
     print("Expected USDT-ETC20 Address, but got \(error)")
  }