diff --git a/app/local/data/interfaces.tsx b/app/local/data/interfaces.tsx new file mode 100644 index 000000000..75528225d --- /dev/null +++ b/app/local/data/interfaces.tsx @@ -0,0 +1,162 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import { CodeGroup } from '../content/prose/code/group/CodeGroup'; + +export type ContractParameter = { + name?: string; + type: string; + description: string; +}; + +export type ContractMethod = { + name: string; + interface: string; + usage: string; + seeMore: string; + input?: Array; + output?: Array; + events?: Array; + examples?: Array; +}; + +export function interfaceDetails(methods: Array) { + return ( + <> + + + + + + + + + {methods.map((method) => { + return ( + + + + + ); + })} + +
UsageFunction Definition
+ + {method.usage} + + {method.name}
+ {methods.map((method) => { + return ( +
+

{method.usage}

+ + {method.name} + + {method.events && ( + + {method.events.map((event) => ( + {event} + ))} + + )} + {method.seeMore && convertEIPLinks(method.seeMore)} +
    +
  • + Interface ID: + {method.interface} +
  • +
+ {method.input && ( + <> +

+ Parameters +

+
    + {method.input.map((input) => { + return ( +
  • + + {input.name + ? `${input.name} (${input.type})` + : input.type} + {': '} + + + {convertCodeTags( + input.description + )} + +
  • + ); + })} +
+ + )} + {method.output && ( + <> +

+ Returns +

+
    + {method.output.map((output) => { + return ( +
  • + + {output.name + ? `${output.name} (${output.type})` + : output.type} + {': '} + + + {convertCodeTags( + output.description + )} + +
  • + ); + })} +
+ + )} + {method.examples && ( + <> +

+ Examples +

+ {method.examples} + + )} +
+ ); + })} + + ); +} + +// Convert any EIP/ENSIPs into links +function convertEIPLinks(string_: string) { + return string_.split(/(EIP-\d+|ENSIP-\d+).*?/g).map((part) => { + if (/EIP-\d+/.test(part)) { + return ( + + {part} + + ); + } else if (/ENSIP-\d+/.test(part)) { + return {part}; + } else { + return part; + } + }); +} + +// Convert any `` into +function convertCodeTags(string_: string) { + return string_ && string_.includes('`') + ? string_.split(/(`[^`]+`).*?/g).map((part) => { + return /`[^`]+`/.test(part) ? ( + {part.slice(1, -1)} + ) : ( + part + ); + }) + : string_ || ''; +} diff --git a/app/local/data/resolver.ts b/app/local/data/resolver.ts deleted file mode 100644 index 3a3cd3ded..000000000 --- a/app/local/data/resolver.ts +++ /dev/null @@ -1,134 +0,0 @@ -/* eslint-disable sonarjs/no-duplicate-string */ - -type ResolverMethod = { - name: string; - interface: string; - usage: string; - seeMore: string; - output?: string; - event?: string; -}; - -export const PUBLIC_RESOLVER_SUPPORTS = [ - // 'addr', - // 'addr.reverse', - // 'contenthash', - // 'contenthash.set', - // 'multicoin', - // 'multicoin.set', - // 'text', - // 'text.set', - // 'ABI', - // 'ABI.set', - // 'pubkey', - // 'pubkey.set', - // 'name', - // 'name.set', - // 'multicall', -]; - -export const resolver_methods: ResolverMethod[] = [ - { - name: 'addr(bytes32 node) view returns (address)', - interface: '0x3b3b57de', - usage: 'Read Ethereum Address', - seeMore: 'ENSIP-1 / EIP-137', - output: 'Ethereum address or the zero address if no address is set.', - }, - { - name: 'addr(bytes32 node, uint coinType) view returns (byte memory)', - interface: '0xf1cb7e06', - usage: 'Read Multicoin Address', - seeMore: - 'ENSIP-9 / [EIP-2304](https://eips.ethereum.org/EIPS/eip-2304)', - output: 'Cryptocurrency address in its native binary format. For example, the Bitcoin address `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` base58check decodes to the 21 bytes `0062e907b15cbf27d5425399ebf6f0fb50ebb88f18` then scriptPubkey encodes to 25 bytes `76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac` whereas the BNB address `bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2` Bech32 decodes to the binary representation `40c2979694bbc961023d1d27be6fc4d21a9febe6`. A zero-length string ("") will be returned if the specified coin type is not set.', - }, - { - name: 'contenthash(bytes32 node) view returns (bytes memory)', - interface: '0xbc1c58d1', - usage: 'Read Content Hash', - seeMore: 'ENSIP-7 / EIP-1577', - }, - { - name: 'text(bytes32 node, string key) view returns (string memory)', - interface: '0x59d1d43c', - usage: 'Read Text Record', - seeMore: 'ENSIP-5 / EIP-634', - output: 'The value of the text record associated with key, or the empty string if no such record exists.', - }, - { - name: 'ABI(bytes32 node, uint256 contentTypes) view returns (uint256, bytes memory)', - interface: '0x2203ab56', - usage: 'Read Contract ABI', - seeMore: 'ENSIP-4 / EIP-205', - output: 'ABI returns a two-tuple of the content type ID and the ABI data. If no data of the appropriate content type ID was found, 0 is returned for the content type ID, and the ABI data will be the empty string.', - }, - { - name: 'pubkey(bytes32 node) view returns (bytes32 x, bytes32 y)', - interface: '0xc8690233', - usage: 'Read Public Key', - seeMore: 'ENSIP- / EIP-619', - output: 'The ECDSA SECP256k1 public key for node, as a 2-tuple (x, y). If no public key is set, (0, 0) is returned.', - }, - { - name: 'name(bytes32 node) view returns (string memory)', - interface: '0x691f3431', - usage: 'Read Name (for reverse records)', - seeMore: 'Implemented by Public Resolver', - }, - { - name: 'setAddr(bytes32 node, address addr)', - interface: '0x3b3b57de', - usage: 'Write Ethereum Adress', - seeMore: 'Implemented by Public Resolver', - event: 'event AddrChanged(bytes32 indexed node, address a);', - }, - { - name: 'setAddr(bytes32 node, uint coinType, bytes calldata a)', - interface: '0x8b95dd71', - usage: 'Set Multicoin Address', - seeMore: 'Implemented by Public Resolver', - event: 'event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);', - }, - { - name: 'setContenthash(bytes32 node, bytes calldata hash)', - interface: '0x304e6ade', - usage: 'Write Content Hash', - seeMore: 'Implemented by Public Resolver', - event: 'event ContenthashChanged(bytes32 indexed node, bytes hash);', - }, - { - name: 'setText(bytes32 node, string calldata key, string calldata value)', - interface: '0xa4d3fbb2', - usage: 'Write Text Record', - seeMore: 'Implemented by Public Resolver', - event: 'event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);', - }, - { - name: 'setABI(bytes32 node, uint256 contentType, bytes calldata data)', - interface: '0x623195b0', - usage: 'Write Contract ABI', - seeMore: 'Implemented by Public Resolver', - event: 'event ABIChanged(bytes32 indexed node, uint256 indexed contentType);', - }, - { - name: 'setPubkey(bytes32 node, bytes32 x, bytes32 y)', - interface: '0x29cd62ea', - usage: 'Write Public Key', - seeMore: 'Implemented by Public Resolver', - event: 'event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);', - }, - { - name: 'setName(bytes32 node, string calldata name)', - interface: '0x77372213', - usage: 'Write Name (for reverse records)', - seeMore: 'Implemented by Public Resolver', - event: 'event NameChanged(bytes32 indexed node, string name);', - }, - { - name: 'multicall(bytes[] calldata data) view returns (bytes[] memory results)', - interface: '0xac9650d8', - usage: 'Batch Read/Write', - seeMore: 'Implemented by Public Resolver', - }, -]; diff --git a/app/local/data/resolver.tsx b/app/local/data/resolver.tsx new file mode 100644 index 000000000..0054a1ae6 --- /dev/null +++ b/app/local/data/resolver.tsx @@ -0,0 +1,553 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import { CodeGroup } from '../content/prose/code/group/CodeGroup'; +import { ContractMethod } from './interfaces'; + +export const PUBLIC_RESOLVER_SUPPORTS = [ + // 'addr', + // 'addr.reverse', + // 'contenthash', + // 'contenthash.set', + // 'multicoin', + // 'multicoin.set', + // 'text', + // 'text.set', + // 'ABI', + // 'ABI.set', + // 'pubkey', + // 'pubkey.set', + // 'name', + // 'name.set', + // 'multicall', +]; + +export const resolver_methods: ContractMethod[] = [ + { + name: 'supportsInterface(bytes4 interfaceID) external pure returns (bool)', + interface: '0x01ffc9a7', + usage: 'Check Interface Support', + seeMore: 'EIP-165', + input: [ + { + name: 'interfaceID', + type: 'bytes4', + description: + 'The interface identifier, as specified in ERC-165', + }, + ], + output: [ + { + type: 'bool', + description: + 'True if the contract supports the specified interface.', + }, + ], + }, + { + name: 'addr(bytes32 node) view returns (address)', + interface: '0x3b3b57de', + usage: 'Read Ethereum Address', + seeMore: 'ENSIP-1 / EIP-137', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to query.', + }, + ], + output: [ + { + type: 'address', + description: + 'Ethereum address or the zero address if no address is set.', + }, + ], + }, + { + name: 'addr(bytes32 node, uint coinType) view returns (bytes memory)', + interface: '0xf1cb7e06', + usage: 'Read Multicoin Address', + seeMore: 'ENSIP-9 / EIP-2304', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to query.', + }, + { + name: 'coinType', + type: 'uint', + description: 'The ENSIP-9 coin type to query.', + }, + ], + output: [ + { + type: 'bytes', + description: + 'Cryptocurrency address in its native binary format. For example, the Bitcoin address `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` base58check decodes to the 21 bytes `0062e907b15cbf27d5425399ebf6f0fb50ebb88f18` then scriptPubkey encodes to 25 bytes `76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac` whereas the BNB address `bnb1grpf0955h0ykzq3ar5nmum7y6gdfl6lxfn46h2` Bech32 decodes to the binary representation `40c2979694bbc961023d1d27be6fc4d21a9febe6`. A zero-length string ("") will be returned if the specified coin type is not set.', + }, + ], + }, + { + name: 'contenthash(bytes32 node) view returns (bytes memory)', + interface: '0xbc1c58d1', + usage: 'Read Content Hash', + seeMore: 'ENSIP-7 / EIP-1577', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to query.', + }, + ], + output: [ + { + type: 'bytes', + description: + 'The contenthash set for the name, encoded in binary format.', + }, + ], + }, + { + name: 'text(bytes32 node, string key) view returns (string memory)', + interface: '0x59d1d43c', + usage: 'Read Text Record', + seeMore: 'ENSIP-5 / EIP-634', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to query.', + }, + { + name: 'key', + type: 'string', + description: 'The text data key to query.', + }, + ], + output: [ + { + type: 'string', + description: + 'The value of the text record associated with key, or the empty string if no such record exists.', + }, + ], + }, + { + name: 'ABI(bytes32 node, uint256 contentTypes) view returns (uint256, bytes memory)', + interface: '0x2203ab56', + usage: 'Read Contract ABI', + seeMore: 'ENSIP-4 / EIP-205', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to query.', + }, + { + name: 'contentTypes', + type: 'uint256', + description: + 'A bitwise OR of the ABI formats accepted by the caller.', + }, + ], + output: [ + { + type: '(uint256, bytes)', + description: + 'ABI returns a two-tuple of the content type ID and the ABI data. If no data of the appropriate content type ID was found, 0 is returned for the content type ID, and the ABI data will be the empty string.', + }, + ], + }, + { + name: 'pubkey(bytes32 node) view returns (bytes32 x, bytes32 y)', + interface: '0xc8690233', + usage: 'Read Public Key', + seeMore: 'ENSIP- / EIP-619', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to query.', + }, + ], + output: [ + { + type: '(bytes32, bytes32)', + description: + 'The ECDSA SECP256k1 public key for node, as a 2-tuple (x, y). If no public key is set, (0, 0) is returned.', + }, + ], + }, + { + name: 'name(bytes32 node) view returns (string memory)', + interface: '0x691f3431', + usage: 'Read Name (for reverse records)', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to query.', + }, + ], + output: [ + { + type: 'string', + description: 'The associated name.', + }, + ], + }, + { + name: 'setAddr(bytes32 node, address a)', + interface: '0x3b3b57de', + usage: 'Write Ethereum Adress', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to update.', + }, + { + name: 'a', + type: 'address', + description: 'The Ethereum address to set.', + }, + ], + events: ['event AddrChanged(bytes32 indexed node, address a);'], + }, + { + name: 'setAddr(bytes32 node, uint coinType, bytes calldata a)', + interface: '0x8b95dd71', + usage: 'Set Multicoin Address', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to update.', + }, + { + name: 'coinType', + type: 'uint', + description: 'The ENSIP-9 coin type to update.', + }, + { + name: 'a', + type: 'bytes', + description: 'The address to set.', + }, + ], + events: [ + 'event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);', + ], + }, + { + name: 'setContenthash(bytes32 node, bytes calldata hash)', + interface: '0x304e6ade', + usage: 'Write Content Hash', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to update.', + }, + { + name: 'hash', + type: 'bytes', + description: 'The contenthash to set.', + }, + ], + events: ['event ContenthashChanged(bytes32 indexed node, bytes hash);'], + }, + { + name: 'setText(bytes32 node, string calldata key, string calldata value)', + interface: '0x10f13a8c', + usage: 'Write Text Record', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to update.', + }, + { + name: 'key', + type: 'string', + description: 'The key to set.', + }, + { + name: 'value', + type: 'string', + description: 'The text data value to set.', + }, + ], + events: [ + 'event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);', + ], + }, + { + name: 'setABI(bytes32 node, uint256 contentType, bytes calldata data)', + interface: '0x623195b0', + usage: 'Write Contract ABI', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to update.', + }, + { + name: 'contentType', + type: 'uint256', + description: 'The content type of the ABI.', + }, + { + name: 'data', + type: 'bytes', + description: 'The ABI data.', + }, + ], + events: [ + 'event ABIChanged(bytes32 indexed node, uint256 indexed contentType);', + ], + }, + { + name: 'setPubkey(bytes32 node, bytes32 x, bytes32 y)', + interface: '0x29cd62ea', + usage: 'Write Public Key', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to update.', + }, + { + name: 'x', + type: 'bytes32', + description: + 'The X coordinate of the curve point for the public key.', + }, + { + name: 'y', + type: 'bytes32', + description: + 'The Y coordinate of the curve point for the public key.', + }, + ], + events: [ + 'event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);', + ], + }, + { + name: 'setName(bytes32 node, string calldata name)', + interface: '0x77372213', + usage: 'Write Name (for reverse records)', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'node', + type: 'bytes32', + description: 'The ENS node to update.', + }, + { + name: 'name', + type: 'string', + description: 'The associated name.', + }, + ], + events: ['event NameChanged(bytes32 indexed node, string name);'], + }, + { + name: 'multicall(bytes[] calldata data) view returns (bytes[] memory results)', + interface: '0xac9650d8', + usage: 'Batch Read/Write', + seeMore: 'Implemented by Public Resolver', + input: [ + { + name: 'data', + type: 'bytes[]', + description: 'An array of ABI-encoded resolver function calls.', + }, + ], + output: [ + { + name: 'results', + type: 'bytes[]', + description: 'An array of data for each resolver call result.', + }, + ], + examples: [ + <> + Set two different text records: +
    +
  • name: myname.eth
  • +
  • key1: value1
  • +
  • key2: value2
  • +
