{"_id":"name-wrapper","_rev":"1-a5d7e7525a3e8b39292f51f4ccc11b56","name":"name-wrapper","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"name-wrapper","version":"1.0.0","main":"index.js","license":"MIT","devDependencies":{"@nomiclabs/hardhat-etherscan":"^2.1.3","@openzeppelin/test-helpers":"^0.5.11","chai":"^4.2.0","dns-packet":"^5.2.4","envfile":"^6.14.0","eslint":"^7.5.0","eslint-config-prettier":"^6.11.0","eslint-plugin-babel":"^5.3.1","eslint-plugin-prettier":"^3.1.4","hardhat-gas-reporter":"^1.0.4"},"dependencies":{"@ensdomains/ens-contracts":"0.0.3","@nomiclabs/hardhat-ethers":"^2.0.0","@nomiclabs/hardhat-waffle":"^2.0.0","@openzeppelin/contracts":"^4.0.0","chalk":"^4.1.0","ethereum-waffle":"^3.1.1","ethers":"^5.0.17","hardhat":"^2.0.4","node-watch":"^0.7.0","qrcode-terminal":"^0.12.0","ramda":"^0.27.1","solium":"^1.2.5"},"scripts":{"chain":"hardhat node","test":"hardhat test","test:local":"hardhat --network localhost test","compile":"hardhat compile","lint":"eslint test/*.js; solium --dir ./contracts","deploy":"npx hardhat run --network localhost scripts/deploy.js","seed":"npx hardhat run --network localhost scripts/seed.js"},"description":"The ENS Name Wrapper is a smart contract that wraps existing ENS names, providing several new features:","_id":"name-wrapper@1.0.0","dist":{"shasum":"6e064a29b9c7806e18032fdbf620a01de48cdfbb","integrity":"sha512-7wTdz1ees+Q3GXFu/Mp76owXzWqYp+k2bB/W0yRnfFtnzU5Y8ga6VKbgl+UWYuCfndy0ylRSQpHPom/mEsDVqg==","tarball":"https://registry.npmjs.org/name-wrapper/-/name-wrapper-1.0.0.tgz","fileCount":32,"unpackedSize":2078700,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0K+DCRA9TVsSAnZWagAAptMP/2UatKbuUC4RVqdj7a1/\np462PoJcaAQQwlBbOqx0US2N5jDtLHF5wxV552sG8PLeEUoGDyeNHvaNiB5Z\nlndlny5lcqLxommDKmEnTqeEPv3zYqRKmRZWE2Lo3/qlK9d81Mz/qhwwXUgR\nE12A37HlM7otLdWHsimBOKznrRQWhZbwlAMiSVv/Bd3r3HmtMCTFqm51FeEw\nqeP/naUbZUucJkugkjyxLNpIGoqGhKT0Qq1iov4iiHKwHodIBPiWHrj69W8v\nzFJCKEihxl27cfw1J/1WAcjMiW8sUqV8wZhpopBg5TJjiBQXaAEKS6pfdvHF\nB0RGh3wpr6rAD9FV+243MkWq3+0yTtH7OOe7B7ydHcpWk1eBHLR4rzap5qi5\nKt7/wdu8IckKiKffe5inPObkzBH/XrTt/dq9r4wTSJIOHdFRFU6br1ytloKC\n+Q4LxEkCLnjT3Vu/Er8bEhikO8rN0ylbl0fMDnXkO5QHjd9KVRSAqA80HJ3V\nocgg/IH2huHHLzuiBfa3sMTLzytMzCQGpvGiLlSVoaj4yOI0aK/9Cd3egOOD\nVcQmeH4GZsN7CKERprYpeiqZQyoxetO4PhMC7FEOABpSoG9RtjmgQRE2vzXP\noLUecxubvyPsRkyQKKbl1mMtwKV4banqqq11mxDiikopn/DoQOeZLKyVpXJw\nDi2j\r\n=zKKt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHN9RVZZZykgIamWjKm+4soVMGG5ofQCD1F5ivNHhX4wAiEAyZetW4fxS5ecBhvcxiZ6hLFJgi9vBMVPZSXdDan0iDs="}]},"_npmUser":{"name":"makoto_inoue","email":"inouemak@googlemail.com"},"directories":{},"maintainers":[{"name":"makoto_inoue","email":"inouemak@googlemail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/name-wrapper_1.0.0_1624289152289_0.17230216703164025"},"_hasShrinkwrap":false}},"time":{"created":"2021-06-21T15:25:52.227Z","1.0.0":"2021-06-21T15:25:52.464Z","modified":"2022-05-10T08:39:28.706Z"},"maintainers":[{"name":"makoto_inoue","email":"inouemak@googlemail.com"}],"description":"The ENS Name Wrapper is a smart contract that wraps existing ENS names, providing several new features:","license":"MIT","readme":"# ENS Name Wrapper\n\nThe ENS Name Wrapper is a smart contract that wraps existing ENS names, providing several new features:\n\n- Wrapped names are ERC1155 tokens\n- Better permission control over wrapped names\n- Consistent API for names at any level of the hierarchy\n\nIn addition to implementing ERC1155, wrapped names have an ERC721-compatible `ownerOf` function to return the owner of a wrapped name.\n\nMaking ENS names ERC1155 compatible allows them to be displayed, transferred and traded in any wallet that supports the standard.\n\n`NameWrapper` implements the optional ERC1155 metadata extension; presently this is via an HTTPS URL to a service ENS operates, but this can be changed in future as better options become available.\n\nWith the exception of the functionality to upgrade the metadata generation for tokens, there is no upgrade mechanism or centralised control over wrapped names.\n\n## Wrapping a name\n\n`.eth` 2LDs (second-level domains) such as `example.eth` can be wrapped by calling `wrapETH2LD(label, wrappedOwner, fuses)`. `label` is the first part of the domain name (eg, `'example'` for `example.eth`), `wrappedOwner` is the desired owner for the wrapped name, and `fuses` is a bitfield representing permissions over the name that should be irrevoacably burned (see 'Fuses' below). A `fuses` value of `0` represents no restrictions on the name.\n\nIn order to wrap a `.eth` 2LD, the owner of the name must have authorised the wrapper by calling `setApprovalForAll` on the registrar, and the caller of `wrapETH2LD` must be either the owner, or authorised by the owner on either the wrapper or the registrar.\n\nAll other domains (non `.eth` names as well as `.eth` subdomains such as `sub.example.eth` can be wrapped by calling `wrap(parentNode, label, wrappedOwner, fuses)`. `parentNode` is the namehash of the name one level higher than the name to be wrapped, `label` is the first part of the name, `wrappedOwner` is the address that should own the wrapped name, and `fuses` is a bitfield representing permissions over the name that should be irrevocably burned (see 'Fuses' below). A `fuses` value of `0` represents no restrictions on the name. For example, to wrap `sub.example.eth`, you should call `wrap(namehash('example.eth'), 'example', owner, fuses)`.\n\nIn order to wrap a domain that is not a `.eth` 2LD, the owner of the name must have authorised the wrapper by calling `setApprovalForAll` on the registry, and the caller of `wrap` must be either the owner, or authorised by the owner on either the wrapper or the registry.\n\n## Wrapping a name by sending the `.eth` token\n\nAn alternative way to wrap `.eth` names is to send the name to the NameWrapper contract, this bypasses the need to `setApprovalForAll` on the registrar and is preferable when only wrapping one name.\n\nTo wrap a name by sending to the contract, you must use `safeTransferFrom(address,address,uint256,bytes)` with the extra data (the last parameter) ABI formatted as `[string label, address owner, uint96 fuses]`.\n\nExample:\n\n```js\n// Using ethers.js v5\nabiCoder.encode(\n  ['string', 'address', 'uint96'],\n  ['vitalik', '0x...', '0x000000000000000000000001']\n)\n```\n\n## Unwrapping a name\n\nWrapped names can be unwrapped by calling either `unwrapETH2LD(label, newRegistrant, newController)` or `unwrap(parentNode, label, newController)` as appropriate. `label` and `parentNode` have meanings as described under \"Wrapping a name\", while `newRegistrant` is the address that should own the .eth registrar token, and `newController` is the address that should be set as the owner of the ENS registry record.\n\n## Working with wrapped names\n\nThe wrapper exposes all the registry functionality via its own methods - `setSubnodeOwner`, `setSubnodeRecord`, `setRecord`, `setResolver` and `setTTL` are all implemented with the same functionality as the registry, and pass through to it after doing authorisation checks. Transfers are handled via ERC1155's transfer methods rather than mirroring the registry's `setOwner` method.\n\nIn addition, `setSubnodeOwnerAndWrap` and `setSubnodeRecordAndWrap` methods are provided, which create or replace subdomains while automatically wrapping the resulting subdomain.\n\nAll functions for working with wrapped names utilise ERC1155's authorisation mechanism, meaning an account that is authorised to act on behalf of another account can manage all its names.\n\n## Fuses\n\n`NameWrapper` also implements a permissions mechanism called 'fuses'. Each name has a set of fuses representing permissions over that name. Fuses can be 'burned' either at the time the name is wrapped or at any subsequent time when the owner or authorised operator calls `burnFuses`. Once a fuse is burned, it cannot be 'unburned' - the permission that fuse represents is permanently revoked.\n\nBefore any fuses can be burned on a name, the parent name's \"replace subdomain\" fuse must first be burned. Without this restriction, any permissions revoked via fuses can be evaded by the parent name replacing the subdomain and then re-wrapping it with a more permissive fuse field. Likewise, when any fuses on a name are burned, the \"unwrap\" fuse must also be burned, to prevent the name being directly unwrapped and re-wrapped to reset the fuses. These restrictions have the effect of allowing applications to simply check the fuse value they care about on the name they are examining without having to be aware of the entire chain of custody up to the root.\n\nThe ENS root and the .eth 2LD are treated as having the \"replace subdomain\" and \"unwrap\" fuses burned. There is one edge-case here insofar as a .eth name's registration can expire; at that point the name can be purchased by a new registrant and effectively becomes unwrapped despite any fuse restrictions. When that name is re-wrapped, fuse fields can be set to a more permissive value than the name previously had. Any application relying on fuse values for .eth subdomains should check the expiration date of the .eth name and warn users if this is likely to expire soon.\n\nThe fuses field is 96 bits, and only 7 fuses are defined by the `NameWrapper` contract itself. Applications may use additional fuse bits to encode their own restrictions on applications. Any application wishing to do so should submit a PR to this README in order to record the use of the value and ensure there is no unintentional overlap.\n\nEach fuse is represented by a single bit. If that bit is cleared (0) the restriction is not applied, and if it is set (1) the restriction is applied. Any updates to the fuse field for a name are treated as a logical-OR; as a result bits can only be set, never cleared.\n\n### CANNOT_UNWRAP = 1\n\nIf this fuse is burned, the name cannot be unwrapped, and calls to `unwrap` and `unwrapETH2LD` will fail.\n\n### CANNOT_BURN_FUSES = 2\n\nIf this fuse is burned, no further fuses can be burned. This has the effect of 'locking open' some set of permissions on the name. Calls to `burnFuses` will fail.\n\n### CANNOT_TRANSFER = 4\n\nIf this fuse is burned, the name cannot be transferred. Calls to `safeTransferFrom` and `safeBatchTransferFrom` will fail.\n\n### CANNOT_SET_RESOLVER = 8\n\nIf this fuse is burned, the resolver cannot be changed. Calls to `setResolver` and `setRecord` will fail.\n\n### CANNOT_SET_TTL = 16\n\nIf this fuse is burned, the TTL cannot be changed. Calls to `setTTL` and `setRecord` will fail.\n\n### CANNOT_CREATE_SUBDOMAIN = 32\n\nIf this fuse is burned, new subdomains cannot be created. Calls to `setSubnodeOwner`, `setSubnodeRecord`, `setSubnodeOwnerAndWrap` and `setSubnodeRecordAndWrap` will fail if they reference a name that does not already exist.\n\n### CANNOT_REPLACE_SUBDOMAIN = 64\n\nIf this fuse is burned, existing subdomains cannot be replaced by the parent name. Calls to `setSubnodeOwner`, `setSubnodeRecord`, `setSubnodeOwnerAndWrap` and `setSubnodeRecordAndWrap` will fail if they reference a name that already exists.\n\n### Checking Fuses using `allFusesBurned(node, uint96)`\n\nTo check whether or not a fuse is burnt you can use this function that takes a fuse mask of all fuses you want to check.\n\n```js\nconst areBurned = await allFusesBurned(\n  namehash('vitalik.eth'),\n  CANNOT_TRANSFER | CANNOT_SET_RESOLVER\n)\n// if CANNOT_UNWRAP AND CANNOT_SET_RESOLVER are *both* burned this will return true\n```\n\n### Get current fuses and parent safety using `getFuses(node)`\n\nGet fuses gets the raw fuses for a current node and also checks the parent hierarchy for you. The raw fuses it returns will be a `uint96` and you will have to decode this yourself. If you just need to check a fuse has been burned, you can call `allFusesBurned` as it will use less gas.\n\nThe parent hierarchy check will start from the root and check 4 things:\n\n1. Is the registrant of the name the wrapper?\n2. Is the controller of the name the wrapper?\n3. Are the fuses burnt for replacing a subdomain?\n4. Is the name expired?\n\nThis is represented by `enum NameSafety {Safe, Registrant, Controller, Fuses, Expired}`\n\nLastly it will return to you the first node up the hierarchy that is vulnerable. After it finds a vulnerable node, it will break from checking and so it needs to be rechecked for children down the hierarchy once the vulnerable node has been made safe.\n\n## Installation and setup\n\n```bash\nnpm install\n```\n\n## Testing\n\n```bash\nnpm run test\n```\n\nAny contract with `2` at the end, is referring to the contract being called by `account2`, rather than `account1`. This is for tests that require authorising another user.\n","readmeFilename":"README.md"}