{"name":"nft-did-resolver","version":"2.0.0-alpha.0","description":"DID Resolver for the NFT method","keywords":["Ceramic","DID","identity","Data"],"author":{"name":"Joel Torstensson","email":"oed3933@gmail.com"},"contributors":[{"name":"Mike Roth","email":"mike@manyuses.com"}],"homepage":"https://github.com/ceramicnetwork/nft-did-resolver","repository":{"type":"git","url":"git://github.com/ceramicnetwork/nft-did-resolver.git"},"license":"(Apache-2.0 OR MIT)","main":"./lib/index.js","type":"module","exports":{".":"./lib/index.js"},"types":"./lib/index.d.ts","directories":{"lib":"./lib"},"sideEffects":false,"scripts":{"test":"jest --coverage","build":"tsc --project tsconfig.build.json","prepublishOnly":"npm run build","prebuild":"npm run clean","lint":"eslint ./src --ext .js,.jsx,.ts,.tsx","clean":"rm -rf ./lib"},"dependencies":{"@ceramicnetwork/common":"^1.1.0","@ceramicnetwork/stream-caip10-link":"^1.0.7","bignumber.js":"^9.0.1","caip":"^1.0.0","cross-fetch":"^3.1.4","json-to-graphql-query":"^2.1.0","merge-options":"^3.0.4","tslib":"^2.3.0","uint8arrays":"^2.1.8"},"devDependencies":{"@babel/core":"^7.14.8","@babel/preset-env":"^7.14.8","@babel/preset-typescript":"^7.14.5","@ceramicnetwork/blockchain-utils-linking":"^1.0.2","@types/jest":"^26.0.24","@types/node":"^16.4.8","@typescript-eslint/eslint-plugin":"^4.28.5","@typescript-eslint/parser":"^4.28.5","babel-jest":"^27.0.6","did-resolver":"^3.0.1","eslint":"^7.32.0","eslint-config-3box":"^0.2.0","eslint-plugin-jest":"^24.4.0","ethers":"^5.4.3","ganache-core":"^2.13.2","jest":"^27.0.6","jest-environment-ceramic":"^0.14.0","jest-fetch-mock":"^3.0.3","jest-resolver-enhanced":"^1.0.1","prettier":"^2.3.2","typescript":"^4.3.5"},"readme":"# NFT DID Resolver\n\n> NFT is a DID method that uses the Ceramic network to resolve DID documents for NFTs\n\n> 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->CAIP**\n\n```\nconst caip = did.substr(8).replace(/_/g, '/')\n```\n\n**CAIP->DID**\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 -> 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 -> 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","readmeFilename":"README.md","gitHead":"afe61528bb88e181d20491ecfa1ffb401348fc40","bugs":{"url":"https://github.com/ceramicnetwork/nft-did-resolver/issues"},"_id":"nft-did-resolver@2.0.0-alpha.0","_nodeVersion":"16.3.0","_npmVersion":"7.15.1","dist":{"integrity":"sha512-7aeMVRIwhM6vanCLQynIBILV0mRgeU4Lub3eIDbBcx2V7t6ILnKcYB6s7k5V0ZHDnAeM91wdtYwaBIffycLdgQ==","shasum":"842e4785e29460d4a9c31d011cd284a09ab67a95","tarball":"https://registry.npmjs.org/nft-did-resolver/-/nft-did-resolver-2.0.0-alpha.0.tgz","fileCount":14,"unpackedSize":46144,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhphrvCRA9TVsSAnZWagAABYEP+wdz2KStr2t5SvDuviAB\n88SjkrOCeUAs3GEBi3maaIb4QO6adzDJomPzqfQli1fobHFloJGUqNReQhAd\nN8ZddzHWvDNS0J/h0Ym9+wGIyPKBmv0w7S6PRgLpUj77tf2lw7qfBFPj7paO\niMoqfWvMOISL0CskiPpAIT9AzF6mwAuvJerSQo1/c0TNWjBRv3qevOgqv1gp\nBQVsnd+KoMNqgO9+FOBJJ2v6cvxuFVv8uLpqfXEV69dgBIoo9iqqReMGiAcn\nsxxvK6N1bpyBbGi9ROdh/jWo9HNqKwpbyynKkJnOBcNLT+U4c6s8RJjtLWtM\nMGjiN0nfXs/KMVbBS1HTq7YdOJx797KXuJ0FDVnrlyG1URaIGCYgmXeVeiUA\nHeJcR6DLNP0GCjhzpdECs1F64KBsZkPCBYnMdfgAEeF0Fs7+Hkwoo0/Qj3lY\n4HYoBxbWFHfxGkUB1NV0aF4YrBsH2rUH+TE5G+pULABpanCp/5pK5JVRW+D/\n4OQX/8WaVL1a+QJ3jxJv/p5spkiUAspsMXPFahRQUEi4Pz6XPPu11i17Lu5E\njuVaNfZUBBcvZ4QTYNAzMDHGteG4i2swtoXDzdk8eICWYkWESPuyGe0ZhTtX\nN+yFeItoD9m3U6ty+6Tu46DpQLPZaEKdBfc+qcOwIqbUqES63mtpIJB7VmLr\nFAGh\r\n=qTpt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG4xiIcmZCBuB1QKUo2WN4swSS3FZ/GjZ2MOFTTtADLbAiBsbGaPT4UvHjs2zjXOSXmnpnBLaASGMQitfAxyH4P5jg=="}]},"_npmUser":{"name":"ukstv","email":"sergey@ukstv.me"},"maintainers":[{"name":"ukstv","email":"sergey@ukstv.me"},{"name":"oed","email":"oed@3box.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nft-did-resolver_2.0.0-alpha.0_1638275823520_0.15753654057354516"},"_hasShrinkwrap":false}