+ The corresponding function call is:{' '} + + setText(bytes32 node, string calldata key, string calldata + value) + + . +
+ So the input parameters would be: +
    +
  • + node:{' '} + + 0x6cbc8d00d20a89e588f430e62b937a6402557bf0bc2127fb1378457331aa463d + +
  • +
  • + key: key1 +
  • +
  • + value: value1 +
  • +
+ Therefore the ABI-encoded call (for key1/value1) would be: + + <> +

0x10f13a8c

+

+ 6cbc8d00d20a89e588f430e62b937a6402557bf0bc2127fb1378457331aa463d +

+

+ 0000000000000000000000000000000000000000000000000000000000000060 +

+

+ 00000000000000000000000000000000000000000000000000000000000000a0 +

+

+ 0000000000000000000000000000000000000000000000000000000000000004 +

+

+ 6b65793100000000000000000000000000000000000000000000000000000000 +

+

+ 0000000000000000000000000000000000000000000000000000000000000006 +

+

+ 76616c7565310000000000000000000000000000000000000000000000000000 +

+ +
+ The second the ABI-encoded call (for key2/value2) would be very + similar: + + <> +

0x10f13a8c

+

+ 6cbc8d00d20a89e588f430e62b937a6402557bf0bc2127fb1378457331aa463d +

