From 11458ba964735b1d2e720568e8771aba68ae038b Mon Sep 17 00:00:00 2001 From: "Serenae.eth" Date: Thu, 8 Aug 2024 14:34:05 -0400 Subject: [PATCH 1/2] Expanding contract interfaces template, filled out for resolver page --- app/local/data/interfaces.tsx | 135 +++++++++++ app/local/data/resolver.ts | 134 ----------- app/local/data/resolver.tsx | 429 ++++++++++++++++++++++++++++++++++ docs/resolvers/interfaces.mdx | 58 +---- 4 files changed, 568 insertions(+), 188 deletions(-) create mode 100644 app/local/data/interfaces.tsx delete mode 100644 app/local/data/resolver.ts create mode 100644 app/local/data/resolver.tsx diff --git a/app/local/data/interfaces.tsx b/app/local/data/interfaces.tsx new file mode 100644 index 000000000..0ffe90eaf --- /dev/null +++ b/app/local/data/interfaces.tsx @@ -0,0 +1,135 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import { CodeGroup } from "../content/prose/code/group/CodeGroup"; + +export type ContractParam = { + 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(str: string) { + return str.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(str: string) { + if (str && str.indexOf('`') >= 0) { + return str.split(/(`[^`]+`).*?/g).map((part) => { + if (/`[^`]+`/.test(part)) { + return ( + {part.substring(1, part.length - 1)} + ) + } else { + return part + } + }) + } else { + return str || '' + } +} \ No newline at end of file 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..3a9abbbab --- /dev/null +++ b/app/local/data/resolver.tsx @@ -0,0 +1,429 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import { ContractMethod } from "./interfaces"; +import { CodeGroup } from "../content/prose/code/group/CodeGroup"; + +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 From 41ac72a84aff102e3f8849b9108e40cc3ae7a343 Mon Sep 17 00:00:00 2001 From: "Serenae.eth" Date: Thu, 8 Aug 2024 15:17:32 -0400 Subject: [PATCH 2/2] Linted files --- app/local/data/interfaces.tsx | 297 +++++++++++---------- app/local/data/resolver.tsx | 472 +++++++++++++++++++++------------- 2 files changed, 460 insertions(+), 309 deletions(-) diff --git a/app/local/data/interfaces.tsx b/app/local/data/interfaces.tsx index 0ffe90eaf..75528225d 100644 --- a/app/local/data/interfaces.tsx +++ b/app/local/data/interfaces.tsx @@ -1,135 +1,162 @@ -/* eslint-disable sonarjs/no-duplicate-string */ -import { CodeGroup } from "../content/prose/code/group/CodeGroup"; - -export type ContractParam = { - 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(str: string) { - return str.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(str: string) { - if (str && str.indexOf('`') >= 0) { - return str.split(/(`[^`]+`).*?/g).map((part) => { - if (/`[^`]+`/.test(part)) { - return ( - {part.substring(1, part.length - 1)} - ) - } else { - return part - } - }) - } else { - return str || '' - } -} \ No newline at end of file +/* 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.tsx b/app/local/data/resolver.tsx index 3a9abbbab..0054a1ae6 100644 --- a/app/local/data/resolver.tsx +++ b/app/local/data/resolver.tsx @@ -1,6 +1,6 @@ /* eslint-disable sonarjs/no-duplicate-string */ -import { ContractMethod } from "./interfaces"; -import { CodeGroup } from "../content/prose/code/group/CodeGroup"; +import { CodeGroup } from '../content/prose/code/group/CodeGroup'; +import { ContractMethod } from './interfaces'; export const PUBLIC_RESOLVER_SUPPORTS = [ // 'addr', @@ -30,13 +30,17 @@ export const resolver_methods: ContractMethod[] = [ { name: 'interfaceID', type: 'bytes4', - description: 'The interface identifier, as specified in ERC-165' - } + description: + 'The interface identifier, as specified in ERC-165', + }, + ], + output: [ + { + type: 'bool', + description: + 'True if the contract supports the specified interface.', + }, ], - output: [{ - type: 'bool', - description: 'True if the contract supports the specified interface.' - }] }, { name: 'addr(bytes32 node) view returns (address)', @@ -47,13 +51,16 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to query.' - } + description: 'The ENS node to query.', + }, + ], + output: [ + { + type: 'address', + description: + 'Ethereum address or the zero address if no address is set.', + }, ], - 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)', @@ -64,18 +71,21 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to query.' + description: 'The ENS node to query.', }, { name: 'coinType', type: 'uint', - description: 'The ENSIP-9 coin type to query.' - } + 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.', + }, ], - 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)', @@ -86,13 +96,16 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to query.' - } + description: 'The ENS node to query.', + }, + ], + output: [ + { + type: 'bytes', + description: + 'The contenthash set for the name, encoded in binary format.', + }, ], - output: [{ - type: 'bytes', - description: 'The contenthash set for the name, encoded in binary format.' - }] }, { name: 'text(bytes32 node, string key) view returns (string memory)', @@ -103,18 +116,21 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to query.' + description: 'The ENS node to query.', }, { name: 'key', type: 'string', - description: 'The text data key to query.' - } + 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.', + }, ], - 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)', @@ -125,18 +141,22 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to query.' + description: 'The ENS node to query.', }, { name: 'contentTypes', type: 'uint256', - description: 'A bitwise OR of the ABI formats accepted by the caller.' - } + 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.', + }, ], - 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)', @@ -147,13 +167,16 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to query.' - } + 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.', + }, ], - 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)', @@ -164,13 +187,15 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to query.' - } + description: 'The ENS node to query.', + }, + ], + output: [ + { + type: 'string', + description: 'The associated name.', + }, ], - output: [{ - type: 'string', - description: 'The associated name.' - }] }, { name: 'setAddr(bytes32 node, address a)', @@ -181,15 +206,15 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to update.' + description: 'The ENS node to update.', }, { name: 'a', type: 'address', - description: 'The Ethereum address to set.' - } + description: 'The Ethereum address to set.', + }, ], - events: ['event AddrChanged(bytes32 indexed node, address a);'] + events: ['event AddrChanged(bytes32 indexed node, address a);'], }, { name: 'setAddr(bytes32 node, uint coinType, bytes calldata a)', @@ -200,20 +225,22 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to update.' + description: 'The ENS node to update.', }, { name: 'coinType', type: 'uint', - description: 'The ENSIP-9 coin type to update.' + description: 'The ENSIP-9 coin type to update.', }, { name: 'a', type: 'bytes', - description: 'The address to set.' - } + description: 'The address to set.', + }, + ], + events: [ + 'event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);', ], - events: ['event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);'] }, { name: 'setContenthash(bytes32 node, bytes calldata hash)', @@ -224,15 +251,15 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to update.' + description: 'The ENS node to update.', }, { name: 'hash', type: 'bytes', - description: 'The contenthash to set.' - } + description: 'The contenthash to set.', + }, ], - events: ['event ContenthashChanged(bytes32 indexed node, bytes hash);'] + events: ['event ContenthashChanged(bytes32 indexed node, bytes hash);'], }, { name: 'setText(bytes32 node, string calldata key, string calldata value)', @@ -243,20 +270,22 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to update.' + description: 'The ENS node to update.', }, { name: 'key', type: 'string', - description: 'The key to set.' + description: 'The key to set.', }, { name: 'value', type: 'string', - description: 'The text data value to set.' - } + description: 'The text data value to set.', + }, + ], + events: [ + 'event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);', ], - events: ['event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);'] }, { name: 'setABI(bytes32 node, uint256 contentType, bytes calldata data)', @@ -267,20 +296,22 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to update.' + description: 'The ENS node to update.', }, { name: 'contentType', type: 'uint256', - description: 'The content type of the ABI.' + description: 'The content type of the ABI.', }, { name: 'data', type: 'bytes', - description: 'The ABI data.' - } + description: 'The ABI data.', + }, + ], + events: [ + 'event ABIChanged(bytes32 indexed node, uint256 indexed contentType);', ], - events: ['event ABIChanged(bytes32 indexed node, uint256 indexed contentType);'] }, { name: 'setPubkey(bytes32 node, bytes32 x, bytes32 y)', @@ -291,20 +322,24 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to update.' + description: 'The ENS node to update.', }, { name: 'x', type: 'bytes32', - description: 'The X coordinate of the curve point for the public key.' + 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.' - } + description: + 'The Y coordinate of the curve point for the public key.', + }, + ], + events: [ + 'event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);', ], - events: ['event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);'] }, { name: 'setName(bytes32 node, string calldata name)', @@ -315,15 +350,15 @@ export const resolver_methods: ContractMethod[] = [ { name: 'node', type: 'bytes32', - description: 'The ENS node to update.' + description: 'The ENS node to update.', }, { name: 'name', type: 'string', - description: 'The associated name.' - } + description: 'The associated name.', + }, ], - events: ['event NameChanged(bytes32 indexed node, string name);'] + events: ['event NameChanged(bytes32 indexed node, string name);'], }, { name: 'multicall(bytes[] calldata data) view returns (bytes[] memory results)', @@ -334,96 +369,185 @@ export const resolver_methods: ContractMethod[] = [ { name: 'data', type: 'bytes[]', - description: 'An array of ABI-encoded resolver function calls.' - } + description: 'An array of ABI-encoded resolver function calls.', + }, + ], + output: [ + { + name: 'results', + type: 'bytes[]', + description: 'An array of data for each resolver call result.', + }, ], - 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

- -
- - ) - ] + <> + 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 +

+ +
+ , + ], }, ];