diff --git a/packages/contracts/.gitignore b/packages/contracts/.gitignore index 9f0543b..de153db 100644 --- a/packages/contracts/.gitignore +++ b/packages/contracts/.gitignore @@ -1,2 +1 @@ -deployments artifacts diff --git a/packages/contracts/deployments/sepolia/.chainId b/packages/contracts/deployments/sepolia/.chainId new file mode 100644 index 0000000..bd8d1cd --- /dev/null +++ b/packages/contracts/deployments/sepolia/.chainId @@ -0,0 +1 @@ +11155111 \ No newline at end of file diff --git a/packages/contracts/deployments/sepolia/OffchainResolver.json b/packages/contracts/deployments/sepolia/OffchainResolver.json new file mode 100644 index 0000000..a3985ea --- /dev/null +++ b/packages/contracts/deployments/sepolia/OffchainResolver.json @@ -0,0 +1,310 @@ +{ + "address": "0x4da9714c940fddcdcb7a0ec8eacabcb4f32d8f5a", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_url", + "type": "string" + }, + { + "internalType": "address[]", + "name": "_signers", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "string[]", + "name": "urls", + "type": "string[]" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes4", + "name": "callbackFunction", + "type": "bytes4" + }, + { + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "OffchainLookup", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address[]", + "name": "signers", + "type": "address[]" + } + ], + "name": "NewSigners", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint64", + "name": "expires", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "request", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "name": "makeSignatureHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "name", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "resolve", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "response", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "name": "resolveWithProof", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "signers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "url", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xefdaea73b539cb8c58ad50cbd9af9bcab63630a89d845422e62da8d1d0723756", + "receipt": { + "to": null, + "from": "0x4fe4e666be5752f1fdd210f4ab5de2cc26e3e0e8", + "contractAddress": "0x4da9714c940fddcdcb7a0ec8eacabcb4f32d8f5a", + "transactionIndex": "0x1b", + "gasUsed": "0x18ca5f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000200000000000000000000000", + "blockHash": "0xc1ca7b2221a8786fe6cf9dbacb734833e8893520090fb9e0e65da86239ae37c6", + "transactionHash": "0x82ffaa3a6cd309b591ca780e2a3a9a7ed1612fdcc04a7e3764397e29e1be3c2f", + "logs": [ + { + "address": "0x4da9714c940fddcdcb7a0ec8eacabcb4f32d8f5a", + "blockHash": "0xc1ca7b2221a8786fe6cf9dbacb734833e8893520090fb9e0e65da86239ae37c6", + "blockNumber": "0x4c7c83", + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "logIndex": "0x34", + "removed": false, + "topics": [ + "0xab0b9cc3a46b568cb08d985497cde8ab7e18892d01f58db7dc7f0d2af859b2d7" + ], + "transactionHash": "0x82ffaa3a6cd309b591ca780e2a3a9a7ed1612fdcc04a7e3764397e29e1be3c2f", + "transactionIndex": "0x1b" + } + ], + "blockNumber": "0x4c7c83", + "cumulativeGasUsed": "0x59dc90", + "status": "0x1" + }, + "args": [ + "https://offchain-resolver-example.uc.r.appspot.com/{sender}/{data}.json", + [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + ] + ], + "numDeployments": 1, + "solcInputHash": "5301ec7b3143dfe50c3160773a82693f", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_url\",\"type\":\"string\"},{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"NewSigners\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"expires\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"request\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"result\",\"type\":\"bytes\"}],\"name\":\"makeSignatureHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveWithProof\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"signers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"url\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"resolve(bytes,bytes)\":{\"params\":{\"data\":\"The ABI encoded data for the underlying resolution function (Eg, addr(bytes32), text(bytes32,string), etc).\",\"name\":\"The DNS-encoded name to resolve.\"},\"returns\":{\"_0\":\"The return data, ABI encoded identically to the underlying function.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"resolve(bytes,bytes)\":{\"notice\":\"Resolves a name, as specified by ENSIP 10.\"},\"resolveWithProof(bytes,bytes)\":{\"notice\":\"Callback used by CCIP read compatible clients to verify and parse the response.\"}},\"notice\":\"Implements an ENS resolver that directs all queries to a CCIP read gateway. Callers must implement EIP 3668 and ENSIP 10.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/OffchainResolver.sol\":\"OffchainResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@ensdomains/ens-contracts/contracts/resolvers/ISupportsInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface ISupportsInterface {\\n function supportsInterface(bytes4 interfaceID) external pure returns(bool);\\n}\",\"keccak256\":\"0x4960422af4a3d38a2c440c656104465cba7dea0231cb7ae4a489a85dd65f645f\",\"license\":\"MIT\"},\"@ensdomains/ens-contracts/contracts/resolvers/SupportsInterface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport \\\"./ISupportsInterface.sol\\\";\\n\\nabstract contract SupportsInterface is ISupportsInterface {\\n function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {\\n return interfaceID == type(ISupportsInterface).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xcd27206ee8f8bd520d5441294f6438dde98f6933eb8801ee59a0155b8a8cde1b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x84ac2d2f343df1e683da7a12bbcf70db542a7a7a0cea90a5d70fcb5e5d035481\",\"license\":\"MIT\"},\"contracts/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(bytes memory name, bytes memory data) external view returns(bytes memory);\\n}\\n\",\"keccak256\":\"0x9d484d07c45702fd30d65d106e1fd00c68a9073730abfdf903eeb21af9c1b49b\",\"license\":\"MIT\"},\"contracts/OffchainResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport \\\"@ensdomains/ens-contracts/contracts/resolvers/SupportsInterface.sol\\\";\\nimport \\\"./IExtendedResolver.sol\\\";\\nimport \\\"./SignatureVerifier.sol\\\";\\n\\ninterface IResolverService {\\n function resolve(bytes calldata name, bytes calldata data) external view returns(bytes memory result, uint64 expires, bytes memory sig);\\n}\\n\\n/**\\n * Implements an ENS resolver that directs all queries to a CCIP read gateway.\\n * Callers must implement EIP 3668 and ENSIP 10.\\n */\\ncontract OffchainResolver is IExtendedResolver, SupportsInterface {\\n string public url;\\n mapping(address=>bool) public signers;\\n\\n event NewSigners(address[] signers);\\n error OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData);\\n\\n constructor(string memory _url, address[] memory _signers) {\\n url = _url;\\n for(uint i = 0; i < _signers.length; i++) {\\n signers[_signers[i]] = true;\\n }\\n emit NewSigners(_signers);\\n }\\n\\n function makeSignatureHash(address target, uint64 expires, bytes memory request, bytes memory result) external pure returns(bytes32) {\\n return SignatureVerifier.makeSignatureHash(target, expires, request, result);\\n }\\n\\n /**\\n * Resolves a name, as specified by ENSIP 10.\\n * @param name The DNS-encoded name to resolve.\\n * @param data The ABI encoded data for the underlying resolution function (Eg, addr(bytes32), text(bytes32,string), etc).\\n * @return The return data, ABI encoded identically to the underlying function.\\n */\\n function resolve(bytes calldata name, bytes calldata data) external override view returns(bytes memory) {\\n bytes memory callData = abi.encodeWithSelector(IResolverService.resolve.selector, name, data);\\n string[] memory urls = new string[](1);\\n urls[0] = url;\\n revert OffchainLookup(\\n address(this),\\n urls,\\n callData,\\n OffchainResolver.resolveWithProof.selector,\\n abi.encode(callData, address(this))\\n );\\n }\\n\\n /**\\n * Callback used by CCIP read compatible clients to verify and parse the response.\\n */\\n function resolveWithProof(bytes calldata response, bytes calldata extraData) external view returns(bytes memory) {\\n (address signer, bytes memory result) = SignatureVerifier.verify(extraData, response);\\n require(\\n signers[signer],\\n \\\"SignatureVerifier: Invalid sigature\\\");\\n return result;\\n }\\n\\n function supportsInterface(bytes4 interfaceID) public pure override returns(bool) {\\n return interfaceID == type(IExtendedResolver).interfaceId || super.supportsInterface(interfaceID);\\n }\\n}\\n\",\"keccak256\":\"0x95124bdd2b7bc4c7f036b31dac239d92abe95f36ee1fe841737ee44dc5cb4797\",\"license\":\"MIT\"},\"contracts/SignatureVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\n\\nlibrary SignatureVerifier {\\n /**\\n * @dev Generates a hash for signing/verifying.\\n * @param target: The address the signature is for.\\n * @param request: The original request that was sent.\\n * @param result: The `result` field of the response (not including the signature part).\\n */\\n function makeSignatureHash(address target, uint64 expires, bytes memory request, bytes memory result) internal pure returns(bytes32) {\\n return keccak256(abi.encodePacked(hex\\\"1900\\\", target, expires, keccak256(request), keccak256(result)));\\n }\\n\\n /**\\n * @dev Verifies a signed message returned from a callback.\\n * @param request: The original request that was sent.\\n * @param response: An ABI encoded tuple of `(bytes result, uint64 expires, bytes sig)`, where `result` is the data to return\\n * to the caller, and `sig` is the (r,s,v) encoded message signature.\\n * @return signer: The address that signed this message.\\n * @return result: The `result` decoded from `response`.\\n */\\n function verify(bytes calldata request, bytes calldata response) internal view returns(address, bytes memory) {\\n (bytes memory result, uint64 expires, bytes memory sig) = abi.decode(response, (bytes, uint64, bytes));\\n (bytes memory extraData, address sender) = abi.decode(request, (bytes, address));\\n address signer = ECDSA.recover(makeSignatureHash(sender, expires, extraData, result), sig);\\n require(\\n expires >= block.timestamp,\\n \\\"SignatureVerifier: Signature expired\\\");\\n return (signer, result);\\n }\\n}\",\"keccak256\":\"0xc3f3b7537893c26bf8756d7be7197f32d2606510739cac5a2ed137f4c7957e35\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506040516200214a3803806200214a8339818101604052810190620000379190620004b6565b81600090805190602001906200004f92919062000129565b5060005b8151811015620000e75760018060008484815181106200007857620000776200053b565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080620000de90620005a3565b91505062000053565b507fab0b9cc3a46b568cb08d985497cde8ab7e18892d01f58db7dc7f0d2af859b2d781604051620001199190620006bf565b60405180910390a1505062000748565b828054620001379062000712565b90600052602060002090601f0160209004810192826200015b5760008555620001a7565b82601f106200017657805160ff1916838001178555620001a7565b82800160010185558215620001a7579182015b82811115620001a657825182559160200191906001019062000189565b5b509050620001b69190620001ba565b5090565b5b80821115620001d5576000816000905550600101620001bb565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200024282620001f7565b810181811067ffffffffffffffff8211171562000264576200026362000208565b5b80604052505050565b600062000279620001d9565b905062000287828262000237565b919050565b600067ffffffffffffffff821115620002aa57620002a962000208565b5b620002b582620001f7565b9050602081019050919050565b60005b83811015620002e2578082015181840152602081019050620002c5565b83811115620002f2576000848401525b50505050565b60006200030f62000309846200028c565b6200026d565b9050828152602081018484840111156200032e576200032d620001f2565b5b6200033b848285620002c2565b509392505050565b600082601f8301126200035b576200035a620001ed565b5b81516200036d848260208601620002f8565b91505092915050565b600067ffffffffffffffff82111562000394576200039362000208565b5b602082029050602081019050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620003d782620003aa565b9050919050565b620003e981620003ca565b8114620003f557600080fd5b50565b6000815190506200040981620003de565b92915050565b600062000426620004208462000376565b6200026d565b905080838252602082019050602084028301858111156200044c576200044b620003a5565b5b835b81811015620004795780620004648882620003f8565b8452602084019350506020810190506200044e565b5050509392505050565b600082601f8301126200049b576200049a620001ed565b5b8151620004ad8482602086016200040f565b91505092915050565b60008060408385031215620004d057620004cf620001e3565b5b600083015167ffffffffffffffff811115620004f157620004f0620001e8565b5b620004ff8582860162000343565b925050602083015167ffffffffffffffff811115620005235762000522620001e8565b5b620005318582860162000483565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000620005b08262000599565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415620005e657620005e56200056a565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6200062881620003ca565b82525050565b60006200063c83836200061d565b60208301905092915050565b6000602082019050919050565b60006200066282620005f1565b6200066e8185620005fc565b93506200067b836200060d565b8060005b83811015620006b25781516200069688826200062e565b9750620006a38362000648565b9250506001810190506200067f565b5085935050505092915050565b60006020820190508181036000830152620006db818462000655565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200072b57607f821691505b60208210811415620007425762000741620006e3565b5b50919050565b6119f280620007586000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806301ffc9a7146100675780631dcfea09146100975780635600f04f146100c7578063736c0d5b146100e55780639061b92314610115578063f4d4d2f814610145575b600080fd5b610081600480360381019061007c9190610b06565b610175565b60405161008e9190610b4e565b60405180910390f35b6100b160048036038101906100ac9190610d4d565b6101ef565b6040516100be9190610e05565b60405180910390f35b6100cf610207565b6040516100dc9190610ea8565b60405180910390f35b6100ff60048036038101906100fa9190610eca565b610295565b60405161010c9190610b4e565b60405180910390f35b61012f600480360381019061012a9190610f57565b6102b5565b60405161013c919061102d565b60405180910390f35b61015f600480360381019061015a9190610f57565b6104a1565b60405161016c919061102d565b60405180910390f35b60007f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e857506101e78261054f565b5b9050919050565b60006101fd858585856105b9565b9050949350505050565b600080546102149061107e565b80601f01602080910402602001604051908101604052809291908181526020018280546102409061107e565b801561028d5780601f106102625761010080835404028352916020019161028d565b820191906000526020600020905b81548152906001019060200180831161027057829003601f168201915b505050505081565b60016020528060005260406000206000915054906101000a900460ff1681565b60606000639061b92360e01b868686866040516024016102d894939291906110dd565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000600167ffffffffffffffff81111561035457610353610c22565b5b60405190808252806020026020018201604052801561038757816020015b60608152602001906001900390816103725790505b509050600080546103979061107e565b80601f01602080910402602001604051908101604052809291908181526020018280546103c39061107e565b80156104105780601f106103e557610100808354040283529160200191610410565b820191906000526020600020905b8154815290600101906020018083116103f357829003601f168201915b50505050508160008151811061042957610428611118565b5b602002602001018190525030818363f4d4d2f860e01b8530604051602001610452929190611156565b6040516020818303038152906040526040517f556f18300000000000000000000000000000000000000000000000000000000081526004016104989594939291906112a1565b60405180910390fd5b60606000806104b285858989610600565b91509150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610542576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105399061137b565b60405180910390fd5b8092505050949350505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008484848051906020012084805190602001206040516020016105e09493929190611491565b604051602081830303815290604052805190602001209050949350505050565b600060606000806000868681019061061891906114ea565b9250925092506000808a8a81019061063091906115b3565b91509150600061064b6106458387868a6105b9565b856106af565b9050428567ffffffffffffffff16101561069a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069190611681565b60405180910390fd5b80869750975050505050505094509492505050565b60008060006106be85856106d6565b915091506106cb81610759565b819250505092915050565b6000806041835114156107185760008060006020860151925060408601519150606086015160001a905061070c8782858561092e565b94509450505050610752565b60408351141561074957600080602085015191506040850151905061073e868383610a3b565b935093505050610752565b60006002915091505b9250929050565b6000600481111561076d5761076c6116a1565b5b8160048111156107805761077f6116a1565b5b141561078b5761092b565b6001600481111561079f5761079e6116a1565b5b8160048111156107b2576107b16116a1565b5b14156107f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ea9061171c565b60405180910390fd5b60026004811115610807576108066116a1565b5b81600481111561081a576108196116a1565b5b141561085b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085290611788565b60405180910390fd5b6003600481111561086f5761086e6116a1565b5b816004811115610882576108816116a1565b5b14156108c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ba9061181a565b60405180910390fd5b6004808111156108d6576108d56116a1565b5b8160048111156108e9576108e86116a1565b5b141561092a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610921906118ac565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115610969576000600391509150610a32565b601b8560ff16141580156109815750601c8560ff1614155b15610993576000600491509150610a32565b6000600187878787604051600081526020016040526040516109b894939291906118e8565b6020604051602081039080840390855afa1580156109da573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a2957600060019250925050610a32565b80600092509250505b94509492505050565b60008060007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b841690506000601b60ff8660001c901c610a7e9190611966565b9050610a8c8782888561092e565b935093505050935093915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610ae381610aae565b8114610aee57600080fd5b50565b600081359050610b0081610ada565b92915050565b600060208284031215610b1c57610b1b610aa4565b5b6000610b2a84828501610af1565b91505092915050565b60008115159050919050565b610b4881610b33565b82525050565b6000602082019050610b636000830184610b3f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b9482610b69565b9050919050565b610ba481610b89565b8114610baf57600080fd5b50565b600081359050610bc181610b9b565b92915050565b600067ffffffffffffffff82169050919050565b610be481610bc7565b8114610bef57600080fd5b50565b600081359050610c0181610bdb565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610c5a82610c11565b810181811067ffffffffffffffff82111715610c7957610c78610c22565b5b80604052505050565b6000610c8c610a9a565b9050610c988282610c51565b919050565b600067ffffffffffffffff821115610cb857610cb7610c22565b5b610cc182610c11565b9050602081019050919050565b82818337600083830152505050565b6000610cf0610ceb84610c9d565b610c82565b905082815260208101848484011115610d0c57610d0b610c0c565b5b610d17848285610cce565b509392505050565b600082601f830112610d3457610d33610c07565b5b8135610d44848260208601610cdd565b91505092915050565b60008060008060808587031215610d6757610d66610aa4565b5b6000610d7587828801610bb2565b9450506020610d8687828801610bf2565b935050604085013567ffffffffffffffff811115610da757610da6610aa9565b5b610db387828801610d1f565b925050606085013567ffffffffffffffff811115610dd457610dd3610aa9565b5b610de087828801610d1f565b91505092959194509250565b6000819050919050565b610dff81610dec565b82525050565b6000602082019050610e1a6000830184610df6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e5a578082015181840152602081019050610e3f565b83811115610e69576000848401525b50505050565b6000610e7a82610e20565b610e848185610e2b565b9350610e94818560208601610e3c565b610e9d81610c11565b840191505092915050565b60006020820190508181036000830152610ec28184610e6f565b905092915050565b600060208284031215610ee057610edf610aa4565b5b6000610eee84828501610bb2565b91505092915050565b600080fd5b600080fd5b60008083601f840112610f1757610f16610c07565b5b8235905067ffffffffffffffff811115610f3457610f33610ef7565b5b602083019150836001820283011115610f5057610f4f610efc565b5b9250929050565b60008060008060408587031215610f7157610f70610aa4565b5b600085013567ffffffffffffffff811115610f8f57610f8e610aa9565b5b610f9b87828801610f01565b9450945050602085013567ffffffffffffffff811115610fbe57610fbd610aa9565b5b610fca87828801610f01565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000610fff82610fd8565b6110098185610fe3565b9350611019818560208601610e3c565b61102281610c11565b840191505092915050565b600060208201905081810360008301526110478184610ff4565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061109657607f821691505b602082108114156110aa576110a961104f565b5b50919050565b60006110bc8385610fe3565b93506110c9838584610cce565b6110d283610c11565b840190509392505050565b600060408201905081810360008301526110f88186886110b0565b9050818103602083015261110d8184866110b0565b905095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61115081610b89565b82525050565b600060408201905081810360008301526111708185610ff4565b905061117f6020830184611147565b9392505050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b60006111ce82610e20565b6111d881856111b2565b93506111e8818560208601610e3c565b6111f181610c11565b840191505092915050565b600061120883836111c3565b905092915050565b6000602082019050919050565b600061122882611186565b6112328185611191565b935083602082028501611244856111a2565b8060005b85811015611280578484038952815161126185826111fc565b945061126c83611210565b925060208a01995050600181019050611248565b50829750879550505050505092915050565b61129b81610aae565b82525050565b600060a0820190506112b66000830188611147565b81810360208301526112c8818761121d565b905081810360408301526112dc8186610ff4565b90506112eb6060830185611292565b81810360808301526112fd8184610ff4565b90509695505050505050565b7f5369676e617475726556657269666965723a20496e76616c696420736967617460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b6000611365602383610e2b565b915061137082611309565b604082019050919050565b6000602082019050818103600083015261139481611358565b9050919050565b600081905092915050565b7f1900000000000000000000000000000000000000000000000000000000000000600082015250565b60006113dc60028361139b565b91506113e7826113a6565b600282019050919050565b60008160601b9050919050565b600061140a826113f2565b9050919050565b600061141c826113ff565b9050919050565b61143461142f82610b89565b611411565b82525050565b60008160c01b9050919050565b60006114528261143a565b9050919050565b61146a61146582610bc7565b611447565b82525050565b6000819050919050565b61148b61148682610dec565b611470565b82525050565b600061149c826113cf565b91506114a88287611423565b6014820191506114b88286611459565b6008820191506114c8828561147a565b6020820191506114d8828461147a565b60208201915081905095945050505050565b60008060006060848603121561150357611502610aa4565b5b600084013567ffffffffffffffff81111561152157611520610aa9565b5b61152d86828701610d1f565b935050602061153e86828701610bf2565b925050604084013567ffffffffffffffff81111561155f5761155e610aa9565b5b61156b86828701610d1f565b9150509250925092565b600061158082610b69565b9050919050565b61159081611575565b811461159b57600080fd5b50565b6000813590506115ad81611587565b92915050565b600080604083850312156115ca576115c9610aa4565b5b600083013567ffffffffffffffff8111156115e8576115e7610aa9565b5b6115f485828601610d1f565b92505060206116058582860161159e565b9150509250929050565b7f5369676e617475726556657269666965723a205369676e61747572652065787060008201527f6972656400000000000000000000000000000000000000000000000000000000602082015250565b600061166b602483610e2b565b91506116768261160f565b604082019050919050565b6000602082019050818103600083015261169a8161165e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000611706601883610e2b565b9150611711826116d0565b602082019050919050565b60006020820190508181036000830152611735816116f9565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000611772601f83610e2b565b915061177d8261173c565b602082019050919050565b600060208201905081810360008301526117a181611765565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000611804602283610e2b565b915061180f826117a8565b604082019050919050565b60006020820190508181036000830152611833816117f7565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000611896602283610e2b565b91506118a18261183a565b604082019050919050565b600060208201905081810360008301526118c581611889565b9050919050565b600060ff82169050919050565b6118e2816118cc565b82525050565b60006080820190506118fd6000830187610df6565b61190a60208301866118d9565b6119176040830185610df6565b6119246060830184610df6565b95945050505050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006119718261192d565b915061197c8361192d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156119b1576119b0611937565b5b82820190509291505056fea26469706673582212201b99a5e340c3a4ca71e5cb840282db278cc1ebc1331e37769ef71184aba6e24a64736f6c634300080a0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c806301ffc9a7146100675780631dcfea09146100975780635600f04f146100c7578063736c0d5b146100e55780639061b92314610115578063f4d4d2f814610145575b600080fd5b610081600480360381019061007c9190610b06565b610175565b60405161008e9190610b4e565b60405180910390f35b6100b160048036038101906100ac9190610d4d565b6101ef565b6040516100be9190610e05565b60405180910390f35b6100cf610207565b6040516100dc9190610ea8565b60405180910390f35b6100ff60048036038101906100fa9190610eca565b610295565b60405161010c9190610b4e565b60405180910390f35b61012f600480360381019061012a9190610f57565b6102b5565b60405161013c919061102d565b60405180910390f35b61015f600480360381019061015a9190610f57565b6104a1565b60405161016c919061102d565b60405180910390f35b60007f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e857506101e78261054f565b5b9050919050565b60006101fd858585856105b9565b9050949350505050565b600080546102149061107e565b80601f01602080910402602001604051908101604052809291908181526020018280546102409061107e565b801561028d5780601f106102625761010080835404028352916020019161028d565b820191906000526020600020905b81548152906001019060200180831161027057829003601f168201915b505050505081565b60016020528060005260406000206000915054906101000a900460ff1681565b60606000639061b92360e01b868686866040516024016102d894939291906110dd565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000600167ffffffffffffffff81111561035457610353610c22565b5b60405190808252806020026020018201604052801561038757816020015b60608152602001906001900390816103725790505b509050600080546103979061107e565b80601f01602080910402602001604051908101604052809291908181526020018280546103c39061107e565b80156104105780601f106103e557610100808354040283529160200191610410565b820191906000526020600020905b8154815290600101906020018083116103f357829003601f168201915b50505050508160008151811061042957610428611118565b5b602002602001018190525030818363f4d4d2f860e01b8530604051602001610452929190611156565b6040516020818303038152906040526040517f556f18300000000000000000000000000000000000000000000000000000000081526004016104989594939291906112a1565b60405180910390fd5b60606000806104b285858989610600565b91509150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610542576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105399061137b565b60405180910390fd5b8092505050949350505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008484848051906020012084805190602001206040516020016105e09493929190611491565b604051602081830303815290604052805190602001209050949350505050565b600060606000806000868681019061061891906114ea565b9250925092506000808a8a81019061063091906115b3565b91509150600061064b6106458387868a6105b9565b856106af565b9050428567ffffffffffffffff16101561069a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069190611681565b60405180910390fd5b80869750975050505050505094509492505050565b60008060006106be85856106d6565b915091506106cb81610759565b819250505092915050565b6000806041835114156107185760008060006020860151925060408601519150606086015160001a905061070c8782858561092e565b94509450505050610752565b60408351141561074957600080602085015191506040850151905061073e868383610a3b565b935093505050610752565b60006002915091505b9250929050565b6000600481111561076d5761076c6116a1565b5b8160048111156107805761077f6116a1565b5b141561078b5761092b565b6001600481111561079f5761079e6116a1565b5b8160048111156107b2576107b16116a1565b5b14156107f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ea9061171c565b60405180910390fd5b60026004811115610807576108066116a1565b5b81600481111561081a576108196116a1565b5b141561085b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085290611788565b60405180910390fd5b6003600481111561086f5761086e6116a1565b5b816004811115610882576108816116a1565b5b14156108c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ba9061181a565b60405180910390fd5b6004808111156108d6576108d56116a1565b5b8160048111156108e9576108e86116a1565b5b141561092a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610921906118ac565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115610969576000600391509150610a32565b601b8560ff16141580156109815750601c8560ff1614155b15610993576000600491509150610a32565b6000600187878787604051600081526020016040526040516109b894939291906118e8565b6020604051602081039080840390855afa1580156109da573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a2957600060019250925050610a32565b80600092509250505b94509492505050565b60008060007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b841690506000601b60ff8660001c901c610a7e9190611966565b9050610a8c8782888561092e565b935093505050935093915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610ae381610aae565b8114610aee57600080fd5b50565b600081359050610b0081610ada565b92915050565b600060208284031215610b1c57610b1b610aa4565b5b6000610b2a84828501610af1565b91505092915050565b60008115159050919050565b610b4881610b33565b82525050565b6000602082019050610b636000830184610b3f565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610b9482610b69565b9050919050565b610ba481610b89565b8114610baf57600080fd5b50565b600081359050610bc181610b9b565b92915050565b600067ffffffffffffffff82169050919050565b610be481610bc7565b8114610bef57600080fd5b50565b600081359050610c0181610bdb565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610c5a82610c11565b810181811067ffffffffffffffff82111715610c7957610c78610c22565b5b80604052505050565b6000610c8c610a9a565b9050610c988282610c51565b919050565b600067ffffffffffffffff821115610cb857610cb7610c22565b5b610cc182610c11565b9050602081019050919050565b82818337600083830152505050565b6000610cf0610ceb84610c9d565b610c82565b905082815260208101848484011115610d0c57610d0b610c0c565b5b610d17848285610cce565b509392505050565b600082601f830112610d3457610d33610c07565b5b8135610d44848260208601610cdd565b91505092915050565b60008060008060808587031215610d6757610d66610aa4565b5b6000610d7587828801610bb2565b9450506020610d8687828801610bf2565b935050604085013567ffffffffffffffff811115610da757610da6610aa9565b5b610db387828801610d1f565b925050606085013567ffffffffffffffff811115610dd457610dd3610aa9565b5b610de087828801610d1f565b91505092959194509250565b6000819050919050565b610dff81610dec565b82525050565b6000602082019050610e1a6000830184610df6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610e5a578082015181840152602081019050610e3f565b83811115610e69576000848401525b50505050565b6000610e7a82610e20565b610e848185610e2b565b9350610e94818560208601610e3c565b610e9d81610c11565b840191505092915050565b60006020820190508181036000830152610ec28184610e6f565b905092915050565b600060208284031215610ee057610edf610aa4565b5b6000610eee84828501610bb2565b91505092915050565b600080fd5b600080fd5b60008083601f840112610f1757610f16610c07565b5b8235905067ffffffffffffffff811115610f3457610f33610ef7565b5b602083019150836001820283011115610f5057610f4f610efc565b5b9250929050565b60008060008060408587031215610f7157610f70610aa4565b5b600085013567ffffffffffffffff811115610f8f57610f8e610aa9565b5b610f9b87828801610f01565b9450945050602085013567ffffffffffffffff811115610fbe57610fbd610aa9565b5b610fca87828801610f01565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000610fff82610fd8565b6110098185610fe3565b9350611019818560208601610e3c565b61102281610c11565b840191505092915050565b600060208201905081810360008301526110478184610ff4565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061109657607f821691505b602082108114156110aa576110a961104f565b5b50919050565b60006110bc8385610fe3565b93506110c9838584610cce565b6110d283610c11565b840190509392505050565b600060408201905081810360008301526110f88186886110b0565b9050818103602083015261110d8184866110b0565b905095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61115081610b89565b82525050565b600060408201905081810360008301526111708185610ff4565b905061117f6020830184611147565b9392505050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b60006111ce82610e20565b6111d881856111b2565b93506111e8818560208601610e3c565b6111f181610c11565b840191505092915050565b600061120883836111c3565b905092915050565b6000602082019050919050565b600061122882611186565b6112328185611191565b935083602082028501611244856111a2565b8060005b85811015611280578484038952815161126185826111fc565b945061126c83611210565b925060208a01995050600181019050611248565b50829750879550505050505092915050565b61129b81610aae565b82525050565b600060a0820190506112b66000830188611147565b81810360208301526112c8818761121d565b905081810360408301526112dc8186610ff4565b90506112eb6060830185611292565b81810360808301526112fd8184610ff4565b90509695505050505050565b7f5369676e617475726556657269666965723a20496e76616c696420736967617460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b6000611365602383610e2b565b915061137082611309565b604082019050919050565b6000602082019050818103600083015261139481611358565b9050919050565b600081905092915050565b7f1900000000000000000000000000000000000000000000000000000000000000600082015250565b60006113dc60028361139b565b91506113e7826113a6565b600282019050919050565b60008160601b9050919050565b600061140a826113f2565b9050919050565b600061141c826113ff565b9050919050565b61143461142f82610b89565b611411565b82525050565b60008160c01b9050919050565b60006114528261143a565b9050919050565b61146a61146582610bc7565b611447565b82525050565b6000819050919050565b61148b61148682610dec565b611470565b82525050565b600061149c826113cf565b91506114a88287611423565b6014820191506114b88286611459565b6008820191506114c8828561147a565b6020820191506114d8828461147a565b60208201915081905095945050505050565b60008060006060848603121561150357611502610aa4565b5b600084013567ffffffffffffffff81111561152157611520610aa9565b5b61152d86828701610d1f565b935050602061153e86828701610bf2565b925050604084013567ffffffffffffffff81111561155f5761155e610aa9565b5b61156b86828701610d1f565b9150509250925092565b600061158082610b69565b9050919050565b61159081611575565b811461159b57600080fd5b50565b6000813590506115ad81611587565b92915050565b600080604083850312156115ca576115c9610aa4565b5b600083013567ffffffffffffffff8111156115e8576115e7610aa9565b5b6115f485828601610d1f565b92505060206116058582860161159e565b9150509250929050565b7f5369676e617475726556657269666965723a205369676e61747572652065787060008201527f6972656400000000000000000000000000000000000000000000000000000000602082015250565b600061166b602483610e2b565b91506116768261160f565b604082019050919050565b6000602082019050818103600083015261169a8161165e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000611706601883610e2b565b9150611711826116d0565b602082019050919050565b60006020820190508181036000830152611735816116f9565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000611772601f83610e2b565b915061177d8261173c565b602082019050919050565b600060208201905081810360008301526117a181611765565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000611804602283610e2b565b915061180f826117a8565b604082019050919050565b60006020820190508181036000830152611833816117f7565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000611896602283610e2b565b91506118a18261183a565b604082019050919050565b600060208201905081810360008301526118c581611889565b9050919050565b600060ff82169050919050565b6118e2816118cc565b82525050565b60006080820190506118fd6000830187610df6565b61190a60208301866118d9565b6119176040830185610df6565b6119246060830184610df6565b95945050505050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006119718261192d565b915061197c8361192d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156119b1576119b0611937565b5b82820190509291505056fea26469706673582212201b99a5e340c3a4ca71e5cb840282db278cc1ebc1331e37769ef71184aba6e24a64736f6c634300080a0033", + "devdoc": { + "kind": "dev", + "methods": { + "resolve(bytes,bytes)": { + "params": { + "data": "The ABI encoded data for the underlying resolution function (Eg, addr(bytes32), text(bytes32,string), etc).", + "name": "The DNS-encoded name to resolve." + }, + "returns": { + "_0": "The return data, ABI encoded identically to the underlying function." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "resolve(bytes,bytes)": { + "notice": "Resolves a name, as specified by ENSIP 10." + }, + "resolveWithProof(bytes,bytes)": { + "notice": "Callback used by CCIP read compatible clients to verify and parse the response." + } + }, + "notice": "Implements an ENS resolver that directs all queries to a CCIP read gateway. Callers must implement EIP 3668 and ENSIP 10.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1263, + "contract": "contracts/OffchainResolver.sol:OffchainResolver", + "label": "url", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + }, + { + "astId": 1267, + "contract": "contracts/OffchainResolver.sol:OffchainResolver", + "label": "signers", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_bool)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/packages/contracts/deployments/sepolia/solcInputs/5301ec7b3143dfe50c3160773a82693f.json b/packages/contracts/deployments/sepolia/solcInputs/5301ec7b3143dfe50c3160773a82693f.json new file mode 100644 index 0000000..7b771b1 --- /dev/null +++ b/packages/contracts/deployments/sepolia/solcInputs/5301ec7b3143dfe50c3160773a82693f.json @@ -0,0 +1,62 @@ +{ + "language": "Solidity", + "sources": { + "contracts/IExtendedResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IExtendedResolver {\n function resolve(bytes memory name, bytes memory data) external view returns(bytes memory);\n}\n" + }, + "contracts/OffchainResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"@ensdomains/ens-contracts/contracts/resolvers/SupportsInterface.sol\";\nimport \"./IExtendedResolver.sol\";\nimport \"./SignatureVerifier.sol\";\n\ninterface IResolverService {\n function resolve(bytes calldata name, bytes calldata data) external view returns(bytes memory result, uint64 expires, bytes memory sig);\n}\n\n/**\n * Implements an ENS resolver that directs all queries to a CCIP read gateway.\n * Callers must implement EIP 3668 and ENSIP 10.\n */\ncontract OffchainResolver is IExtendedResolver, SupportsInterface {\n string public url;\n mapping(address=>bool) public signers;\n\n event NewSigners(address[] signers);\n error OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData);\n\n constructor(string memory _url, address[] memory _signers) {\n url = _url;\n for(uint i = 0; i < _signers.length; i++) {\n signers[_signers[i]] = true;\n }\n emit NewSigners(_signers);\n }\n\n function makeSignatureHash(address target, uint64 expires, bytes memory request, bytes memory result) external pure returns(bytes32) {\n return SignatureVerifier.makeSignatureHash(target, expires, request, result);\n }\n\n /**\n * Resolves a name, as specified by ENSIP 10.\n * @param name The DNS-encoded name to resolve.\n * @param data The ABI encoded data for the underlying resolution function (Eg, addr(bytes32), text(bytes32,string), etc).\n * @return The return data, ABI encoded identically to the underlying function.\n */\n function resolve(bytes calldata name, bytes calldata data) external override view returns(bytes memory) {\n bytes memory callData = abi.encodeWithSelector(IResolverService.resolve.selector, name, data);\n string[] memory urls = new string[](1);\n urls[0] = url;\n revert OffchainLookup(\n address(this),\n urls,\n callData,\n OffchainResolver.resolveWithProof.selector,\n abi.encode(callData, address(this))\n );\n }\n\n /**\n * Callback used by CCIP read compatible clients to verify and parse the response.\n */\n function resolveWithProof(bytes calldata response, bytes calldata extraData) external view returns(bytes memory) {\n (address signer, bytes memory result) = SignatureVerifier.verify(extraData, response);\n require(\n signers[signer],\n \"SignatureVerifier: Invalid sigature\");\n return result;\n }\n\n function supportsInterface(bytes4 interfaceID) public pure override returns(bool) {\n return interfaceID == type(IExtendedResolver).interfaceId || super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/SignatureVerifier.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.4;\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\nlibrary SignatureVerifier {\n /**\n * @dev Generates a hash for signing/verifying.\n * @param target: The address the signature is for.\n * @param request: The original request that was sent.\n * @param result: The `result` field of the response (not including the signature part).\n */\n function makeSignatureHash(address target, uint64 expires, bytes memory request, bytes memory result) internal pure returns(bytes32) {\n return keccak256(abi.encodePacked(hex\"1900\", target, expires, keccak256(request), keccak256(result)));\n }\n\n /**\n * @dev Verifies a signed message returned from a callback.\n * @param request: The original request that was sent.\n * @param response: An ABI encoded tuple of `(bytes result, uint64 expires, bytes sig)`, where `result` is the data to return\n * to the caller, and `sig` is the (r,s,v) encoded message signature.\n * @return signer: The address that signed this message.\n * @return result: The `result` decoded from `response`.\n */\n function verify(bytes calldata request, bytes calldata response) internal view returns(address, bytes memory) {\n (bytes memory result, uint64 expires, bytes memory sig) = abi.decode(response, (bytes, uint64, bytes));\n (bytes memory extraData, address sender) = abi.decode(request, (bytes, address));\n address signer = ECDSA.recover(makeSignatureHash(sender, expires, extraData, result), sig);\n require(\n expires >= block.timestamp,\n \"SignatureVerifier: Signature expired\");\n return (signer, result);\n }\n}" + }, + "@ensdomains/ens-contracts/contracts/resolvers/SupportsInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./ISupportsInterface.sol\";\n\nabstract contract SupportsInterface is ISupportsInterface {\n function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {\n return interfaceID == type(ISupportsInterface).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@ensdomains/ens-contracts/contracts/resolvers/ISupportsInterface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface ISupportsInterface {\n function supportsInterface(bytes4 interfaceID) external pure returns(bool);\n}" + }, + "contracts/imports.sol": { + "content": "import \"@ensdomains/ens-contracts/contracts/registry/ENSRegistry.sol\";" + }, + "@ensdomains/ens-contracts/contracts/registry/ENSRegistry.sol": { + "content": "pragma solidity >=0.8.4;\n\nimport \"./ENS.sol\";\n\n/**\n * The ENS registry contract.\n */\ncontract ENSRegistry is ENS {\n\n struct Record {\n address owner;\n address resolver;\n uint64 ttl;\n }\n\n mapping (bytes32 => Record) records;\n mapping (address => mapping(address => bool)) operators;\n\n // Permits modifications only by the owner of the specified node.\n modifier authorised(bytes32 node) {\n address owner = records[node].owner;\n require(owner == msg.sender || operators[owner][msg.sender]);\n _;\n }\n\n /**\n * @dev Constructs a new ENS registrar.\n */\n constructor() public {\n records[0x0].owner = msg.sender;\n }\n\n /**\n * @dev Sets the record for a node.\n * @param node The node to update.\n * @param owner The address of the new owner.\n * @param resolver The address of the resolver.\n * @param ttl The TTL in seconds.\n */\n function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual override {\n setOwner(node, owner);\n _setResolverAndTTL(node, resolver, ttl);\n }\n\n /**\n * @dev Sets the record for a subnode.\n * @param node The parent node.\n * @param label The hash of the label specifying the subnode.\n * @param owner The address of the new owner.\n * @param resolver The address of the resolver.\n * @param ttl The TTL in seconds.\n */\n function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual override {\n bytes32 subnode = setSubnodeOwner(node, label, owner);\n _setResolverAndTTL(subnode, resolver, ttl);\n }\n\n /**\n * @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node.\n * @param node The node to transfer ownership of.\n * @param owner The address of the new owner.\n */\n function setOwner(bytes32 node, address owner) public virtual override authorised(node) {\n _setOwner(node, owner);\n emit Transfer(node, owner);\n }\n\n /**\n * @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node.\n * @param node The parent node.\n * @param label The hash of the label specifying the subnode.\n * @param owner The address of the new owner.\n */\n function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public virtual override authorised(node) returns(bytes32) {\n bytes32 subnode = keccak256(abi.encodePacked(node, label));\n _setOwner(subnode, owner);\n emit NewOwner(node, label, owner);\n return subnode;\n }\n\n /**\n * @dev Sets the resolver address for the specified node.\n * @param node The node to update.\n * @param resolver The address of the resolver.\n */\n function setResolver(bytes32 node, address resolver) public virtual override authorised(node) {\n emit NewResolver(node, resolver);\n records[node].resolver = resolver;\n }\n\n /**\n * @dev Sets the TTL for the specified node.\n * @param node The node to update.\n * @param ttl The TTL in seconds.\n */\n function setTTL(bytes32 node, uint64 ttl) public virtual override authorised(node) {\n emit NewTTL(node, ttl);\n records[node].ttl = ttl;\n }\n\n /**\n * @dev Enable or disable approval for a third party (\"operator\") to manage\n * all of `msg.sender`'s ENS records. Emits the ApprovalForAll event.\n * @param operator Address to add to the set of authorized operators.\n * @param approved True if the operator is approved, false to revoke approval.\n */\n function setApprovalForAll(address operator, bool approved) external virtual override {\n operators[msg.sender][operator] = approved;\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n /**\n * @dev Returns the address that owns the specified node.\n * @param node The specified node.\n * @return address of the owner.\n */\n function owner(bytes32 node) public virtual override view returns (address) {\n address addr = records[node].owner;\n if (addr == address(this)) {\n return address(0x0);\n }\n\n return addr;\n }\n\n /**\n * @dev Returns the address of the resolver for the specified node.\n * @param node The specified node.\n * @return address of the resolver.\n */\n function resolver(bytes32 node) public virtual override view returns (address) {\n return records[node].resolver;\n }\n\n /**\n * @dev Returns the TTL of a node, and any records associated with it.\n * @param node The specified node.\n * @return ttl of the node.\n */\n function ttl(bytes32 node) public virtual override view returns (uint64) {\n return records[node].ttl;\n }\n\n /**\n * @dev Returns whether a record has been imported to the registry.\n * @param node The specified node.\n * @return Bool if record exists\n */\n function recordExists(bytes32 node) public virtual override view returns (bool) {\n return records[node].owner != address(0x0);\n }\n\n /**\n * @dev Query if an address is an authorized operator for another address.\n * @param owner The address that owns the records.\n * @param operator The address that acts on behalf of the owner.\n * @return True if `operator` is an approved operator for `owner`, false otherwise.\n */\n function isApprovedForAll(address owner, address operator) external virtual override view returns (bool) {\n return operators[owner][operator];\n }\n\n function _setOwner(bytes32 node, address owner) internal virtual {\n records[node].owner = owner;\n }\n\n function _setResolverAndTTL(bytes32 node, address resolver, uint64 ttl) internal {\n if(resolver != records[node].resolver) {\n records[node].resolver = resolver;\n emit NewResolver(node, resolver);\n }\n\n if(ttl != records[node].ttl) {\n records[node].ttl = ttl;\n emit NewTTL(node, ttl);\n }\n }\n}\n" + }, + "@ensdomains/ens-contracts/contracts/registry/ENS.sol": { + "content": "pragma solidity >=0.8.4;\n\ninterface ENS {\n\n // Logged when the owner of a node assigns a new owner to a subnode.\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\n\n // Logged when the owner of a node transfers ownership to a new account.\n event Transfer(bytes32 indexed node, address owner);\n\n // Logged when the resolver for a node changes.\n event NewResolver(bytes32 indexed node, address resolver);\n\n // Logged when the TTL of a node changes\n event NewTTL(bytes32 indexed node, uint64 ttl);\n\n // Logged when an operator is added or removed.\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual;\n function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual;\n function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external virtual returns(bytes32);\n function setResolver(bytes32 node, address resolver) external virtual;\n function setOwner(bytes32 node, address owner) external virtual;\n function setTTL(bytes32 node, uint64 ttl) external virtual;\n function setApprovalForAll(address operator, bool approved) external virtual;\n function owner(bytes32 node) external virtual view returns (address);\n function resolver(bytes32 node) external virtual view returns (address);\n function ttl(bytes32 node) external virtual view returns (uint64);\n function recordExists(bytes32 node) external virtual view returns (bool);\n function isApprovedForAll(address owner, address operator) external virtual view returns (bool);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/contracts/hardhat.config.js b/packages/contracts/hardhat.config.js index 82fe413..7c75d77 100644 --- a/packages/contracts/hardhat.config.js +++ b/packages/contracts/hardhat.config.js @@ -1,28 +1,27 @@ // const { task } = require('hardhat/config'); -require('@nomiclabs/hardhat-etherscan'); -require('@nomiclabs/hardhat-ethers'); -require('@nomiclabs/hardhat-waffle'); -require('hardhat-deploy'); -require('hardhat-deploy-ethers'); +require("@nomiclabs/hardhat-etherscan"); +require("@nomiclabs/hardhat-ethers"); +require("@nomiclabs/hardhat-waffle"); +require("hardhat-deploy"); +require("hardhat-deploy-ethers"); real_accounts = undefined; if (process.env.DEPLOYER_KEY && process.env.OWNER_KEY) { real_accounts = [process.env.OWNER_KEY, process.env.DEPLOYER_KEY]; } const gatewayurl = - 'https://offchain-resolver-example.uc.r.appspot.com/{sender}/{data}.json'; + "https://offchain-resolver-example.uc.r.appspot.com/{sender}/{data}.json"; -let devgatewayurl = 'http://localhost:8080/{sender}/{data}.json'; +let devgatewayurl = "http://localhost:8080/{sender}/{data}.json"; if (process.env.REMOTE_GATEWAY) { - devgatewayurl = - `${process.env.REMOTE_GATEWAY}/{sender}/{data}.json`; + devgatewayurl = `${process.env.REMOTE_GATEWAY}/{sender}/{data}.json`; } /** * @type import('hardhat/config').HardhatUserConfig */ module.exports = { - solidity: '0.8.10', + solidity: "0.8.10", networks: { hardhat: { throwOnCallFailures: false, @@ -30,28 +29,35 @@ module.exports = { }, ropsten: { url: `https://ropsten.infura.io/v3/${process.env.INFURA_ID}`, - tags: ['test', 'demo'], + tags: ["test", "demo"], chainId: 3, accounts: real_accounts, gatewayurl, }, rinkeby: { url: `https://rinkeby.infura.io/v3/${process.env.INFURA_ID}`, - tags: ['test', 'demo'], + tags: ["test", "demo"], chainId: 4, accounts: real_accounts, gatewayurl, }, goerli: { url: `https://goerli.infura.io/v3/${process.env.INFURA_ID}`, - tags: ['test', 'demo'], + tags: ["test", "demo"], chainId: 5, accounts: real_accounts, gatewayurl, }, + sepolia: { + url: `https://sepolia.infura.io/v3/${process.env.INFURA_ID}`, + tags: ["test", "demo"], + chainId: 11155111, + accounts: real_accounts, + gatewayurl, + }, mainnet: { url: `https://mainnet.infura.io/v3/${process.env.INFURA_ID}`, - tags: ['demo'], + tags: ["demo"], chainId: 1, accounts: real_accounts, gatewayurl, @@ -62,7 +68,7 @@ module.exports = { }, namedAccounts: { signer: { - default: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + default: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", }, deployer: { default: 1,