+

+ 0000000000000000000000000000000000000000000000000000000000000060 +

+

+ 00000000000000000000000000000000000000000000000000000000000000a0 +

+

+ 0000000000000000000000000000000000000000000000000000000000000004 +

+

+ 6b65793200000000000000000000000000000000000000000000000000000000 +

+

+ 0000000000000000000000000000000000000000000000000000000000000006 +

+

+ 76616c7565320000000000000000000000000000000000000000000000000000 +

+ +
+ Both of those byte arrays would be passed into the + two-dimensional bytes[] input parameter. +
+ The full ABI-encoded multicall call would therefore be (with + proper padding): + + <> +

0xac9650d8

+

+ 0000000000000000000000000000000000000000000000000000000000000020 +

+

+ 0000000000000000000000000000000000000000000000000000000000000002 +

+

+ 0000000000000000000000000000000000000000000000000000000000000040 +

+

+ 0000000000000000000000000000000000000000000000000000000000000160 +

+
+

+ 00000000000000000000000000000000000000000000000000000000000000e4 +

+
+

10f13a8c

+

+ 6cbc8d00d20a89e588f430e62b937a6402557bf0bc2127fb1378457331aa463d +

+

+ 0000000000000000000000000000000000000000000000000000000000000060 +

+

+ 00000000000000000000000000000000000000000000000000000000000000a0 +

