|
1 | 1 | // SPDX-License-Identifier: MIT |
2 | 2 | pragma solidity 0.8.24; |
3 | 3 |
|
4 | | -import "@openzeppelin/contracts/utils/Strings.sol"; |
5 | 4 | import {Base64} from "solady/utils/Base64.sol"; |
6 | 5 | import {LibString} from "solady/utils/LibString.sol"; |
7 | 6 | import "./ERC721EthscriptionsEnumerableUpgradeable.sol"; |
8 | 7 | import "./interfaces/IProtocolHandler.sol"; |
9 | 8 | import "./Ethscriptions.sol"; |
10 | 9 | import "./libraries/Predeploys.sol"; |
| 10 | +import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; |
11 | 11 |
|
12 | 12 | /// @title NameRegistry |
13 | 13 | /// @notice Handles legacy word-domain registrations and mirrors ownership as an ERC-721 collection. |
14 | 14 | contract NameRegistry is ERC721EthscriptionsEnumerableUpgradeable, IProtocolHandler { |
15 | | - using Strings for uint256; |
| 15 | + using LibString for *; |
16 | 16 |
|
17 | 17 | Ethscriptions public constant ethscriptions = Ethscriptions(Predeploys.ETHSCRIPTIONS); |
18 | 18 |
|
19 | | - string public constant PROTOCOL_NAME = "word-domains"; |
| 19 | + string public constant protocolName = "word-domains"; |
20 | 20 |
|
21 | 21 | struct DomainRecord { |
22 | 22 | bytes32 packedName; |
@@ -62,10 +62,6 @@ contract NameRegistry is ERC721EthscriptionsEnumerableUpgradeable, IProtocolHand |
62 | 62 | return "NAME"; |
63 | 63 | } |
64 | 64 |
|
65 | | - function protocolName() external pure returns (string memory) { |
66 | | - return PROTOCOL_NAME; |
67 | | - } |
68 | | - |
69 | 65 | // ============================ |
70 | 66 | // Protocol handler functions |
71 | 67 | // ============================ |
@@ -192,27 +188,90 @@ contract NameRegistry is ERC721EthscriptionsEnumerableUpgradeable, IProtocolHand |
192 | 188 | // Get the ethscription data to extract the ethscription number |
193 | 189 | Ethscriptions.Ethscription memory ethscription = ethscriptions.getEthscription(record.ethscriptionId, false); |
194 | 190 |
|
| 191 | + // Get the media URI from the ethscription |
| 192 | + (string memory mediaType, string memory mediaUri) = ethscriptions.getMediaUri(record.ethscriptionId); |
| 193 | + |
195 | 194 | // Convert ethscriptionId to hex string (0x prefixed) |
196 | 195 | string memory ethscriptionIdHex = uint256(record.ethscriptionId).toHexString(32); |
197 | 196 |
|
198 | 197 | bytes memory json = abi.encodePacked( |
199 | 198 | '{"name":"', |
200 | | - name, |
| 199 | + name.escapeJSON(), |
201 | 200 | '","description":"Dotless word domain"', |
202 | 201 | ',"ethscription_id":"', |
203 | 202 | ethscriptionIdHex, |
204 | 203 | '","ethscription_number":', |
205 | 204 | ethscription.ethscriptionNumber.toString(), |
206 | | - ',"attributes":[', |
| 205 | + ',"', |
| 206 | + mediaType, |
| 207 | + '":"', |
| 208 | + mediaUri, |
| 209 | + '","attributes":[', |
207 | 210 | '{"trait_type":"Name","value":"', |
208 | | - name, |
| 211 | + name.escapeJSON(), |
209 | 212 | '"}', |
210 | 213 | ']}' |
211 | 214 | ); |
212 | 215 |
|
213 | 216 | return string(abi.encodePacked("data:application/json;base64,", Base64.encode(json))); |
214 | 217 | } |
215 | 218 |
|
| 219 | + /// @notice OpenSea collection-level metadata |
| 220 | + /// @return JSON string with collection metadata |
| 221 | + function contractURI() external pure returns (string memory) { |
| 222 | + return string(abi.encodePacked( |
| 223 | + 'data:application/json;base64,', |
| 224 | + Base64.encode(bytes( |
| 225 | + '{"name":"Word Domains Registry",' |
| 226 | + '"description":"On-chain word domain name system for Ethscriptions. Register unique, dotless domain names as NFTs.",' |
| 227 | + '"image":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAwIiBoZWlnaHQ9IjUwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNTAwIiBoZWlnaHQ9IjUwMCIgZmlsbD0iIzEwMTAxMCIvPjx0ZXh0IHg9IjI1MCIgeT0iMjUwIiBmb250LXNpemU9IjgwIiBmb250LWZhbWlseT0ibW9ub3NwYWNlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmaWxsPSIjMDBmZjAwIj5bTkFNRVNdPC90ZXh0Pjwvc3ZnPg==",' |
| 228 | + '"external_link":"https://ethscriptions.com"}' |
| 229 | + )) |
| 230 | + )); |
| 231 | + } |
| 232 | + |
| 233 | + // --- Transfer/approvals blocked externally --------------------------------- |
| 234 | + |
| 235 | + function transferFrom(address, address, uint256) |
| 236 | + public |
| 237 | + pure |
| 238 | + override(ERC721EthscriptionsUpgradeable, IERC721) |
| 239 | + { |
| 240 | + revert TransfersDisabled(); |
| 241 | + } |
| 242 | + |
| 243 | + function safeTransferFrom(address, address, uint256) |
| 244 | + public |
| 245 | + pure |
| 246 | + override(ERC721EthscriptionsUpgradeable, IERC721) |
| 247 | + { |
| 248 | + revert TransfersDisabled(); |
| 249 | + } |
| 250 | + |
| 251 | + function safeTransferFrom(address, address, uint256, bytes memory) |
| 252 | + public |
| 253 | + pure |
| 254 | + override(ERC721EthscriptionsUpgradeable, IERC721) |
| 255 | + { |
| 256 | + revert TransfersDisabled(); |
| 257 | + } |
| 258 | + |
| 259 | + function approve(address, uint256) |
| 260 | + public |
| 261 | + pure |
| 262 | + override(ERC721EthscriptionsUpgradeable, IERC721) |
| 263 | + { |
| 264 | + revert TransfersDisabled(); |
| 265 | + } |
| 266 | + |
| 267 | + function setApprovalForAll(address, bool) |
| 268 | + public |
| 269 | + pure |
| 270 | + override(ERC721EthscriptionsUpgradeable, IERC721) |
| 271 | + { |
| 272 | + revert TransfersDisabled(); |
| 273 | + } |
| 274 | + |
216 | 275 | function _update(address to, uint256 tokenId, address auth) internal override returns (address) { |
217 | 276 | if (auth != address(0) && auth != address(this)) { |
218 | 277 | revert TransfersDisabled(); |
|
0 commit comments