{"id":15546774,"url":"https://github.com/unstoppabledomains/resolution","last_synced_at":"2025-05-15T04:08:15.181Z","repository":{"id":36475979,"uuid":"157450306","full_name":"unstoppabledomains/resolution","owner":"unstoppabledomains","description":"A library to resolve blockchain domain names.","archived":false,"fork":false,"pushed_at":"2025-01-16T17:59:35.000Z","size":5225,"stargazers_count":224,"open_issues_count":6,"forks_count":68,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-05-03T12:35:50.522Z","etag":null,"topics":["blockchain","cns","domains","ethereum","resolution","zns"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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":"2018-11-13T21:36:30.000Z","updated_at":"2025-01-16T17:04:06.000Z","dependencies_parsed_at":"2023-10-03T10:14:51.521Z","dependency_job_id":"9c8bf016-e1f7-4d80-b501-10e5646a4be8","html_url":"https://github.com/unstoppabledomains/resolution","commit_stats":{"total_commits":942,"total_committers":32,"mean_commits":29.4375,"dds":0.6953290870488322,"last_synced_commit":"b48f95341853167057bbab6708fd1a85329a6432"},"previous_names":["unstoppabledomains/namicorn"],"tags_count":153,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unstoppabledomains%2Fresolution/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unstoppabledomains","download_url":"https://codeload.github.com/unstoppabledomains/resolution/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254120915,"owners_count":22018064,"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":["blockchain","cns","domains","ethereum","resolution","zns"],"created_at":"2024-10-02T13:04:42.455Z","updated_at":"2025-05-15T04:08:10.155Z","avatar_url":"https://github.com/unstoppabledomains.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Resolution\n\n[![NPM version](https://img.shields.io/npm/v/@unstoppabledomains/resolution.svg?style=flat)](https://www.npmjs.com/package/@unstoppabledomains/resolution)\n![CI](https://github.com/unstoppabledomains/resolution/workflows/CI/badge.svg?branch=master)\n[![Bundle Size Minified](https://img.shields.io/bundlephobia/min/@unstoppabledomains/resolution.svg)](https://bundlephobia.com/result?p=@unstoppabledomains/resolution)\n[![Bundle Size Minified Zipped](https://img.shields.io/bundlephobia/minzip/@unstoppabledomains/resolution.svg)](https://bundlephobia.com/result?p=@unstoppabledomains/resolution)\n[![Unstoppable Domains Documentation](https://img.shields.io/badge/Documentation-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- [Installing Resolution](#installing-resolution)\n- [Updating Resolution](#updating-resolution)\n- [Using Resolution](#using-resolution)\n- [Error Handling](#error-handling)\n- [Development](#development)\n- [Free advertising for integrated apps](#free-advertising-for-integrated-apps)\n\nResolution is a library for interacting with blockchain domain names. It can be\nused to retrieve\n[payment addresses](https://unstoppabledomains.com/learn/how-to-send-crypto-using-your-domain)\nand IPFS hashes for\n[decentralized websites](https://support.unstoppabledomains.com/support/solutions/articles/48001181925-build-website).\n\nResolution is primarily built and maintained by\n[Unstoppable Domains](https://unstoppabledomains.com/).\n\nResolution supports different decentralized domains. Please, refer to the\n[Top Level Domains List](https://api.unstoppabledomains.com/resolve/supported_tlds)\n\nFor more information, see our detailed\n[API Reference](https://unstoppabledomains.github.io/resolution/).\n\n## Installing Resolution\n\nResolution can be installed with either `yarn` or `npm`.\n\n```shell\nyarn add @unstoppabledomains/resolution\n```\n\n```shell\nnpm install @unstoppabledomains/resolution --save\n```\n\nIf you're interested in resolving domains via the command line, see our\n[CLI section](#command-line-interface).\n\n## Updating Resolution\n\nResolution can be updated with either `yarn` or `npm`.\n\n```shell\nyarn upgrade @unstoppabledomains/resolution --latest\n```\n\n```shell\nnpm update @unstoppabledomains/resolution --save\n```\n\n## Using Resolution\n\n## Initialize with Unstoppable Domains' UNS Proxy Provider\n\n```javascript\nconst {default: Resolution} = require('@unstoppabledomains/resolution');\n\n// obtain a key by following this document https://docs.unstoppabledomains.com/domain-distribution-and-management/quickstart/retrieve-an-api-key/#api-key\nconst resolution = new Resolution({apiKey: '\u003capi_key\u003e'});\n```\n\n\u003e NOTE: The `apiKey` is only used resolve domains from UNS. Behind the scene, it\n\u003e still uses the default ZNS (Zilliqa) RPC url. For additional control, please\n\u003e specify your ZNS configuration.\n\n```javascript\nconst {default: Resolution} = require('@unstoppabledomains/resolution');\n\nconst resolution = new Resolution({\n  apiKey: '\u003capi_key\u003e',\n  sourceConfig: {\n    zns: {\n      url: 'https://api.zilliqa.com',\n      network: 'mainnet',\n    },\n  },\n});\n```\n\n## Initialize with Custom Provider Configuration\n\nYou may want to specify a custom provider:\n\n- if you want to use a dedicated blockchain node\n- if you want to monitor app usage\n- if you already have a provider in your app to re-use it for domain resolution\n\nDefault provider can be changed by changing constructor options\n`new Resolution(options)` or by using one of the factory methods:\n\n- `Resolution.alchemy()`\n- `Resolution.infura()`\n- `Resolution.fromWeb3Version1Provider()`\n- `Resolution.fromEthersProvider()`\n- etc.\n\n```javascript\nconst {default: Resolution} = require('@unstoppabledomains/resolution');\n\n// obtain a key from https://www.infura.io\nconst resolution = new Resolution({\n  sourceConfig: {\n    uns: {\n      locations: {\n        Layer1: {\n          url: 'https://mainnet.infura.io/v3/\u003cinfura_api_key\u003e',\n          network: 'mainnet',\n        },\n        Layer2: {\n          url: 'https://polygon-mainnet.infura.io/v3/\u003cinfura_api_key\u003e',\n          network: 'polygon-mainnet',\n        },\n      },\n    },\n    zns: {\n      url: 'https://api.zilliqa.com',\n      network: 'mainnet',\n    },\n    ens: {\n      url: 'https://mainnet.infura.io/v3/\u003cinfura_api_key\u003e',\n      network: 'mainnet',\n    },\n  },\n});\n```\n\n## Initialize with Autoconfiguration of blockchain network\n\nIn some scenarios system might not be flexible enough to easy distinguish\nbetween various Ethereum testnets at compilation time. In this case, Resolution\nlibrary provide a special async constructor\n`await Resolution.autonetwork(options)`. This method makes a JSON RPC\n\"net_version\" call to the provider to get the network id.\n\nThis method configures only Uns. Zns is supported only on Zilliqa mainnet which\nis going to be used in any cases. You can provide a configured provider or a\nblockchain url as in the following example:\n\n```\nawait Resolution.autoNetwork({\n  uns: {provider},\n});\n```\n\n### Examples\n\nTo see all constructor options and factory methods check\n[Unstoppable API reference](https://unstoppabledomains.github.io/resolution).\n\n#### Look up a domain's crypto address\n\n```javascript\nfunction resolve(domain, currency) {\n  resolution\n    .addr(domain, currency)\n    .then((address) =\u003e console.log(domain, 'resolves to', address))\n    .catch(console.error);\n}\n\nresolve('brad.crypto', 'ETH');\nresolve('brad.zil', 'ZIL');\nresolve('vitalik.eth', 'ETH');\n```\n\n### Find the IPFS hash for a decentralized website\n\nCreate a new file in your project, `ipfs_hash.js`.\n\n```javascript\nfunction resolveIpfsHash(domain) {\n  resolution\n    .ipfsHash(domain)\n    .then((hash) =\u003e\n      console.log(\n        `You can access this website via a public IPFS gateway: https://gateway.ipfs.io/ipfs/${hash}`,\n      ),\n    )\n    .catch(console.error);\n}\n\nresolveIpfsHash('homecakes.crypto');\nresolveIpfsHash('vitalik.eth');\n```\n\n### Find a custom record\n\nCreate a new file in your project, `custom-resolution.js`.\n\n```javascript\n// Does not support ENS\n\nfunction resolveCustomRecord(domain, record) {\n  resolution\n    .records(domain, [record])\n    .then((value) =\u003e console.log(`Domain ${domain} ${record} is: ${value}`))\n    .catch(console.error);\n}\n\nresolveCustomRecord('homecakes.crypto', 'custom.record.value');\n```\n\n### Resolve wallet address 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\nWith `homecakes.crypto` has `crypto.ETH.address` on-chain:\n\n```javascript\nfunction getWalletAddr(domain, ticker) {\n  resolution\n    .addr(domain, ticker)\n    .then((address) =\u003e\n      console.log(`Domain ${domain} has address for ${ticker}: ${address}`),\n    )\n    .catch(console.error);\n}\ngetWalletAddr('homecakes.crypto', 'ETH');\n// Domain homecakes.crypto has address for ETH: 0xe7474D07fD2FA286e7e0aa23cd107F8379085037\ngetWalletAddr('vitalik.eth', 'ETH');\n// Domain homecakes.crypto has address for ETH: 0xe7474D07fD2FA286e7e0aa23cd107F8379085037\n```\n\n### Resolve multi-chain address format using `multiChainAddr`\n\nThis API is used to retrieve wallet address for multi-chain address records.\n(See\n[multi-chain currency](https://docs.unstoppabledomains.com/resolution/guides/records-reference/#multi-chain-currencies))\n\nWith `aaron.x` has `crypto.AAVE.version.ERC20.address` on-chain:\n\n```javascript\n// Does not support ENS\n\nfunction getMultiChainWalletAddr(domain, ticker, network) {\n  resolution\n    .multiChainAddr(domain, ticker, network)\n    .then((address) =\u003e\n      console.log(\n        `Domain ${domain} has address for ${ticker} on network ${network}: ${address}`,\n      ),\n    )\n    .catch(console.error);\n}\ngetMultiChainWalletAddr('aaron.x', 'AAVE', 'ETH');\n// Domain aaron.x has address for AAVE on network ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n```\n\n### Resolve wallet address using `getAddress`\n\nThis (beta) API can be used to resolve different formats\n\n```javascript\nfunction getWalletAddress(domain, network, token) {\n  resolution\n    .getAddress(domain, network, token)\n    .then((address) =\u003e\n      console.log(\n        `Domain ${domain} has address for ${token} on ${network}: ${address}`,\n      ),\n    )\n    .catch(console.error);\n}\n```\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```javascript\ngetWalletAddress('homecakes.crypto', 'ETH', 'ETH');\n// Domain homecakes.crypto has address for ETH on ETH: 0xe7474D07fD2FA286e7e0aa23cd107F8379085037\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```javascript\ngetWalletAddress('aaron.x', 'ETH', 'AAVE');\n// Domain aaron.x has address for AAVE on ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\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\nwith same wallet 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```javascript\ngetWalletAddress('blockchain-family-keys.x', 'ETH', 'AAVE');\n// Domain blockchain-family-keys.x has address for AAVE on ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\ngetWalletAddress('blockchain-family-keys.x', 'ETH', 'ETH');\n// Domain blockchain-family-keys.x has address for ETH on ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\ngetWalletAddress('blockchain-family-keys.x', 'AVAX', 'USDT');\n// Domain blockchain-family-keys.x has address for USDT on AVAX: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\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```javascript\ngetWalletAddress('uns-devtest-nickshatilo-withdraw-test2.x', 'ETH', 'AAVE');\n// Domain blockchain-family-keys.x has address for AAVE on ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\ngetWalletAddress('uns-devtest-nickshatilo-withdraw-test2.x', 'ETH', 'MATIC');\n// Domain blockchain-family-keys.x has address for ETH on ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\ngetWalletAddress('uns-devtest-nickshatilo-withdraw-test2.x', 'ETH', 'USDT');\n// Domain blockchain-family-keys.x has address for USDT on ETH: 0xCD0DAdAb45bAF9a06ce1279D1342EcC3F44845af\n\ngetWalletAddress('uns-devtest-nickshatilo-withdraw-test2.x', 'MATIC', 'USDT');\n// won't work\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// Not supported with ENS\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## Error Handling\n\nWhen resolution encounters an error it returns the error code instead of\nstopping the process. Keep an eye out for return values like `RECORD_NOT_FOUND`.\n\n## Development\n\nUse these commands to set up a local development environment (**macOS Terminal**\nor **Linux shell**).\n\n1. Recommended NodeJs version\n\n- Node v16\n\n2. Clone the repository\n\n   ```bash\n   git clone https://github.com/unstoppabledomains/resolution.git\n   cd resolution\n   ```\n\n3. Install dependencies\n\n   ```bash\n   yarn install\n   ```\n\n   or\n\n   ```bash\n   npm install\n   ```\n\n### Internal config\n\n#### To update:\n- Network config: `$ yarn network-config:pull`\n- Resolver keys: `$ yarn resolver-keys:pull`\n- Both configs: `$ yarn config:pull`\n\n#### Unit tests:\n\nResolution library relies on environment variables to load **TestNet** RPC Urls.\nThis way, our keys don't expose directly to the code. These environment\nvariables are:\n\n- L1_TEST_NET_RPC_URL\n- L1_TEST_NET_RPC_WSS_URL\n- L2_TEST_NET_RPC_URL\n- L2_TEST_NET_RPC_WSS_URL\n\nIn order to validate the code change, copy `.env.example` file change the name\nto `.env`. Then, update the values of variables.\n\n## Free advertising for integrated apps\n\nOnce your app has a working Unstoppable Domains integration,\n[register it here](https://unstoppabledomains.com/app-submission). Registered\napps appear on the Unstoppable Domains\n[homepage](https://unstoppabledomains.com/) and\n[Applications](https://unstoppabledomains.com/apps) page — putting your app in\nfront of tens of thousands of potential customers per day.\n\nAlso, every week we select a newly-integrated app to feature in the Unstoppable\nUpdate newsletter. This newsletter is delivered straight into the inbox of\n~100,000 crypto fanatics — all of whom could be new customers to grow your\nbusiness.\n\n## Get help\n\n[Join our discord community](https://discord.gg/unstoppabledomains) and ask\nquestions.\n\n## Help us improve\n\nWe're always looking for ways to improve how developers use and integrate our\nproducts into their applications. We'd love to hear about your experience to\nhelp 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","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funstoppabledomains%2Fresolution","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funstoppabledomains%2Fresolution/lists"}