{"id":20415746,"url":"https://github.com/unstoppabledomains/resolution-go","last_synced_at":"2025-04-12T17:06:43.932Z","repository":{"id":38172789,"uuid":"336585983","full_name":"unstoppabledomains/resolution-go","owner":"unstoppabledomains","description":"Golang library for resolving unstoppable domains","archived":false,"fork":false,"pushed_at":"2023-10-02T11:08:21.000Z","size":22276,"stargazers_count":32,"open_issues_count":2,"forks_count":13,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-26T11:21:29.814Z","etag":null,"topics":["crypto","resolution","unstoppable-domains","zilliqa"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unstoppabledomains.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-06T16:45:33.000Z","updated_at":"2024-12-13T15:01:16.000Z","dependencies_parsed_at":"2024-06-18T22:46:05.772Z","dependency_job_id":"ded06860-65c9-4ad1-9d0e-4df7d96fb5de","html_url":"https://github.com/unstoppabledomains/resolution-go","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unstoppabledomains","download_url":"https://codeload.github.com/unstoppabledomains/resolution-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248602303,"owners_count":21131615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crypto","resolution","unstoppable-domains","zilliqa"],"created_at":"2024-11-15T06:17:24.387Z","updated_at":"2025-04-12T17:06:43.910Z","avatar_url":"https://github.com/unstoppabledomains.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Test](https://github.com/unstoppabledomains/resolution-go/workflows/Test/badge.svg?branch=master)\n![Lint](https://github.com/unstoppabledomains/resolution-go/workflows/Lint/badge.svg?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/unstoppabledomains/resolution-go)](https://goreportcard.com/report/github.com/unstoppabledomains/resolution-go)\n[![GoDoc](https://godoc.org/github.com/unstoppabledomains/resolution-go?status.svg)](https://pkg.go.dev/github.com/unstoppabledomains/resolution-go)\n[![Unstoppable Domains Documentation](https://img.shields.io/badge/docs-unstoppabledomains.com-blue)](https://docs.unstoppabledomains.com/)\n[![Get help on Discord](https://img.shields.io/badge/Get%20help%20on-Discord-blueviolet)](https://discord.gg/b6ZVxSZ9Hn)\n\n# resolution-go\n\nresolution-go is a library for interacting with blockchain domain names. It can be used to retrieve [payment addresses](https://unstoppabledomains.com/learn/how-to-send-crypto-using-your-domain) and IPFS hashes for [decentralized websites](https://support.unstoppabledomains.com/support/solutions/articles/48001181925-build-website).\n\nresolution-go is primarily built and maintained by [Unstoppable Domains](https://unstoppabledomains.com/).\n\nResolution supports different decentralized domains. Please, refer to the [Top Level Domains List](https://resolve.unstoppabledomains.com/supported_tlds)\n\n- [Installing Resolution](#installing-resolution-go)\n- [Updating Resolution](#updating-resolution-go)\n- [Using Resolution](#using-resolution)\n  - [Web3Domain Resolution](#web3domain-resolution)\n  - [Unstoppable Domain Resolution](#unstoppable-domain-resolution)\n- [Contributions](#contributions)\n- [Free advertising for integrated apps](#free-advertising-for-integrated-apps)\n\n# Installing resolution-go\n\n```shell\ngo get github.com/unstoppabledomains/resolution-go/v3\n```\n\n# Updating resolution-go\n\n```shell\ngo get -u github.com/unstoppabledomains/resolution-go/v3\n```\n\n# Using Resolution\n\n---\n**NOTE**\n\nFrom version `3.2.0`, we introduce a new interface to handle multiple naming services domain resolution.\n\nIf you wish to migrate to the new interface to be able resolve other naming services such as [ENS](https://ens.domains/), please reference the new interface.\n\n---\n\n## Web3Domain Resolution\n\nWe are currently support the following naming services. More naming service on other blockchain are coming...\n* UNS: `.x`, `.crypto`, `.go` etc... \n* ZNS: `.zil`\n* ENS: `.eth`, `.kred`, `.xyz`, `.luxe`\n\n### Initialize with Unstoppable Domains' Proxy Provider\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/unstoppabledomains/resolution-go/v3\"\n)\n\nfunc main() {\n\t// obtain a key from https://unstoppabledomains.com/partner-api-dashboard if you are a partner\n\tweb3domain, _ := resolution.NewWeb3DomainBuilder().SetUdClient(\"\u003capi_key\u003e\").Build()\n}\n\n```\n\n## Initialize with Custom Providers Configuration\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/Zilliqa/gozilliqa-sdk/provider\"\n\t\"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/unstoppabledomains/resolution-go/v3\"\n)\n\nfunc main() {\n\t// obtain a key from https://www.infura.io\n\tethereumUrl := \"https://mainnet.infura.io/v3/\u003cinfura_api_key\u003e\"\n\tmaticUrl := \"https://polygon-mainnet.infura.io/v3/\u003cinfura_api_key\u003e\"\n\n\tweb3DomainBuilder := resolution.NewWeb3DomainBuilder()\n\tethBackend, _ := ethclient.Dial(ethereumUrl)\n\tmaticBackend, _ := ethclient.Dial(maticUrl)\n\n\tweb3DomainBuilder.SetEthContractBackend(backend)\n\tweb3DomainBuilder.SetMaticContractBackend(backendL2)\n\n\tw3bDomain, _ = web3DomainBuilder.Build()\n}\n```\n### Resolve web3 domains example\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/Zilliqa/gozilliqa-sdk/provider\"\n\t\"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/unstoppabledomains/resolution-go/v3\"\n\t\"github.com/unstoppabledomains/resolution-go/v3/namingservice\"\n)\n\nfunc main() {\n\tweb3Domain, _ := resolution.NewWeb3DomainBuilder().SetUdClient(\"\u003capi_key\u003e\").Build()\n\n\t// .x domain - UNS naming service\n\tunsDomain := \"lisa.x\"\n\tlisaAddress, _ := web3Domain.Owner(unsDomain)\n\tfmt.Printf(\"Owner of %s is %s\\n\", unsDomain, lisaAddress)\n\tlisaEthAddress, _ := web3Domain.Addr(unsDomain, \"ETH\")\n\tfmt.Printf(\"ETH address of %s is %s\\n\", unsDomain, lisaEthAddress)\n\n\t// .eth domain - ENS naming service\n\tensDomain := \"vitalik.eth\"\n\tvitalikAddress, _ := web3Domain.Owner(ensDomain)\n\tfmt.Printf(\"Owner of %s is %s\\n\", ensDomain, vitalikAddress)\n\tvitalikEthAddress, _ := web3Domain.Addr(ensDomain, \"ETH\")\n\tfmt.Printf(\"ETH address of %s is %s\\n\", ensDomain, vitalikEthAddress)\n\n\t// .zil domain - ZNS naming service\n\tznsDomain := \"brad.zil\"\n\tbradAddress, _ := web3Domain.Owner(znsDomain)\n\tfmt.Printf(\"Owner of %s is %s\\n\", znsDomain, bradAddress)\n\tbradEthAddress, _ := web3Domain.Addr(znsDomain, \"ETH\")\n\tfmt.Printf(\"ETH address of %s is %s\\n\", znsDomain, bradEthAddress)\n\n\t//reverse resolution\n\taddress1 := \"0x05391f2407B664fbd1dcA5AEa9eEa89A29B946b4\"\n\tfoundDomain, _ := web3Domain.ReverseOf(address1)\n\tfmt.Printf(\"foundDomain for address %s is %s\\n\", address1, foundDomain) // tun.x\n\n\taddress2 := \"0x4309325e607de185bd6b091cc2e3cfc9f4d6e2e1\"\n\tfoundEthDomain, _ := web3Domain.ReverseOf(address2)\n\tfmt.Printf(\"foundDomain for address %s is %s\\n\", address2, foundEthDomain) // unimev.eth\n\n\tfoundDomains, _ := web3Domain.MultiReverseOf(address1) \t// find a list of domains the address revere resolution to\n\tfmt.Printf(\"foundDomain for address %s is %v\\n\", address1, foundDomains) // [tun.x tu-nguyen.eth]\n\n\n\t//get addr records\n\tcoinAddressUnsDomain, _ := web3Domain.Addr(unsDomain, \"ETH\")\n\tfmt.Printf(\"ETH address of %s is %s\\n\", unsDomain, coinAddressUnsDomain)\n\n\tcoinAddressEnsDomain, _ := web3Domain.Addr(ensDomain, \"ETH\")\n\tfmt.Printf(\"ETH address of %s is %s\\n\", ensDomain, coinAddressEnsDomain)\n\n\t// For ENS domains, it's crucial to know that a domain is still valid\n\tensExpiry, _ := web3Domain.DomainExpiry(ensDomain)\n\tfmt.Printf(\"Is %s expired %t\\n\", ensDomain, ensExpiry.Before(time.Now()))\n}\n```\n\n## Unstoppable Domain Resolution\n\n### Initialize with Unstoppable Domains' Proxy Provider\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/unstoppabledomains/resolution-go/v3\"\n)\n\nfunc main() {\n\t// obtain a key from https://unstoppabledomains.com/partner-api-dashboard if you are a partner\n\tuns, _ := resolution.NewUnsBuilder().SetUdClient(\"\u003capi_key\u003e\").Build()\n}\n\n```\n\n### Initialize with Custom Ethereum Provider Configuration\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/Zilliqa/gozilliqa-sdk/provider\"\n\t\"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/unstoppabledomains/resolution-go/v3\"\n)\n\nfunc main() {\n\t// obtain a key from https://www.infura.io\n\tvar ethereumUrl = \"https://mainnet.infura.io/v3/\u003cinfura_api_key\u003e\"\n\tvar ethereumL2Url = \"https://polygon-mainnet.infura.io/v3/\u003cinfura_api_key\u003e\"\n\n\tunsBuilder := resolution.NewUnsBuilder()\n\tbackend, _ := ethclient.Dial(ethereumUrl)\n\tbackendL2, _ := ethclient.Dial(ethereumL2Url)\n\n\tunsBuilder.SetContractBackend(backend)\n\tunsBuilder.SetL2ContractBackend(backendL2)\n\n\tuns, _ = unsBuilder.Build()\n\n\tzilliqaProvider := provider.NewProvider(\"https://api.zilliqa.com\")\n\tzns, _ := resolution.NewZnsBuilder().SetProvider(zilliqaProvider).Build()\n}\n```\n\n### Resolve domains example\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/Zilliqa/gozilliqa-sdk/provider\"\n\t\"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/unstoppabledomains/resolution-go/v3\"\n\t\"github.com/unstoppabledomains/resolution-go/v3/namingservice\"\n)\n\nfunc main() {\n\t// Resolve .crypto\n\tuns, _ := resolution.NewUnsBuilder().SetUdClient(\"\u003capi_key\u003e\").Build()\n\tethAddress, _ := uns.Addr(\"brad.crypto\", \"ETH\")\n\tfmt.Println(\"ETH address for brad.crypto is\", ethAddress)\n\n\t// Resolve.zil\n\tzns, _ := resolution.NewZnsBuilder().Build()\n\tbtcAddress, _ := zns.Addr(\"brad.zil\", \"BTC\")\n\tfmt.Println(\"BTC address for brad.zil is\", btcAddress)\n\n\t// Get locations of domains\n\tuns, _ = resolution.NewUnsBuilder().Build()\n\tlocations, _ := uns.Locations([]string{\"ryan.crypto\", \"brad.crypto\"})\n\tfmt.Println(\"Locations for ryan.crypto and brad.crypto are\", locations)\n\n\t// Detect domain naming service\n\tnamingServices := map[string]resolution.NamingService{namingservice.UNS: uns, namingservice.ZNS: zns}\n\tdomainToDetect := \"ryan.crypto\"\n\tnamingServiceName, _ := resolution.DetectNamingService(domainToDetect)\n\tif namingServices[namingServiceName] != nil {\n\t\tresolvedAddress, _ := namingServices[namingServiceName].Addr(domainToDetect, \"ETH\")\n\t\tfmt.Println(\"ETH address for\", domainToDetect, \"is\", resolvedAddress)\n\t}\n}\n```\n\n### Resolve Wallet Address Examples\n\n---\n**NOTE**\n\nThese example are only applied to UNS using `NewUnsBuilder` function\n\n---\n\n#### Using **`Addr`**\n\nThis API is used to retrieve wallet address for single address record. (See\n[Cryptocurrency payment](https://docs.unstoppabledomains.com/resolution/guides/records-reference/#cryptocurrency-payments)\nsection for the record format)\n\n```go\nfunc main() {\n\t//...\n\t// homecakes.crypto has `crypto.ETH.address` set to 0xe7474D07fD2FA286e7e0aa23cd107F8379085037\n\tdomain := \"homecakes.crypto\"\n\twalletAddress, err := uns.Addr(domain, \"ETH\")\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tfmt.Printf(\"Addr for %s ticker %s: %s\\n\", domain, \"ETH\", walletAddress)\n\t// Addr for homecakes.crypto ticker ETH: 0xe7474D07fD2FA286e7e0aa23cd107F8379085037\n}\n```\n\n#### Using **`GetAddr`**\n\nThis (beta) API can be used to resolve different formats\n\n**Resolve single address format (similar to **`Addr`** API)**\n\nWith `homecakes.crypto` has a `crypto.ETH.address` record set on-chain:\n\n```go\nfunc main() {\n\tdomain := \"homecakes.crypto\"\n\twalletAddress, err := uns.GetAddr(domain, \"ETH\", \"ETH\")\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tfmt.Printf(\"Addr for %s on network %s with token %s: %s\\n\", domain, \"ETH\", \"ETH\", walletAddress)\n\t// Addr for homecakes.crypto on network ETH with token ETH: 0xe7474D07fD2FA286e7e0aa23cd107F8379085037\n}\n```\n\n**Resolve multi-chain currency address format (See\n[multi-chain currency](https://docs.unstoppabledomains.com/resolution/guides/records-reference/#multi-chain-currencies))**\n\nWith `aaron.x` has a `crypto.AAVE.version.ERC20.address` record set to\n`0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af`. The `ERC20` indicates it's a token\non `ETH` network:\n\n```go\nfunc main() {\n\tdomain := \"aaron.x\"\n\twalletAddress, err := uns.GetAddr(domain, \"ETH\", \"AAVE\")\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tfmt.Printf(\"Addr for %s on network %s with token %s: %s\\n\", domain, \"ETH\", \"AAVE\", walletAddress)\n\t// Addr for aaron.x on network ETH with token AAVE: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n}\n```\n\n**Derive wallet addresses within the same blockchain network and blockchain\nfamily.**\n\nThe API can also be used by crypto exchanges to infer wallet addresses. In\ncentralized exchanges, users have same wallet addresses on different networks with same\nwallet family. (See [Blockchain Family, Network, Token Level Addresses](https://apidocs.unstoppabledomains.com/resolution/guides/records-reference/#blockchain-family-network-token-level-addresses) section for the record format)\n\nWith `blockchain-family-keys.x` only has `token.EVM.address` record on-chain.\nThe API resolves to same wallet address for tokens live on EVM compatible\nnetworks.\n\n```go\n\nfunc main() {\n\tdomain := \"blockchain-family-keys.x\"\n\taaveOnEthWallet, _ := uns.GetAddr(domain, \"ETH\", \"AAVE\")\n\tfmt.Printf(\"Addr for %s on network %s with token %s: %s\\n\", domain, \"ETH\", \"AAVE\", aaveOnEthWallet)\n\t// Addr for blockchain-family-keys.x on network ETH with token AAVE: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\n\tethOnEthWallet, _ := uns.GetAddr(domain, \"ETH\", \"ETH\")\n\tfmt.Printf(\"Addr for %s on network %s with token %s: %s\\n\", domain, \"ETH\", \"ETH\", ethOnEthWallet)\n\t// Addr for blockchain-family-keys.x on network ETH with token ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\n\tusdtOnAvax, _ := uns.GetAddr(domain, \"AVAX\", \"USDT\")\n\tfmt.Printf(\"Addr for %s on network %s with token %s: %s\\n\", domain, \"AVAX\", \"USDT\", usdtOnAvax)\n\t// Addr for blockchain-family-keys.x on network AVAX with token USDT: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n}\n```\n\nWith `uns-devtest-nickshatilo-withdraw-test2.x` only has `token.EVM.ETH.address`\nrecord on chain. The API resolves to the same wallet address for tokens\nspecifically on Ethereum network.\n\n```go\nfunc main() {\n\tdomain := \"uns-devtest-nickshatilo-withdraw-test2.x\"\n\taaveOnEthWallet, _ := uns.GetAddr(domain, \"ETH\", \"AAVE\")\n\tfmt.Printf(\"Addr for %s on network %s with token %s: %s\\n\", domain, \"ETH\", \"AAVE\", aaveOnEthWallet)\n\t// Addr for uns-devtest-nickshatilo-withdraw-test2.x on network ETH with token AAVE: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\n\tethOnEthWallet, _ := uns.GetAddr(domain, \"ETH\", \"ETH\")\n\tfmt.Printf(\"Addr for %s on network %s with token %s: %s\\n\", domain, \"ETH\", \"ETH\", ethOnEthWallet)\n\t// Addr for uns-devtest-nickshatilo-withdraw-test2.x on network ETH with token ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\n\tusdtOnAvax, _ := uns.GetAddr(domain, \"AVAX\", \"USDT\")\n\t// won't work\n}\n```\n\nThe API is compatible with other address formats. If a domain has multiple\naddress formats set, it will follow the algorithm described as follow:\n\nif a domain has following records set:\n\n```\ntoken.EVM.address\ncrypto.USDC.version.ERC20.address\ntoken.EVM.ETH.USDC.address\ncrypto.USDC.address\ntoken.EVM.ETH.address\n```\n\n`getAddress(domain, 'ETH', 'USDC')` will lookup records in the following order:\n\n```\n1. token.EVM.ETH.USDC.address\n2. crypto.USDC.address\n3. crypto.USDC.version.ERC20.address\n4. token.EVM.ETH.address\n5. token.EVM.address\n```\n\n# Contributions\n\nContributions to this library are more than welcome. The easiest way to contribute is through GitHub issues and pull requests.\n\nUse these commands to set up a local development environment (**macOS Terminal**\nor **Linux shell**).\n\n1. Recommended golang version\n\n- go1.18\n\n2. Clone the repository\n\n   ```bash\n   git clone https://github.com/unstoppabledomains/resolution-go.git\n   cd resolution-go\n   ```\n\n3. Install dependencies\n\n   ```bash\n   go mod download\n   ```\n\n### Internal config\n\n#### Unit tests:\n\n**resolution-go** library relies on environment variables to load **TestNet** RPC Urls. This way, our keys don't expose directly to the code. In order to validate the code change, please set these variables to your local environment.\n\n- L1_TEST_NET_RPC_URL\n- L2_TEST_NET_RPC_URL\n\n# Free advertising for integrated apps\n\nOnce your app has a working Unstoppable Domains integration, [register it here](https://unstoppabledomains.com/app-submission). Registered apps appear on the Unstoppable Domains [homepage](https://unstoppabledomains.com/) and [Applications](https://unstoppabledomains.com/apps) page — putting your app in front of tens of thousands of potential customers per day.\n\nAlso, 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.\n\n# Get help\n\n[Join our discord community](https://discord.gg/unstoppabledomains) and ask questions.\n\n# Help us improve\n\nWe're always looking for ways to improve how developers use and integrate our products into their applications. We'd love to hear about your experience to help us improve by [taking our survey](https://form.typeform.com/to/uHPQyHO6).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funstoppabledomains%2Fresolution-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funstoppabledomains%2Fresolution-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funstoppabledomains%2Fresolution-go/lists"}