{"id":21019441,"url":"https://github.com/ceramicnetwork/nft-did-resolver","last_synced_at":"2025-10-06T10:32:35.262Z","repository":{"id":38676278,"uuid":"350071642","full_name":"ceramicnetwork/nft-did-resolver","owner":"ceramicnetwork","description":null,"archived":false,"fork":false,"pushed_at":"2023-03-06T19:20:12.000Z","size":2273,"stargazers_count":33,"open_issues_count":5,"forks_count":12,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-01-22T08:43:46.245Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ceramicnetwork.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","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-03-21T17:35:38.000Z","updated_at":"2023-02-25T08:14:12.000Z","dependencies_parsed_at":"2024-06-18T16:43:16.409Z","dependency_job_id":"2ed15819-44f9-4c17-9991-ca1c4f50943e","html_url":"https://github.com/ceramicnetwork/nft-did-resolver","commit_stats":{"total_commits":37,"total_committers":10,"mean_commits":3.7,"dds":0.4864864864864865,"last_synced_commit":"900358617606392f09968eb73f1c34f1cbec39f4"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ceramicnetwork%2Fnft-did-resolver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ceramicnetwork%2Fnft-did-resolver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ceramicnetwork%2Fnft-did-resolver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ceramicnetwork%2Fnft-did-resolver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ceramicnetwork","download_url":"https://codeload.github.com/ceramicnetwork/nft-did-resolver/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235465065,"owners_count":18994549,"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":[],"created_at":"2024-11-19T10:32:10.764Z","updated_at":"2025-10-06T10:32:29.934Z","avatar_url":"https://github.com/ceramicnetwork.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NFT DID Resolver\n\n\u003e NFT is a DID method that uses the Ceramic network to resolve DID documents for NFTs\n\n\u003e See [CIP-94](https://github.com/ceramicnetwork/CIP/blob/main/CIPs/CIP-94/CIP-94.md)\n\n## Getting started\n\nThis implementation is still a prototype. Contributions are welcome!\n\nTo use a package, you would need to provide three subgraph endpoints for every network you are going to use:\none for blocks, one for ERC721 tokens, another for ERC1155 tokens. You would also need to provide a `skew` that\nis a time (in milliseconds) within which a latest block is considered valid. Usually it is a typical block time.\n\n### Installation\n\n```\n$ npm install nft-did-resolver\n```\n\n### Usage\n\n```typescript\nimport { getResolver } from 'nft-did-resolver'\nimport type { NftResolverConfig } from 'nft-did-resolver'\nimport { Resolver } from 'did-resolver'\nimport Ceramic from '@ceramicnetwork/http-client'\n\nconst ceramic = new Ceramic() // connects to localhost:7007 by default\n\nconst config: NftResolverConfig = {\n  ceramic,\n  chains: {\n    'eip155:1': {\n      blocks: 'https://api.thegraph.com/subgraphs/name/yyong1010/ethereumblocks',\n      skew: 15000,\n      assets: {\n        erc721: 'https://api.thegraph.com/subgraphs/name/sunguru98/mainnet-erc721-subgraph',\n        erc1155: 'https://api.thegraph.com/subgraphs/name/sunguru98/mainnet-erc1155-subgraph',\n      },\n    },\n    'eip155:4': {\n      blocks: 'https://api.thegraph.com/subgraphs/name/mul53/rinkeby-blocks',\n      skew: 15000,\n      assets: {\n        erc721: 'https://api.thegraph.com/subgraphs/name/sunguru98/erc721-rinkeby-subgraph',\n        erc1155: 'https://api.thegraph.com/subgraphs/name/sunguru98/erc1155-rinkeby-subgraph',\n      },\n    },\n  },\n}\n\n// getResolver will return an object with a key/value pair of { 'nft': resolver }\n// where resolver is a function used by the generic did resolver.\nconst nftResolver = getResolver(config)\nconst didResolver = Resolver(nftResolver)\n\nconst erc721result = await didResolver.resolve(\n  'did:nft:eip155:1_erc721:0xb300a43751601bd54ffee7de35929537b28e1488_2'\n)\nconst erc1155result = await didResolver.resolve(\n  'did:nft:eip155:1_erc1155:0x06eb48572a2ef9a3b230d69ca731330793b65bdc_1'\n)\nconsole.log(erc721result, erc1155result)\n```\n\n`chains` field in config has [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md) chain identifiers as keys.\nEach such `chain` is expected to contain endpoints to ERC721 and/or ERC1155 subgraphs under `assets` field.\nBoth ERC721 and ERC1155 are supported. Feel free to specify either one or both.\n\nThe resolver supports the following networks by default:\n\n- Ethereum mainnet (`eip155:1`),\n- Ethereum Rinkeby (`eip155:4`),\n- Polygon (formerly Matic) (`eip155:137`).\n\nIf you use one of those, you do not have to provide `chains` field.\n\n## Testing\n\n```\n$ npm test\n```\n\n## Custom Subgraphs\n\nYou may specify custom subgraph URLs in the configuration object as shown above in [usage](#usage).\n\n**Note**: custom subgraphs must conform to the below schemas at a _minimum_ for assets to be resolved properly.\n\n**Note**: At the moment, only ERC721 and ERC1155 asset namespaces are supported. However, CAIP2 chains beside ETH,\nfor instance xDAI, with support for those namespaces _are_ supported, as long as the subgraph schema is the same.\n\n### ERC721:\n\n```gql\ntype Token @entity {\n  id: ID!\n  contract: TokenContract!\n  owner: Owner!\n  ...\n}\n\ntype TokenContract @entity {\n  id: ID!\n  tokens: [Token!]! @derivedFrom(field: \"contract\")\n  ...\n}\n\ntype Owner @entity {\n  id: ID!\n  tokens: [Token!]! @derivedFrom(field: \"owner\")\n  ...\n}\n\n```\n\n### ERC1155:\n\n```gql\ntype Account @entity {\n  id: ID!\n  balances: [Balance!]! @derivedFrom(field: \"account\")\n  ...\n}\n\ntype TokenRegistry @entity {\n  id: ID!\n  tokens: [Token!]! @derivedFrom(field: \"registry\")\n  ...\n}\n\ntype Token @entity {\n  id: ID!\n  registry: TokenRegistry!\n  identifier: BigInt!\n  balances: [Balance!]! @derivedFrom(field: \"token\")\n  ...\n}\n\ntype Balance @entity {\n  id: ID!\n  token: Token!\n  account: Account!\n  ...\n}\n\n```\n\nFor more information on writing schemas for GraphProtocol, check out [their documentation](https://thegraph.com/docs/define-a-subgraph#defining-entities).\n\n## DID Specs\n\nThe token DIDs are prefixed with `did:nft:`, and the latter half is a modified CAIP format.\n\n**ERC721** ([CAIP-22](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/CAIP-22.md))\n\nDID: `did:nft:{chainNamespace}:{chainReference}_erc721:{contractAddress}_{tokenId}`\n\nCAIP-22: `{chainNamespace}:{chainReference}/erc721:{contractAddress}/{tokenId}`\n\n**ERC1155** ([CAIP-29](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/CAIP-29.md))\n\nDID: `did:nft:{chainNamespace}:{chainReference}_erc1155:{contractAddress}_{tokenId}`\n\nCAIP-29: `{chainNamespace}:{chainReference}/erc1155:{contractAddress}/{tokenId}`\n\n### Conversions\n\n**DID-\u003eCAIP**\n\n```\nconst caip = did.substr(8).replace(/_/g, '/')\n```\n\n**CAIP-\u003eDID**\n\n```\nconst did = `did:nft:${caip.replace(/\\//g, '_')\n```\n\nThere are helpers that help you with the conversion:\n\n```typescript\nimport { caipToDid, didToCaip, createNftDidUrl } from 'nft-did-resolver'\nimport { AssetId } from 'caip'\n\n// CAIP -\u003e DID URL\nconst didUrl = createNftDidUrl({\n  chainId: 'eip155:1',\n  namespace: 'erc721',\n  contract: '0x1234567891234567891234567891234596351156'\n  tokenId: '1',\n})\n// If you use `caip` library in your app, consider using sister `caipToDid` function to convert `AssetId` to NFT DID URL.\n\n// DID URL -\u003e CAIP\nconst assetId1 = didToCaip(didUrl) // eip155:1/erc721:0x1234567891234567891234567891234596351156/1\nconst assetId2 = didToCaip(didUrlWithTimestamp) // eip155:1/erc721:0x1234567891234567891234567891234596351156/1\n```\n\n## Contributing\n\nWe are happy to accept small and large contributions. Make sure to check out the [Ceramic specifications](https://github.com/ceramicnetwork/specs) for details of how the protocol works.\n\n## License\n\nApache-2.0 OR MIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fceramicnetwork%2Fnft-did-resolver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fceramicnetwork%2Fnft-did-resolver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fceramicnetwork%2Fnft-did-resolver/lists"}