+

+ 0000000000000000000000000000000000000000000000000000000000000004 +

+

+ 6b65793100000000000000000000000000000000000000000000000000000000 +

+

+ 0000000000000000000000000000000000000000000000000000000000000006 +

+

+ 76616c7565310000000000000000000000000000000000000000000000000000 +

+

+ 00000000000000000000000000000000000000000000000000000000 +

+
+

+ 00000000000000000000000000000000000000000000000000000000000000e4 +

+
+

10f13a8c

+

+ 6cbc8d00d20a89e588f430e62b937a6402557bf0bc2127fb1378457331aa463d +

+

+ 0000000000000000000000000000000000000000000000000000000000000060 +

+

+ 00000000000000000000000000000000000000000000000000000000000000a0 +

+

+ 0000000000000000000000000000000000000000000000000000000000000004 +

+

+ 6b65793200000000000000000000000000000000000000000000000000000000 +

+

+ 0000000000000000000000000000000000000000000000000000000000000006 +

+

+ 76616c7565320000000000000000000000000000000000000000000000000000 +

+
+

+ 00000000000000000000000000000000000000000000000000000000 +

+ +
+ , + ], + }, +]; diff --git a/docs/resolvers/interfaces.mdx b/docs/resolvers/interfaces.mdx index 2004c7748..a7575a1d3 100644 --- a/docs/resolvers/interfaces.mdx +++ b/docs/resolvers/interfaces.mdx @@ -1,4 +1,5 @@ import { WIP } from "@/components/wip/WIP"; +import { interfaceDetails } from "#/data/interfaces"; import { resolver_methods } from "#/data/resolver"; import { h2, h3, h4 } from '@/components/mdx/heading/h2'; @@ -9,59 +10,8 @@ export const meta = { contributors: [] }; -export const methods = resolver_methods; +# Resolver Interface Standards -# Interface Standards +This page is a collection of methods that a resolver MAY implement. -This page is a collection of methods that a resolver MAY implement - - - - - - - - - - {methods.map((method) => { - return ( - - - - - ); - })} - -
UsageInterface ID
- {method.usage} - {method.name}
- -## Check Interface Support - -``` -function supportsInterface(bytes4 interfaceID) external pure returns (bool) -``` - -{ - methods.map((method) => { - return ( -
-

{method.usage}

- - {method.name} - -

- Interface ID is - {method.interface} -

- {method.seeMore} - {method.output && ( - <> -

Outputs

-

{method.output}

- - )} -
- ); - }) -} \ No newline at end of file +{interfaceDetails(resolver_methods)} \ No newline at end of file