{"name":"nft-did-resolver","version":"0.2.0-alpha.2","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","types":"lib/index.d.ts","directories":{"lib":"lib"},"scripts":{"test":"jest --coverage","build":"tsc -p tsconfig.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-beta.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.13.0","jest-fetch-mock":"^3.0.3","lru_map":"^0.4.1","prettier":"^2.3.2","typescript":"^4.3.5"},"jest":{"automock":false,"setupFiles":["./jest.setup.ts"],"testMatch":["**/?(*.)+(spec|test).[jt]s?(x)"]},"prettier":"eslint-config-3box/prettier.config","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 NftResolver, { 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 = 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: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":"d7dcf7ff91ec2b7dce66cf1a8b2df640bbb97980","bugs":{"url":"https://github.com/ceramicnetwork/nft-did-resolver/issues"},"_id":"nft-did-resolver@0.2.0-alpha.2","_nodeVersion":"16.3.0","_npmVersion":"7.15.1","dist":{"integrity":"sha512-7fd+RYG4NpBAJE2IrStcM1YhfYtx1q7R85UHpdn0n9iRkUbFBaXEViVFVW8pK7PcKOSW55WyTlJVfaGZy8K1lw==","shasum":"144040318411aa04946b02c1654906f83849a812","tarball":"https://registry.npmjs.org/nft-did-resolver/-/nft-did-resolver-0.2.0-alpha.2.tgz","fileCount":14,"unpackedSize":47979,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhE8Q0CRA9TVsSAnZWagAAHwMP/2+yBJCYGNk8Jucq0+XJ\n1lxRjWEHJvBjUZQP0X3DOA7Zxu43lDpqP7qa0zaOxJIdZtmsoGQepYyRxd8a\nSbPXo8Hyj0QCqFCcTAlM/zG8F1nHTgTKex4yFxngQ9d4X/SY2pzp0akqe0Yl\nDWpIqrzQLkaQG/VYQ1Dke8ZEUX/uy11jMNFtmH94l8zLgeop68Vlijal1PlF\nh/68AtQx6zzENqeH6pnm7iDJYiTXVj1q6VTle5NJTYjSLv7Vr+vD7110bpIz\nnkBFzHBeoM9BIdviJD/fzuuf/Q1vtHjwEM3quHF+u4eJunCMN85I96qs24dw\ngEWYlYFU6dc7NozTNp3IcrgHszn+hDZSRkyc1JuDODwCUPKK/o5HTuAUVmxi\naTFQl8ii5MLPqH8HGK/eLebnuU6Z1x29c0j9lIoKWS0yS+ilQTjWU+pQRl8M\n2dTqAXjXGpEkPaqF/RK907W7tsTRNixkOY61A3JnL5cWr5qiLFxhhYVIf7ZS\nfsnIqXIHQOj9axdYfbKGxImqiFtXGyyhRyhKOp28r27q5qbkXA9d7kkJwUX+\naIFuCXvHdEKrIo79Xai+ptr1qocohE/8OofJtay5aYePTwTO+OPN2n+CBwkF\nVyfVwBTe4lR4MeV0R9MS2kgkAjvW4Bt+tXWaj47EcCwaPFgVLu1BQ6tJFoMz\nhmZH\r\n=MAWi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+6eOhgsOEZqhGB7pHSBFv0NKdqzrNYD1ehkHG9NM7xgIgVBFFpi+DL0UlfDQ6swh0GeNEyYpDE5zQ+rv3HypIi4U="}]},"_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_0.2.0-alpha.2_1628685364155_0.4403315327183255"},"_hasShrinkwrap":false}