From 69aa210d7f3f27fd6c7d3af36a36af6bdb9ddc88 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Tue, 8 Oct 2024 08:42:38 -0300 Subject: [PATCH 01/17] refactor: add parentNode to register --- packages/client/src/client.ts | 14 ++- packages/client/src/l2.write.ts | 89 ++++++++++--------- .../script/local/L2ArbitrumResolver.sol | 1 + packages/contracts/src/L1Resolver.sol | 10 ++- .../contracts/src/SubdomainController.sol | 14 +-- .../src/interfaces/OffchainResolver.sol | 10 ++- 6 files changed, 81 insertions(+), 57 deletions(-) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 15501493..7d39f104 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -73,7 +73,7 @@ export async function handleDBStorage({ }) } -export function getChain(chainId: number) { +export function getChain(chainId: number): chains.Chain | undefined { return [ ...Object.values(chains), defineChain({ @@ -92,3 +92,15 @@ export function getChain(chainId: number) { }), ].find((chain) => chain.id === chainId) } + +// gather the first part of the domain (e.g. floripa.blockful.eth -> floripa) +export function extractLabelFromName(name: string): string { + const [, label] = /^(\w+)/.exec(name) || [] + return label +} + +// gather the last part of the domain (e.g. floripa.blockful.eth -> blockful.eth) +export function extractParentFromName(name: string): string { + const [, parent] = /\w*\.(.*)$/.exec(name) || [] + return parent +} diff --git a/packages/client/src/l2.write.ts b/packages/client/src/l2.write.ts index 8f855bbd..90e7e4ed 100644 --- a/packages/client/src/l2.write.ts +++ b/packages/client/src/l2.write.ts @@ -20,15 +20,20 @@ import { privateKeyToAccount } from 'viem/accounts' import { abi as uAbi } from '@blockful/contracts/out/UniversalResolver.sol/UniversalResolver.json' import { abi as l1Abi } from '@blockful/contracts/out/L1Resolver.sol/L1Resolver.json' -import { getRevertErrorData, getChain } from './client' +import { + getRevertErrorData, + getChain, + extractLabelFromName, + extractParentFromName, +} from './client' config({ path: process.env.ENV_FILE || '../.env', }) let { - UNIVERSAL_RESOLVER_ADDRESS: resolver, - L2_RESOLVER_ADDRESS: l2Resolver, + UNIVERSAL_RESOLVER_ADDRESS: universalResolver, + RESOLVER_ADDRESS: resolver, CHAIN_ID: chainId = '31337', RPC_URL: provider = 'http://127.0.0.1:8545/', L2_RPC_URL: providerL2 = 'http://127.0.0.1:8547', @@ -37,38 +42,40 @@ let { } = process.env const chain = getChain(parseInt(chainId)) -console.log(`Connecting to ${chain?.name}.`) +if (!chain) { + throw new Error('Chain not found') +} const client = createPublicClient({ chain, transport: http(provider), }).extend(walletActions) +console.log(`Connecting to ${chain?.name}.`) // eslint-disable-next-line const _ = (async () => { - if (!l2Resolver) { - throw new Error('L2_RESOLVER_ADDRESS is required') + if (!resolver) { + throw new Error('RESOLVER_ADDRESS is required') } - const publicAddress = normalize('lucas.arb.eth') - const node = namehash(publicAddress) + const name = normalize('gibi.blockful.eth') + const node = namehash(name) const signer = privateKeyToAccount(privateKey as Hex) - if (!resolver) { - resolver = getChainContractAddress({ + if (!universalResolver) { + universalResolver = getChainContractAddress({ chain: client.chain, contract: 'ensUniversalResolver', }) } const [resolverAddr] = (await client.readContract({ - address: resolver as Hex, + address: universalResolver as Hex, functionName: 'findResolver', abi: uAbi, - args: [toHex(packetToBytes(publicAddress))], + args: [toHex(packetToBytes(name))], })) as Hash[] - const name = extractLabelFromName(publicAddress) const duration = 31556952000n // SUBDOMAIN PRICING @@ -105,13 +112,14 @@ const _ = (async () => { functionName: 'register', abi: l1Abi, args: [ - name, + namehash(extractParentFromName(name)), // parent + extractLabelFromName(name), // label signer.address, // owner duration, `0x${'a'.repeat(64)}` as Hex, // secret - l2Resolver, // resolver - data, // calldata - false, // primaryName + resolver, + data, // records calldata + false, // reverseRecord 0, // fuses `0x${'a'.repeat(64)}` as Hex, // extraData ], @@ -124,33 +132,28 @@ const _ = (async () => { await client.simulateContract(calldata) } catch (err) { const data = getRevertErrorData(err) - if (data?.errorName === 'StorageHandledByL2') { - const [chainId, contractAddress] = data.args as [bigint, `0x${string}`] - - const l2Client = createPublicClient({ - chain: getChain(Number(chainId)), - transport: http(providerL2), - }).extend(walletActions) - - try { - const { request } = await l2Client.simulateContract({ - ...calldata, - address: contractAddress, - }) - await l2Client.writeContract(request) - } catch (err) { - console.log('error while trying to make the request: ', { err }) + switch (data?.errorName) { + case 'StorageHandledByL2': { + const [chainId, contractAddress] = data.args as [bigint, `0x${string}`] + + const l2Client = createPublicClient({ + chain: getChain(Number(chainId)), + transport: http(providerL2), + }).extend(walletActions) + + try { + const { request } = await l2Client.simulateContract({ + ...calldata, + address: contractAddress, + }) + await l2Client.writeContract(request) + } catch (err) { + console.log('error while trying to make the request: ', { err }) + } + return } - } else if (data) { - console.error('error registering domain: ', data.errorName) - } else { - console.error('error registering domain: ', { err }) + default: + console.error('error registering domain: ', { err }) } } })() - -// gather the first part of the domain (e.g. floripa.blockful.eth -> floripa) -function extractLabelFromName(name: string): string { - const [, label] = /^(\w+)/.exec(name) || [] - return label -} diff --git a/packages/contracts/script/local/L2ArbitrumResolver.sol b/packages/contracts/script/local/L2ArbitrumResolver.sol index 69b69904..5f754aaf 100644 --- a/packages/contracts/script/local/L2ArbitrumResolver.sol +++ b/packages/contracts/script/local/L2ArbitrumResolver.sol @@ -110,6 +110,7 @@ contract L2ArbitrumResolver is Script, ENSHelper { "@blockful" ); subdomainController.register{value: subdomainController.price()}( + namehash("arb.eth"), "blockful", msg.sender, 31556952000, diff --git a/packages/contracts/src/L1Resolver.sol b/packages/contracts/src/L1Resolver.sol index d2e1b043..a47b3c44 100644 --- a/packages/contracts/src/L1Resolver.sol +++ b/packages/contracts/src/L1Resolver.sol @@ -103,16 +103,20 @@ contract L1Resolver is /** * Forwards the registering of a subdomain to the L2 contracts - * @param -name The DNS-encoded name to resolve. + * @param -parentNode namehash of the parent node + * @param -label The name to be registered. * @param -owner Owner of the domain * @param -duration duration The duration in seconds of the registration. + * @param -secret The secret to be used for the registration based on commit/reveal * @param -resolver The address of the resolver to set for this name. * @param -data Multicallable data bytes for setting records in the associated resolver upon reigstration. + * @param -reverseRecord Whether this name is the primary name * @param -fuses The fuses to set for this name. * @param -extraData any encoded additional data */ function register( - string calldata, /* name */ + bytes32, /* parentNode */ + string calldata, /* label */ address, /* owner */ uint256, /* duration */ bytes32, /* secret */ @@ -137,7 +141,7 @@ contract L1Resolver is * @return extraData any given structure in an ABI encoded format */ function registerParams( - bytes memory, /* name */ + bytes calldata, /* name */ uint256 /* duration */ ) external diff --git a/packages/contracts/src/SubdomainController.sol b/packages/contracts/src/SubdomainController.sol index 87e22e76..66bc7b80 100644 --- a/packages/contracts/src/SubdomainController.sol +++ b/packages/contracts/src/SubdomainController.sol @@ -27,9 +27,10 @@ contract SubdomainController is OffchainRegister, ENSHelper { } function register( - string calldata name, + bytes32 parentNode, + string calldata label, address owner, - uint256 duration, + uint256 duration, bytes32, /* secret */ address resolver, bytes[] calldata data, @@ -41,21 +42,20 @@ contract SubdomainController is OffchainRegister, ENSHelper { payable override { - bytes32 nodehash = - keccak256(abi.encodePacked(baseNode, labelhash(name))); + bytes32 node = keccak256(abi.encodePacked(parentNode, labelhash(label))); require( - nameWrapper.ownerOf(uint256(nodehash)) == address(0), + nameWrapper.ownerOf(uint256(node)) == address(0), "domain already registered" ); require(msg.value >= price, "insufficient funds"); nameWrapper.setSubnodeRecord( - baseNode, name, owner, resolver, 0, fuses, uint64(duration) + parentNode, label, owner, resolver, 0, fuses, uint64(duration) ); if (data.length > 0) { - Resolver(resolver).multicallWithNodeCheck(nodehash, data); + Resolver(resolver).multicallWithNodeCheck(node, data); } } diff --git a/packages/contracts/src/interfaces/OffchainResolver.sol b/packages/contracts/src/interfaces/OffchainResolver.sol index c9768e2e..d1172492 100644 --- a/packages/contracts/src/interfaces/OffchainResolver.sol +++ b/packages/contracts/src/interfaces/OffchainResolver.sol @@ -5,16 +5,20 @@ interface OffchainRegister { /** * Forwards the registering of a domain to the L2 contracts - * @param name The DNS-encoded name to resolve. + * @param parentNode namehash of the parent node + * @param label The name to be registered. * @param owner Owner of the domain * @param duration duration The duration in seconds of the registration. + * @param secret The secret to be used for the registration based on commit/reveal * @param resolver The address of the resolver to set for this name. * @param data Multicallable data bytes for setting records in the associated resolver upon reigstration. + * @param reverseRecord Whether this name is the primary name * @param fuses The fuses to set for this name. * @param extraData any encoded additional data */ function register( - string calldata name, + bytes32 parentNode, + string calldata label, address owner, uint256 duration, bytes32 secret, @@ -40,7 +44,7 @@ interface OffchainRegisterParams { * @return extraData any given structure in an ABI encoded format */ function registerParams( - bytes memory name, + bytes calldata name, uint256 duration ) external From 526ac30e8ba4aa6a15229dfd69f423812f4fd1c0 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Tue, 8 Oct 2024 08:45:09 -0300 Subject: [PATCH 02/17] chore: update ensip register docs --- ensips/ccip-write/ccip-write.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ensips/ccip-write/ccip-write.md b/ensips/ccip-write/ccip-write.md index 68e5fb72..a4b4db2a 100644 --- a/ensips/ccip-write/ccip-write.md +++ b/ensips/ccip-write/ccip-write.md @@ -47,7 +47,7 @@ The function has the following signature: ```solidity function registerParams( - bytes memory name, + bytes calldata name, uint256 duration ) external @@ -89,7 +89,8 @@ Aiming to integrate with the already existing interface of domain registration, ```solidity function register( - string calldata name, + bytes32 parentNode, + string calldata label, address owner, uint256 duration, bytes32 secret, @@ -103,7 +104,8 @@ function register( Parameters: -- `name`: DNS-encoded name to be registered +- `parentNode`: namehash of the parent domain +- `label`: DNS-encoded name to be registered - `owner`: subdomain owner's address - `duration`: the duration in miliseconds of the registration - `secret`: random seed to be used for commit/reveal @@ -278,7 +280,8 @@ interface OffchainRegister { /** * Forwards the registering of a domain to the L2 contracts - * @param name The DNS-encoded name to resolve. + * @param parentNode namehash of the parent domain + * @param label The DNS-encoded name to resolve. * @param owner Owner of the domain * @param duration duration The duration in seconds of the registration. * @param resolver The address of the resolver to set for this name. @@ -287,7 +290,8 @@ interface OffchainRegister { * @param extraData any encoded additional data */ function register( - string calldata name, + bytes32 parentNode, + string calldata label, address owner, uint256 duration, bytes32 secret, @@ -336,10 +340,10 @@ interface OffchainMulticallable { interface OffchainCommitable { - /** - * @notice produces the commit hash from the register calldata - * @returns the hash of the commit to be used - */ + /** + * @notice produces the commit hash from the register calldata + * @returns the hash of the commit to be used + */ function makeCommitment( string calldata name, address owner, From 6514a6dc8f6c12d7b33b23078454e59871bd6a3e Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Tue, 8 Oct 2024 13:18:40 -0300 Subject: [PATCH 03/17] chore: remove baseNode from subdomainController --- packages/contracts/script/deploy/SubdomainController.sol | 3 ++- packages/contracts/script/local/L2ArbitrumResolver.sol | 1 - packages/contracts/src/SubdomainController.sol | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/contracts/script/deploy/SubdomainController.sol b/packages/contracts/script/deploy/SubdomainController.sol index 7b114fb3..09ba5906 100644 --- a/packages/contracts/script/deploy/SubdomainController.sol +++ b/packages/contracts/script/deploy/SubdomainController.sol @@ -18,8 +18,9 @@ contract SubdomainControllerScript is DeployHelper, ENSHelper { vm.startBroadcast(); uint256 subdomainPrice = 0.001 ether; + uint256 commitTime = 0; SubdomainController subdomainController = new SubdomainController( - namehash("arb.eth"), address(nameWrapper), subdomainPrice, 0 + address(nameWrapper), subdomainPrice, commitTime ); nameWrapper.setApprovalForAll(address(subdomainController), true); diff --git a/packages/contracts/script/local/L2ArbitrumResolver.sol b/packages/contracts/script/local/L2ArbitrumResolver.sol index 5f754aaf..ffba08cc 100644 --- a/packages/contracts/script/local/L2ArbitrumResolver.sol +++ b/packages/contracts/script/local/L2ArbitrumResolver.sol @@ -81,7 +81,6 @@ contract L2ArbitrumResolver is Script, ENSHelper { uint256 subdomainPrice = 0.001 ether; uint256 commitTime = 0; SubdomainController subdomainController = new SubdomainController( - namehash("arb.eth"), address(nameWrapper), subdomainPrice, commitTime diff --git a/packages/contracts/src/SubdomainController.sol b/packages/contracts/src/SubdomainController.sol index 66bc7b80..b9618cbf 100644 --- a/packages/contracts/src/SubdomainController.sol +++ b/packages/contracts/src/SubdomainController.sol @@ -11,17 +11,14 @@ contract SubdomainController is OffchainRegister, ENSHelper { uint256 public price; uint256 public commitTime; - bytes32 public baseNode; INameWrapper nameWrapper; constructor( - bytes32 _baseNode, address _nameWrapperAddress, uint256 _price, uint256 _commitTime ) { commitTime = _commitTime; - baseNode = _baseNode; price = _price; nameWrapper = INameWrapper(_nameWrapperAddress); } From ad4c037d475abc50da713add9e88964cc0658cb0 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Wed, 9 Oct 2024 11:01:28 -0300 Subject: [PATCH 04/17] refactor: register receiving name dns-encoded --- packages/client/src/l2.write.ts | 12 +- .../script/local/L2ArbitrumResolver.sol | 17 +- packages/contracts/src/L1Resolver.sol | 6 +- .../contracts/src/SubdomainController.sol | 48 +++- .../src/interfaces/OffchainResolver.sol | 6 +- .../contracts/test/SubdomainController.t.sol | 254 ++++++++++++++++++ 6 files changed, 313 insertions(+), 30 deletions(-) create mode 100644 packages/contracts/test/SubdomainController.t.sol diff --git a/packages/client/src/l2.write.ts b/packages/client/src/l2.write.ts index 90e7e4ed..ec117d1f 100644 --- a/packages/client/src/l2.write.ts +++ b/packages/client/src/l2.write.ts @@ -20,12 +20,7 @@ import { privateKeyToAccount } from 'viem/accounts' import { abi as uAbi } from '@blockful/contracts/out/UniversalResolver.sol/UniversalResolver.json' import { abi as l1Abi } from '@blockful/contracts/out/L1Resolver.sol/L1Resolver.json' -import { - getRevertErrorData, - getChain, - extractLabelFromName, - extractParentFromName, -} from './client' +import { getRevertErrorData, getChain } from './client' config({ path: process.env.ENV_FILE || '../.env', @@ -58,7 +53,7 @@ const _ = (async () => { throw new Error('RESOLVER_ADDRESS is required') } - const name = normalize('gibi.blockful.eth') + const name = normalize('gibi.arb.eth') const node = namehash(name) const signer = privateKeyToAccount(privateKey as Hex) @@ -112,8 +107,7 @@ const _ = (async () => { functionName: 'register', abi: l1Abi, args: [ - namehash(extractParentFromName(name)), // parent - extractLabelFromName(name), // label + toHex(name), // name signer.address, // owner duration, `0x${'a'.repeat(64)}` as Hex, // secret diff --git a/packages/contracts/script/local/L2ArbitrumResolver.sol b/packages/contracts/script/local/L2ArbitrumResolver.sol index ffba08cc..0323e020 100644 --- a/packages/contracts/script/local/L2ArbitrumResolver.sol +++ b/packages/contracts/script/local/L2ArbitrumResolver.sol @@ -21,6 +21,7 @@ import {StaticMetadataService} from "@ens-contracts/wrapper/StaticMetadataService.sol"; import {IMetadataService} from "@ens-contracts/wrapper/IMetadataService.sol"; import {PublicResolver} from "@ens-contracts/resolvers/PublicResolver.sol"; +import {NameEncoder} from "@ens-contracts/utils/NameEncoder.sol"; import {ENSHelper} from "../ENSHelper.sol"; import {SubdomainController} from "../../src/SubdomainController.sol"; @@ -81,9 +82,7 @@ contract L2ArbitrumResolver is Script, ENSHelper { uint256 subdomainPrice = 0.001 ether; uint256 commitTime = 0; SubdomainController subdomainController = new SubdomainController( - address(nameWrapper), - subdomainPrice, - commitTime + address(nameWrapper), subdomainPrice, commitTime ); nameWrapper.setApprovalForAll(address(subdomainController), true); @@ -101,16 +100,16 @@ contract L2ArbitrumResolver is Script, ENSHelper { "arb", msg.sender, 31556952000, address(arbResolver), 1 ); + (bytes memory name, bytes32 node) = + NameEncoder.dnsEncodeName("blockful.arb.eth"); + bytes[] memory data = new bytes[](1); data[0] = abi.encodeWithSelector( - TextResolver.setText.selector, - namehash("blockful.arb.eth"), - "com.twitter", - "@blockful" + TextResolver.setText.selector, node, "com.twitter", "@blockful" ); + subdomainController.register{value: subdomainController.price()}( - namehash("arb.eth"), - "blockful", + name, msg.sender, 31556952000, keccak256("secret"), diff --git a/packages/contracts/src/L1Resolver.sol b/packages/contracts/src/L1Resolver.sol index a47b3c44..dbd5de52 100644 --- a/packages/contracts/src/L1Resolver.sol +++ b/packages/contracts/src/L1Resolver.sol @@ -103,8 +103,7 @@ contract L1Resolver is /** * Forwards the registering of a subdomain to the L2 contracts - * @param -parentNode namehash of the parent node - * @param -label The name to be registered. + * @param -name The DNS-encoded name to be registered. * @param -owner Owner of the domain * @param -duration duration The duration in seconds of the registration. * @param -secret The secret to be used for the registration based on commit/reveal @@ -115,8 +114,7 @@ contract L1Resolver is * @param -extraData any encoded additional data */ function register( - bytes32, /* parentNode */ - string calldata, /* label */ + bytes calldata, /* name */ address, /* owner */ uint256, /* duration */ bytes32, /* secret */ diff --git a/packages/contracts/src/SubdomainController.sol b/packages/contracts/src/SubdomainController.sol index b9618cbf..9c84d10f 100644 --- a/packages/contracts/src/SubdomainController.sol +++ b/packages/contracts/src/SubdomainController.sol @@ -1,14 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; +import "forge-std/console.sol"; + import {INameWrapper} from "@ens-contracts/wrapper/INameWrapper.sol"; import {Resolver} from "@ens-contracts/resolvers/Resolver.sol"; +import {BytesUtils} from "@ens-contracts/utils/BytesUtils.sol"; import {ENSHelper} from "../script/ENSHelper.sol"; import {OffchainRegister} from "./interfaces/OffchainResolver.sol"; contract SubdomainController is OffchainRegister, ENSHelper { + using BytesUtils for bytes; + uint256 public price; uint256 public commitTime; INameWrapper nameWrapper; @@ -24,10 +29,9 @@ contract SubdomainController is OffchainRegister, ENSHelper { } function register( - bytes32 parentNode, - string calldata label, + bytes calldata name, address owner, - uint256 duration, + uint256 duration, bytes32, /* secret */ address resolver, bytes[] calldata data, @@ -39,7 +43,11 @@ contract SubdomainController is OffchainRegister, ENSHelper { payable override { - bytes32 node = keccak256(abi.encodePacked(parentNode, labelhash(label))); + bytes32 node = _getNode(name); + string memory label = _getLabel(name); + + (, uint256 offset) = name.readLabel(0); + bytes32 parentNode = name.namehash(offset); require( nameWrapper.ownerOf(uint256(node)) == address(0), @@ -56,4 +64,36 @@ contract SubdomainController is OffchainRegister, ENSHelper { } } + function _getNode(bytes memory name) private pure returns (bytes32 node) { + return _getNode(name, 0); + } + + function _getNode( + bytes memory name, + uint256 offset + ) + private + pure + returns (bytes32 node) + { + uint256 len = name.readUint8(offset); + node = bytes32(0); + if (len > 0) { + bytes32 label = name.keccak(offset + 1, len); + bytes32 parentNode = _getNode(name, offset + len + 1); + node = keccak256(abi.encodePacked(parentNode, label)); + } + return node; + } + + function _getLabel(bytes calldata name) + private + pure + returns (string memory) + { + uint256 labelLength = uint256(uint8(name[0])); + if (labelLength == 0) return ""; + return string(name[1:labelLength + 1]); + } + } diff --git a/packages/contracts/src/interfaces/OffchainResolver.sol b/packages/contracts/src/interfaces/OffchainResolver.sol index d1172492..ad25f463 100644 --- a/packages/contracts/src/interfaces/OffchainResolver.sol +++ b/packages/contracts/src/interfaces/OffchainResolver.sol @@ -5,8 +5,7 @@ interface OffchainRegister { /** * Forwards the registering of a domain to the L2 contracts - * @param parentNode namehash of the parent node - * @param label The name to be registered. + * @param name DNS-encoded name to be registered. * @param owner Owner of the domain * @param duration duration The duration in seconds of the registration. * @param secret The secret to be used for the registration based on commit/reveal @@ -17,8 +16,7 @@ interface OffchainRegister { * @param extraData any encoded additional data */ function register( - bytes32 parentNode, - string calldata label, + bytes calldata name, address owner, uint256 duration, bytes32 secret, diff --git a/packages/contracts/test/SubdomainController.t.sol b/packages/contracts/test/SubdomainController.t.sol new file mode 100644 index 00000000..91cd3255 --- /dev/null +++ b/packages/contracts/test/SubdomainController.t.sol @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import {Test, console} from "forge-std/Test.sol"; + +import {DummyOffchainResolver} from + "@ens-contracts/test/mocks/DummyOffchainResolver.sol"; +import {NameEncoder} from "@ens-contracts/utils/NameEncoder.sol"; +import {Multicallable} from "@ens-contracts/resolvers/Multicallable.sol"; + +import "../src/SubdomainController.sol"; +import {ENSHelper} from "../script/ENSHelper.sol"; + +contract DummyNameWrapper { + + mapping(bytes32 => address) public owners; + + function ownerOf(uint256 id) public view returns (address) { + return owners[bytes32(id)]; + } + + function setSubnodeRecord( + bytes32 parentNode, + string memory label, + address owner, + address, /* resolver */ + uint64, /* ttl */ + uint32, /* fuses */ + uint64 /* expiry */ + ) + public + returns (bytes32 node) + { + node = keccak256(abi.encodePacked(parentNode, keccak256(bytes(label)))); + owners[node] = owner; + return node; + } + +} + +contract DummyResolver is DummyOffchainResolver, Multicallable { + + mapping(bytes32 => mapping(string => string)) private records; + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(DummyOffchainResolver, Multicallable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + function setText( + bytes32 node, + string calldata key, + string calldata value + ) + external + { + records[node][key] = value; + } + + function text( + bytes32 node, + string calldata key + ) + external + view + returns (string memory) + { + return records[node][key]; + } + +} + +contract SubdomainControllerTest is Test, ENSHelper { + + SubdomainController public controller; + DummyNameWrapper public nameWrapper; + DummyResolver public resolver; + + uint256 constant PRICE = 0.1 ether; + uint256 constant COMMIT_TIME = 1 days; + + function setUp() public { + nameWrapper = new DummyNameWrapper(); + resolver = new DummyResolver(); + controller = + new SubdomainController(address(nameWrapper), PRICE, COMMIT_TIME); + } + + function testRegister() public { + (bytes memory name, bytes32 node) = + NameEncoder.dnsEncodeName("newdomain.blockful.eth"); + address owner = address(0x123); + uint256 duration = 365 days; + bytes32 secret = bytes32(0); + bytes[] memory data = new bytes[](0); + + vm.expectCall( + address(nameWrapper), + abi.encodeWithSelector( + DummyNameWrapper.setSubnodeRecord.selector, + namehash("blockful.eth"), + "newdomain", + owner, + address(resolver), + 0, + 0, + duration + ) + ); + + vm.deal(address(this), PRICE); + controller.register{value: PRICE}( + name, + owner, + duration, + secret, + address(resolver), + data, + false, + 0, + abi.encode("") + ); + + assertEq( + nameWrapper.ownerOf(uint256(node)), + owner, + "Owner should be set correctly" + ); + } + + function testRegisterInsufficientFunds() public { + (bytes memory name,) = + NameEncoder.dnsEncodeName("newdomain.blockful.eth"); + address owner = address(0x123); + uint256 duration = 365 days; + bytes32 secret = bytes32(0); + bytes[] memory data = new bytes[](0); + + vm.expectRevert("insufficient funds"); + + controller.register{value: PRICE - 1}( + name, + owner, + duration, + secret, + address(resolver), + data, + false, + 0, + abi.encode("") + ); + } + + function testRegisterAlreadyRegistered() public { + (bytes memory name,) = + NameEncoder.dnsEncodeName("existingdomain.blockful.eth"); + address owner = address(0x123); + uint256 duration = 365 days; + bytes32 secret = bytes32(0); + bytes[] memory data = new bytes[](0); + + // Simulate that the domain is already registered + nameWrapper.setSubnodeRecord( + namehash("blockful.eth"), + "existingdomain", + owner, + address(0), + 0, + 0, + 0 + ); + + vm.expectRevert("domain already registered"); + + vm.deal(address(this), PRICE); + controller.register{value: PRICE}( + name, + owner, + duration, + secret, + address(resolver), + data, + false, + 0, + abi.encode("") + ); + } + + function testRegisterWithResolverData() public { + (bytes memory name, bytes32 node) = + NameEncoder.dnsEncodeName("newdomain.blockful.eth"); + address owner = address(0x123); + uint256 duration = 365 days; + bytes32 secret = bytes32(0); + + bytes[] memory data = new bytes[](1); + data[0] = abi.encodeWithSelector( + DummyResolver.setText.selector, node, "key", "value" + ); + + vm.expectCall( + address(nameWrapper), + abi.encodeWithSelector( + DummyNameWrapper.setSubnodeRecord.selector, + namehash("blockful.eth"), + "newdomain", + owner, + address(resolver), + 0, + 0, + duration + ) + ); + + vm.expectCall( + address(resolver), + abi.encodeWithSelector( + Multicallable.multicallWithNodeCheck.selector, node, data + ) + ); + + vm.deal(address(this), PRICE); + controller.register{value: PRICE}( + name, + owner, + duration, + secret, + address(resolver), + data, + false, + 0, + abi.encode("") + ); + + assertEq( + nameWrapper.ownerOf(uint256(node)), + owner, + "Owner should be set correctly" + ); + + // Verify that the text record was saved correctly + assertEq( + resolver.text(node, "key"), + "value", + "Text record should be set correctly" + ); + } + +} From 659db1252860c2fa87f357990548a6552bd51c84 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Wed, 9 Oct 2024 11:27:23 -0300 Subject: [PATCH 05/17] fix: namehash from bytesutils --- packages/client/src/l2.write.ts | 5 ++-- .../contracts/src/SubdomainController.sol | 26 +------------------ 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/packages/client/src/l2.write.ts b/packages/client/src/l2.write.ts index ec117d1f..f1ccc15d 100644 --- a/packages/client/src/l2.write.ts +++ b/packages/client/src/l2.write.ts @@ -54,6 +54,7 @@ const _ = (async () => { } const name = normalize('gibi.arb.eth') + const dnsName = toHex(packetToBytes(name)) const node = namehash(name) const signer = privateKeyToAccount(privateKey as Hex) @@ -68,7 +69,7 @@ const _ = (async () => { address: universalResolver as Hex, functionName: 'findResolver', abi: uAbi, - args: [toHex(packetToBytes(name))], + args: [dnsName], })) as Hash[] const duration = 31556952000n @@ -107,7 +108,7 @@ const _ = (async () => { functionName: 'register', abi: l1Abi, args: [ - toHex(name), // name + dnsName, // name signer.address, // owner duration, `0x${'a'.repeat(64)}` as Hex, // secret diff --git a/packages/contracts/src/SubdomainController.sol b/packages/contracts/src/SubdomainController.sol index 9c84d10f..c6bd0a50 100644 --- a/packages/contracts/src/SubdomainController.sol +++ b/packages/contracts/src/SubdomainController.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -import "forge-std/console.sol"; - import {INameWrapper} from "@ens-contracts/wrapper/INameWrapper.sol"; import {Resolver} from "@ens-contracts/resolvers/Resolver.sol"; import {BytesUtils} from "@ens-contracts/utils/BytesUtils.sol"; @@ -43,7 +41,7 @@ contract SubdomainController is OffchainRegister, ENSHelper { payable override { - bytes32 node = _getNode(name); + bytes32 node = name.namehash(0); string memory label = _getLabel(name); (, uint256 offset) = name.readLabel(0); @@ -64,28 +62,6 @@ contract SubdomainController is OffchainRegister, ENSHelper { } } - function _getNode(bytes memory name) private pure returns (bytes32 node) { - return _getNode(name, 0); - } - - function _getNode( - bytes memory name, - uint256 offset - ) - private - pure - returns (bytes32 node) - { - uint256 len = name.readUint8(offset); - node = bytes32(0); - if (len > 0) { - bytes32 label = name.keccak(offset + 1, len); - bytes32 parentNode = _getNode(name, offset + len + 1); - node = keccak256(abi.encodePacked(parentNode, label)); - } - return node; - } - function _getLabel(bytes calldata name) private pure From 0a10ee2e259607251e730ef761191e797a872a15 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Tue, 8 Oct 2024 09:02:36 -0300 Subject: [PATCH 06/17] refactor: ttl as string --- .../migrations/1728326723263-TTLAsString.ts | 15 +++++++++++++++ packages/gateway/src/entities/domain.ts | 4 ++-- packages/gateway/src/handlers/address.ts | 5 +++-- packages/gateway/src/handlers/domain.ts | 5 ++++- packages/gateway/src/handlers/text.ts | 3 ++- packages/gateway/src/repositories/memory.ts | 4 ++-- packages/gateway/src/types/dtos.ts | 4 ++-- 7 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts diff --git a/packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts b/packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts new file mode 100644 index 00000000..a53807b4 --- /dev/null +++ b/packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class TTLAsString1728326723263 implements MigrationInterface { + name = 'TTLAsString1728326723263' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) + await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" bigint NOT NULL`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) + await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" integer NOT NULL`) + } +} diff --git a/packages/gateway/src/entities/domain.ts b/packages/gateway/src/entities/domain.ts index 9cf2f125..a129bd40 100644 --- a/packages/gateway/src/entities/domain.ts +++ b/packages/gateway/src/entities/domain.ts @@ -29,8 +29,8 @@ export class Domain { @Column({ nullable: true, length: 32 }) contenthash?: `0x${string}` - @Column() - ttl: number + @Column('bigint') + ttl: string @OneToMany(() => Address, (addr) => addr.domain, { cascade: true, diff --git a/packages/gateway/src/handlers/address.ts b/packages/gateway/src/handlers/address.ts index 671c496e..6231ab1e 100644 --- a/packages/gateway/src/handlers/address.ts +++ b/packages/gateway/src/handlers/address.ts @@ -89,7 +89,7 @@ export function withGetAddr(repo: ReadRepository): ccip.HandlerDescription { if (addr) return { data: [addr.value], - extraData: formatTTL(addr.ttl), + extraData: formatTTL(parseInt(addr.ttl)), } }, } @@ -102,7 +102,8 @@ export function withGetAddrByCoin( type: 'addr(bytes32 node, uint256 coinType)', func: async ({ node, coinType: coin }) => { const addr = await repo.getAddr({ node, coin: coin.toString() }) - if (addr) return { data: [addr.value], extraData: formatTTL(addr.ttl) } + if (addr) + return { data: [addr.value], extraData: formatTTL(parseInt(addr.ttl)) } }, } } diff --git a/packages/gateway/src/handlers/domain.ts b/packages/gateway/src/handlers/domain.ts index 4f03a004..a3b80139 100644 --- a/packages/gateway/src/handlers/domain.ts +++ b/packages/gateway/src/handlers/domain.ts @@ -138,7 +138,10 @@ export function withGetContentHash( func: async ({ node }) => { const content = await repo.getContentHash({ node }) if (content) - return { data: [content.value], extraData: formatTTL(content.ttl) } + return { + data: [content.value], + extraData: formatTTL(parseInt(content.ttl)), + } }, } } diff --git a/packages/gateway/src/handlers/text.ts b/packages/gateway/src/handlers/text.ts index 80356d87..178d9682 100644 --- a/packages/gateway/src/handlers/text.ts +++ b/packages/gateway/src/handlers/text.ts @@ -59,7 +59,8 @@ export function withGetText(repo: ReadRepository): ccip.HandlerDescription { type: 'text(bytes32 node, string key) view returns (string)', func: async ({ node, key }) => { const text = await repo.getText({ node, key }) - if (text) return { data: [text.value], extraData: formatTTL(text.ttl) } + if (text) + return { data: [text.value], extraData: formatTTL(parseInt(text.ttl)) } }, } } diff --git a/packages/gateway/src/repositories/memory.ts b/packages/gateway/src/repositories/memory.ts index f777665b..9df2a5db 100644 --- a/packages/gateway/src/repositories/memory.ts +++ b/packages/gateway/src/repositories/memory.ts @@ -194,7 +194,7 @@ export class InMemoryRepository { const domain = this.domains.get(node) let ttl = domain?.ttl if (!address) return - if (!domain || !ttl) ttl = 300 // default value + if (!domain || !ttl) ttl = '300' // default value return { value: address.address, ttl } } @@ -226,7 +226,7 @@ export class InMemoryRepository { const domain = this.domains.get(node) let ttl = domain?.ttl if (!text) return - if (!domain || !ttl) ttl = 300 // default value + if (!domain || !ttl) ttl = '300' // default value return { value: text.value, ttl } } diff --git a/packages/gateway/src/types/dtos.ts b/packages/gateway/src/types/dtos.ts index 6c33bae0..cd2b1685 100644 --- a/packages/gateway/src/types/dtos.ts +++ b/packages/gateway/src/types/dtos.ts @@ -3,7 +3,7 @@ import { PubKey } from '.' export type Response = { value: string - ttl: number + ttl: string } export type WritingProps = { @@ -69,5 +69,5 @@ export type SetPubkeyProps = NodeProps & export type GetPubkeyResponse = { value: PubKey - ttl: number + ttl: string } From 881564305e4b077bf836917e1b9bc607907f85fe Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Tue, 8 Oct 2024 09:37:32 -0300 Subject: [PATCH 07/17] feat: add db register and registerParams --- .vscode/launch.json | 19 +--- packages/client/package.json | 5 +- packages/client/src/db.write.ts | 105 ------------------ packages/client/src/{l2.write.ts => write.ts} | 24 +++- .../script/local/DatabaseResolver.sol | 2 + packages/contracts/src/DatabaseResolver.sol | 61 ++++++++-- packages/gateway/cmd/database.ts | 5 +- packages/gateway/src/abi.ts | 3 +- packages/gateway/src/handlers/domain.ts | 33 ++++-- 9 files changed, 105 insertions(+), 152 deletions(-) delete mode 100644 packages/client/src/db.write.ts rename packages/client/src/{l2.write.ts => write.ts} (84%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 0914eb2d..a0dd2c73 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,24 +19,9 @@ { "type": "node", "request": "launch", - "name": "db write client", + "name": "write client", "skipFiles": ["/**"], - "program": "${workspaceFolder}/packages/client/src/db.write.ts", - "runtimeArgs": ["-r", "ts-node/register", "-r", "tsconfig-paths/register"], - "env": { - "NODE_ENV": "development", - "TS_NODE_PROJECT": "${workspaceFolder}/packages/client/tsconfig.json", - "ENV_FILE": "${workspaceFolder}/.env" - }, - "console": "integratedTerminal", - "outFiles": ["${workspaceFolder}/**/*.js", "!**/node_modules/**"] - }, - { - "type": "node", - "request": "launch", - "name": "l2 write client", - "skipFiles": ["/**"], - "program": "${workspaceFolder}/packages/client/src/l2.write.ts", + "program": "${workspaceFolder}/packages/client/src/write.ts", "runtimeArgs": ["-r", "ts-node/register", "-r", "tsconfig-paths/register"], "env": { "NODE_ENV": "development", diff --git a/packages/client/package.json b/packages/client/package.json index 618329f1..5785ba27 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -4,9 +4,8 @@ "test": "npm-run-all test:**", "test:l1": "hardhat test ./test/arb.e2e.spec.ts --network localhost", "test:db": "hardhat test ./test/db.e2e.spec.ts --network localhost", - "start:read": "ts-node src/read.ts --resolver 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", - "start:write:db": "ts-node src/db.write.ts --resolver 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", - "start:write:l2": "ts-node src/l2.write.ts --resolver 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "start:read": "ts-node src/read.ts", + "start:write": "ts-node src/write.ts", "lint": "eslint . --ext .ts --fix" }, "devDependencies": { diff --git a/packages/client/src/db.write.ts b/packages/client/src/db.write.ts deleted file mode 100644 index 07359b80..00000000 --- a/packages/client/src/db.write.ts +++ /dev/null @@ -1,105 +0,0 @@ -/** - * This file purpose is to implement a client capable of calling methods on a given - * Blockchain Node and to redirect the request to a Gateway whenever necessary. - */ - -import { config } from 'dotenv' -import { - Hash, - Hex, - createPublicClient, - encodeFunctionData, - getChainContractAddress, - http, - namehash, - toHex, -} from 'viem' -import { normalize, packetToBytes } from 'viem/ens' -import { privateKeyToAccount } from 'viem/accounts' - -import { MessageData, DomainData } from '@blockful/gateway/src/types' -import { abi as dbAbi } from '@blockful/contracts/out/DatabaseResolver.sol/DatabaseResolver.json' -import { abi as uAbi } from '@blockful/contracts/out/UniversalResolver.sol/UniversalResolver.json' -import { getRevertErrorData, handleDBStorage, getChain } from './client' - -config({ - path: process.env.ENV_FILE || '../../../.env', -}) - -let { - UNIVERSAL_RESOLVER_ADDRESS: resolver, - CHAIN_ID: chainId = '31337', - RPC_URL: provider = 'http://127.0.0.1:8545/', - PRIVATE_KEY: - privateKey = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', // anvil PK -} = process.env - -const chain = getChain(parseInt(chainId)) -console.log(`Connecting to ${chain?.name}.`) - -const client = createPublicClient({ - chain, - transport: http(provider), -}) - -// eslint-disable-next-line -const _ = (async () => { - const name = normalize('blockful.eth') - const node = namehash(name) - const signer = privateKeyToAccount(privateKey as Hex) - - if (!resolver) { - resolver = getChainContractAddress({ - chain: client.chain, - contract: 'ensUniversalResolver', - }) - } - - const [resolverAddr] = (await client.readContract({ - address: resolver as Hex, - functionName: 'findResolver', - abi: uAbi, - args: [toHex(packetToBytes(name))], - })) as Hash[] - - const data: Hash[] = [ - encodeFunctionData({ - functionName: 'setText', - abi: dbAbi, - args: [node, 'com.twitter', '@blockful.eth'], - }), - encodeFunctionData({ - functionName: 'setAddr', - abi: dbAbi, - args: [node, '0x3a872f8FED4421E7d5BE5c98Ab5Ea0e0245169A0'], - }), - encodeFunctionData({ - functionName: 'setAddr', - abi: dbAbi, - args: [node, 1n, '0x3a872f8FED4421E7d5BE5c98Ab5Ea0e0245169A0'], - }), - ] - - // REGISTER NEW DOMAIN - try { - await client.simulateContract({ - functionName: 'register', - abi: dbAbi, - args: [toHex(name), 300, signer.address, data], - account: signer.address, - address: resolverAddr, - }) - } catch (err) { - const data = getRevertErrorData(err) - if (data?.errorName === 'StorageHandledByOffChainDatabase') { - const [domain, url, message] = data.args as [ - DomainData, - string, - MessageData, - ] - await handleDBStorage({ domain, url, message, signer }) - } else { - console.error('writing failed: ', { err }) - } - } -})() diff --git a/packages/client/src/l2.write.ts b/packages/client/src/write.ts similarity index 84% rename from packages/client/src/l2.write.ts rename to packages/client/src/write.ts index f1ccc15d..e8e684b5 100644 --- a/packages/client/src/l2.write.ts +++ b/packages/client/src/write.ts @@ -20,7 +20,8 @@ import { privateKeyToAccount } from 'viem/accounts' import { abi as uAbi } from '@blockful/contracts/out/UniversalResolver.sol/UniversalResolver.json' import { abi as l1Abi } from '@blockful/contracts/out/L1Resolver.sol/L1Resolver.json' -import { getRevertErrorData, getChain } from './client' +import { MessageData, DomainData } from '@blockful/gateway/src/types' +import { getRevertErrorData, getChain, handleDBStorage } from './client' config({ path: process.env.ENV_FILE || '../.env', @@ -33,7 +34,7 @@ let { RPC_URL: provider = 'http://127.0.0.1:8545/', L2_RPC_URL: providerL2 = 'http://127.0.0.1:8547', PRIVATE_KEY: - privateKey = '0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659', // local arbitrum PK + privateKey = '0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659', // local arbitrum PK } = process.env const chain = getChain(parseInt(chainId)) @@ -76,14 +77,20 @@ const _ = (async () => { // SUBDOMAIN PRICING - const [value /* commitTime */ /* extraData */, ,] = - (await client.readContract({ + let value = 0n + try { + const [_value] = (await client.readContract({ address: resolverAddr, abi: l1Abi, functionName: 'registerParams', args: [toHex(name), duration], })) as [bigint, bigint, Hex] + value = _value + } catch { + // expected revert when the resolver doesn't implement registerParams + } + // REGISTER NEW SUBDOMAIN const data: Hex[] = [ @@ -128,6 +135,15 @@ const _ = (async () => { } catch (err) { const data = getRevertErrorData(err) switch (data?.errorName) { + case 'StorageHandledByOffChainDatabase': { + const [domain, url, message] = data.args as [ + DomainData, + string, + MessageData, + ] + await handleDBStorage({ domain, url, message, signer }) + return + } case 'StorageHandledByL2': { const [chainId, contractAddress] = data.args as [bigint, `0x${string}`] diff --git a/packages/contracts/script/local/DatabaseResolver.sol b/packages/contracts/script/local/DatabaseResolver.sol index a43c773e..c9d199f1 100644 --- a/packages/contracts/script/local/DatabaseResolver.sol +++ b/packages/contracts/script/local/DatabaseResolver.sol @@ -38,6 +38,8 @@ contract DatabaseResolverScript is Script, ENSHelper { 9999999999 ); vm.stopBroadcast(); + + console.log("DatabaseResolver deployed at", address(resolver)); } } diff --git a/packages/contracts/src/DatabaseResolver.sol b/packages/contracts/src/DatabaseResolver.sol index 57cca13b..232a4be5 100644 --- a/packages/contracts/src/DatabaseResolver.sol +++ b/packages/contracts/src/DatabaseResolver.sol @@ -20,6 +20,11 @@ import {ENSIP16} from "./ENSIP16.sol"; import {SignatureVerifier} from "./SignatureVerifier.sol"; import {IWriteDeferral} from "./interfaces/IWriteDeferral.sol"; import {EnumerableSetUpgradeable} from "./utils/EnumerableSetUpgradeable.sol"; +import { + OffchainRegister, + OffchainRegisterParams, + OffchainMulticallable +} from "./interfaces/OffchainResolver.sol"; /** * Implements an ENS resolver that directs all queries to a CCIP read gateway. @@ -36,6 +41,9 @@ contract DatabaseResolver is TextResolver, ContentHashResolver, NameResolver, + OffchainRegister, + OffchainRegisterParams, + OffchainMulticallable, Ownable { @@ -106,23 +114,60 @@ contract DatabaseResolver is //////// OFFCHAIN STORAGE REGISTER DOMAIN //////// /** - * Resolves a name, as specified by ENSIP 10 (wildcard). - * @param -name The DNS-encoded name to be registered. - * @param -ttl Expiration timestamp of the domain - * @param -owner address of the owner of the domain + * Forwards the registering of a domain to the L2 contracts + * @param -parentNode namehash of the parent node + * @param -label The name to be registered. + * @param -owner Owner of the domain + * @param -duration duration The duration in seconds of the registration. + * @param -secret The secret to be used for the registration based on commit/reveal + * @param -resolver The address of the resolver to set for this name. + * @param -data Multicallable data bytes for setting records in the associated resolver upon reigstration. + * @param -reverseRecord Whether this name is the primary name + * @param -fuses The fuses to set for this name. + * @param -extraData any encoded additional data */ function register( - bytes memory, /* name */ - uint32, /* ttl */ + bytes32, /* parentNode */ + string calldata, /* name */ address, /* owner */ - bytes[] calldata /* data */ + uint256, /* duration */ + bytes32, /* secret */ + address, /* resolver */ + bytes[] calldata, /* data */ + bool, /* reverseRecord */ + uint16, /* fuses */ + bytes memory /* extraData */ ) external - view + payable + override { _offChainStorage(); } + /** + * @notice Returns the registration parameters for a given name and duration + * @param -name The DNS-encoded name to query + * @param -duration The duration in seconds for the registration + * @return price The price of the registration in wei per second + * @return commitTime the amount of time the commit should wait before being revealed + * @return extraData any given structure in an ABI encoded format + */ + function registerParams( + bytes calldata, /* name */ + uint256 /* duration */ + ) + external + view + returns ( + uint256, /* price */ + uint256, /* commitTime */ + bytes memory /* extraData */ + ) + { + _offChainLookup(msg.data); + } + //////// OFFCHAIN STORAGE TRANSFER DOMAIN //////// /** diff --git a/packages/gateway/cmd/database.ts b/packages/gateway/cmd/database.ts index 29228366..28bf5f9d 100644 --- a/packages/gateway/cmd/database.ts +++ b/packages/gateway/cmd/database.ts @@ -1,6 +1,3 @@ -/** - * Script for running the server locally exposing the API - */ import 'reflect-metadata' import { config } from 'dotenv' import { Hex, createPublicClient, getChainContractAddress, http } from 'viem' @@ -23,6 +20,7 @@ import { withQuery, withRegisterDomain, withTransferDomain, + withRegisterParams, } from '../src/handlers' import { abi } from '../src/abi' import { getChain } from '../src/chain' @@ -106,6 +104,7 @@ const _ = (async () => { withSetAddrByCoin(repo, ownershipValidator), withGetContentHash(repo), withSetContentHash(repo, ownershipValidator), + withRegisterParams(), withRegisterDomain(repo), withTransferDomain(repo, ownershipValidator), ) diff --git a/packages/gateway/src/abi.ts b/packages/gateway/src/abi.ts index a043cea8..5fc03d5c 100644 --- a/packages/gateway/src/abi.ts +++ b/packages/gateway/src/abi.ts @@ -14,7 +14,8 @@ export const abi: string[] = [ 'function setPubkey(bytes32 node,bytes32 x, bytes32 y)', 'function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y)', 'function getStorageSlots(address addr, bytes32[] memory commands, bytes[] memory) external view returns(bytes memory witness)', - 'function register(bytes memory name, uint32 ttl, address owner, bytes[] calldata data)', + 'function registerParams(bytes memory name,uint256 duration) external view returns(uint256 price,uint256 commitTime,bytes memory extraData)', + 'function register(bytes32 parentNode, string calldata label, address owner, uint256 duration, bytes32 secret, address resolver, bytes[] calldata data, bool reverseRecord, uint16 fuses, bytes memory extraData)', 'function transfer(bytes32 node, address owner)', 'function multicall(bytes[] calldata data) external returns (bytes[] memory results)', ] diff --git a/packages/gateway/src/handlers/domain.ts b/packages/gateway/src/handlers/domain.ts index a3b80139..762f6acd 100644 --- a/packages/gateway/src/handlers/domain.ts +++ b/packages/gateway/src/handlers/domain.ts @@ -1,4 +1,4 @@ -import { hexToString, namehash } from 'viem' +import { concat, keccak256, labelhash, stringToBytes } from 'viem' import * as ccip from '@blockful/ccip-server' @@ -29,36 +29,47 @@ interface ReadRepository { getDomain(params: NodeProps): Promise } +export function withRegisterParams(): ccip.HandlerDescription { + return { + type: 'registerParams(bytes memory name,uint256 duration)', + func: async ({ duration }) => { + const price = 0n + const commitTime = 0n + const extraData = stringToBytes('') + return { + data: [price, commitTime, extraData], + extraData: formatTTL(duration), + } + }, + } +} + export function withRegisterDomain( repo: WriteRepository & ReadRepository, ): ccip.HandlerDescription { return { - type: 'register(bytes memory name, uint32 ttl, address owner, bytes[] calldata data)', + type: 'register(bytes32 parentNode, string calldata label, address owner, uint256 duration, bytes32 secret, address resolver, bytes[] calldata data, bool reverseRecord, uint16 fuses, bytes memory extraData)', func: async ( - { name, ttl, owner, data }, + { parentNode, label, duration: ttl, owner, data }, { signature }: { signature: TypedSignature }, ) => { try { - name = hexToString(name) - const node = namehash(name) + const node = keccak256(concat([parentNode, labelhash(label)])) const existingDomain = await repo.getDomain({ node }) if (existingDomain) { return { error: { message: 'Domain already exists', status: 400 } } } - const [, parent] = /\w*\.(.*)$/.exec(name) || [] - const parentHash = namehash(parent) - const addresses = parseEncodedAddressCalls(data, signature) const texts = parseEncodedTextCalls(data, signature) await repo.register({ - name, + name: label, node, - ttl, + ttl: ttl.toString(), owner, - parent: parentHash, + parent: parentNode, resolver: signature.domain.verifyingContract, resolverVersion: signature.domain.version, addresses, From fb3386aa24538f5ac20ccdcedf93247423614676 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Tue, 8 Oct 2024 11:42:50 -0300 Subject: [PATCH 08/17] chore: remove registerParams from db resolver --- package-lock.json | 244 ++++++++++++++------ packages/client/package.json | 4 +- packages/client/src/write.ts | 16 +- packages/contracts/src/DatabaseResolver.sol | 25 -- packages/gateway/cmd/database.ts | 2 - packages/gateway/package.json | 4 +- packages/gateway/src/handlers/domain.ts | 17 +- 7 files changed, 180 insertions(+), 132 deletions(-) diff --git a/package-lock.json b/package-lock.json index 77bb3287..ec2105b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,9 +33,10 @@ } }, "node_modules/@adraffy/ens-normalize": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", - "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz", + "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==", + "license": "MIT" }, "node_modules/@alcalzone/ansi-tokenize": { "version": "0.1.3", @@ -4417,28 +4418,28 @@ } }, "node_modules/@nomicfoundation/edr": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.5.2.tgz", - "integrity": "sha512-hW/iLvUQZNTVjFyX/I40rtKvvDOqUEyIi96T28YaLfmPL+3LW2lxmYLUXEJ6MI14HzqxDqrLyhf6IbjAa2r3Dw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.6.3.tgz", + "integrity": "sha512-hThe5ORR75WFYTXKL0K2AyLDxkTMrG+VQ1yL9BhQYsuh3OIH+3yNDxMz2LjfvrpOrMmJ4kk5NKdFewpqDojjXQ==", "dev": true, "license": "MIT", "dependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.5.2", - "@nomicfoundation/edr-darwin-x64": "0.5.2", - "@nomicfoundation/edr-linux-arm64-gnu": "0.5.2", - "@nomicfoundation/edr-linux-arm64-musl": "0.5.2", - "@nomicfoundation/edr-linux-x64-gnu": "0.5.2", - "@nomicfoundation/edr-linux-x64-musl": "0.5.2", - "@nomicfoundation/edr-win32-x64-msvc": "0.5.2" + "@nomicfoundation/edr-darwin-arm64": "0.6.3", + "@nomicfoundation/edr-darwin-x64": "0.6.3", + "@nomicfoundation/edr-linux-arm64-gnu": "0.6.3", + "@nomicfoundation/edr-linux-arm64-musl": "0.6.3", + "@nomicfoundation/edr-linux-x64-gnu": "0.6.3", + "@nomicfoundation/edr-linux-x64-musl": "0.6.3", + "@nomicfoundation/edr-win32-x64-msvc": "0.6.3" }, "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.5.2.tgz", - "integrity": "sha512-Gm4wOPKhbDjGTIRyFA2QUAPfCXA1AHxYOKt3yLSGJkQkdy9a5WW+qtqKeEKHc/+4wpJSLtsGQfpzyIzggFfo/A==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.3.tgz", + "integrity": "sha512-hqtI7tYDqKG5PDmZ//Z65EH5cgH8VL/SAAu50rpHP7WAVfJWkOCcYbecywwF6nhHdonJbRTDGAeG1/+VOy6zew==", "dev": true, "license": "MIT", "engines": { @@ -4446,9 +4447,9 @@ } }, "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.5.2.tgz", - "integrity": "sha512-ClyABq2dFCsrYEED3/UIO0c7p4H1/4vvlswFlqUyBpOkJccr75qIYvahOSJRM62WgUFRhbSS0OJXFRwc/PwmVg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.3.tgz", + "integrity": "sha512-4fGi79/lyOlRUORhCYsYb3sWqRHuHT7qqzyZfZuNOn8llaxmT1k36xNmvpyg37R8SzjnhT/DzoukSJrs23Ip9Q==", "dev": true, "license": "MIT", "engines": { @@ -4456,9 +4457,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.5.2.tgz", - "integrity": "sha512-HWMTVk1iOabfvU2RvrKLDgtFjJZTC42CpHiw2h6rfpsgRqMahvIlx2jdjWYzFNy1jZKPTN1AStQ/91MRrg5KnA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.3.tgz", + "integrity": "sha512-yFFTvGFMhfAvQ1Z2itUh1jpoUA+mVROyVELcaxjIq8fyg602lQmbS+NXkhQ+oaeDgJ+06mSENrHBg4fcfRf9cw==", "dev": true, "license": "MIT", "engines": { @@ -4466,9 +4467,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.5.2.tgz", - "integrity": "sha512-CwsQ10xFx/QAD5y3/g5alm9+jFVuhc7uYMhrZAu9UVF+KtVjeCvafj0PaVsZ8qyijjqVuVsJ8hD1x5ob7SMcGg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.3.tgz", + "integrity": "sha512-pOKmd0Fa3a6BHg5qbjbl/jMRELVi9oazbfiuU7Bvgn/dpTK+ID3jwT0SXiuC2zxjmPByWgXL6G9XRf5BPAM2rQ==", "dev": true, "license": "MIT", "engines": { @@ -4476,9 +4477,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.5.2.tgz", - "integrity": "sha512-CWVCEdhWJ3fmUpzWHCRnC0/VLBDbqtqTGTR6yyY1Ep3S3BOrHEAvt7h5gx85r2vLcztisu2vlDq51auie4IU1A==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.3.tgz", + "integrity": "sha512-3AUferhkLIXtLV63w5GjpHttzdxZ36i656XMy+pkBZbbiqnzIVeKWg6DJv1A94fQY16gB4gqj9CLq4CWvbNN6w==", "dev": true, "license": "MIT", "engines": { @@ -4486,9 +4487,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.5.2.tgz", - "integrity": "sha512-+aJDfwhkddy2pP5u1ISg3IZVAm0dO836tRlDTFWtvvSMQ5hRGqPcWwlsbobhDQsIxhPJyT7phL0orCg5W3WMeA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.3.tgz", + "integrity": "sha512-fr6bD872WIBXe9YnTDi0CzYepMcYRgSnkVqn0yK4wRnIvKrloWhxXNVY45GVIl51aNZguBnvoA4WEt6HIazs3A==", "dev": true, "license": "MIT", "engines": { @@ -4496,9 +4497,9 @@ } }, "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.5.2.tgz", - "integrity": "sha512-CcvvuA3sAv7liFNPsIR/68YlH6rrybKzYttLlMr80d4GKJjwJ5OKb3YgE6FdZZnOfP19HEHhsLcE0DPLtY3r0w==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.3.tgz", + "integrity": "sha512-sn34MvN1ajw2Oq1+Drpxej78Z0HfIzI4p4WlolupAV9dOZKzp2JAIQeLVfZpjIFbF3zuyxLPP4dUBrQoFPEqhA==", "dev": true, "license": "MIT", "engines": { @@ -6347,6 +6348,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, "dependencies": { "@noble/curves": "~1.4.0", "@noble/hashes": "~1.4.0", @@ -7705,9 +7707,10 @@ "devOptional": true }, "node_modules/abitype": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.5.tgz", - "integrity": "sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.6.tgz", + "integrity": "sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/wevm" }, @@ -14088,15 +14091,15 @@ } }, "node_modules/hardhat": { - "version": "2.22.11", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.11.tgz", - "integrity": "sha512-g9xr6BGXbzj2sqG9AjHwqeUOS9v2NwLbuq7rsdjMB2RLWmYp8IFdZnzq8UewwLJisuWgiygB+dwLktjqAbRuOw==", + "version": "2.22.12", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.12.tgz", + "integrity": "sha512-yok65M+LsOeTBHQsjg//QreGCyrsaNmeLVzhTFqlOvZ4ZE5y69N0wRxH1b2BC9dGK8S8OPUJMNiL9X0RAvbm8w==", "dev": true, "license": "MIT", "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "^0.5.2", + "@nomicfoundation/edr": "^0.6.1", "@nomicfoundation/ethereumjs-common": "4.0.4", "@nomicfoundation/ethereumjs-tx": "5.0.4", "@nomicfoundation/ethereumjs-util": "9.0.4", @@ -15981,15 +15984,16 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isows": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.4.tgz", - "integrity": "sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.6.tgz", + "integrity": "sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/wagmi-dev" + "url": "https://github.com/sponsors/wevm" } ], + "license": "MIT", "peerDependencies": { "ws": "*" } @@ -23636,9 +23640,9 @@ } }, "node_modules/viem": { - "version": "2.21.17", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.21.17.tgz", - "integrity": "sha512-YtqH0JZxmxQ4KBzXFwIe2EMFydlb8oOcwYnXgnNNOTy5nryEVkEO3Dbf7/VzFOIVsatr778i+QbUtSO60bKGkw==", + "version": "2.21.19", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.21.19.tgz", + "integrity": "sha512-FdlkN+UI1IU5sYOmzvygkxsUNjDRD5YHht3gZFu2X9xFv6Z3h9pXq9ycrYQ3F17lNfb41O2Ot4/aqbUkwOv9dA==", "funding": [ { "type": "github", @@ -23647,15 +23651,15 @@ ], "license": "MIT", "dependencies": { - "@adraffy/ens-normalize": "1.10.0", - "@noble/curves": "1.4.0", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", + "@adraffy/ens-normalize": "1.11.0", + "@noble/curves": "1.6.0", + "@noble/hashes": "1.5.0", + "@scure/bip32": "1.5.0", "@scure/bip39": "1.4.0", - "abitype": "1.0.5", - "isows": "1.0.4", - "webauthn-p256": "0.0.5", - "ws": "8.17.1" + "abitype": "1.0.6", + "isows": "1.0.6", + "webauthn-p256": "0.0.10", + "ws": "8.18.0" }, "peerDependencies": { "typescript": ">=5.0.4" @@ -23666,20 +23670,22 @@ } } }, - "node_modules/viem/node_modules/@scure/bip39": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.4.0.tgz", - "integrity": "sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==", + "node_modules/viem/node_modules/@noble/curves": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.6.0.tgz", + "integrity": "sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==", "license": "MIT", "dependencies": { - "@noble/hashes": "~1.5.0", - "@scure/base": "~1.1.8" + "@noble/hashes": "1.5.0" + }, + "engines": { + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/viem/node_modules/@scure/bip39/node_modules/@noble/hashes": { + "node_modules/viem/node_modules/@noble/hashes": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", @@ -23691,6 +23697,33 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/viem/node_modules/@scure/bip32": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.5.0.tgz", + "integrity": "sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.6.0", + "@noble/hashes": "~1.5.0", + "@scure/base": "~1.1.7" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip39": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.4.0.tgz", + "integrity": "sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.5.0", + "@scure/base": "~1.1.8" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/vite": { "version": "5.2.12", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.12.tgz", @@ -24299,9 +24332,9 @@ } }, "node_modules/webauthn-p256": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/webauthn-p256/-/webauthn-p256-0.0.5.tgz", - "integrity": "sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==", + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/webauthn-p256/-/webauthn-p256-0.0.10.tgz", + "integrity": "sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==", "funding": [ { "type": "github", @@ -24492,9 +24525,9 @@ } }, "node_modules/winston": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz", - "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.15.0.tgz", + "integrity": "sha512-RhruH2Cj0bV0WgNL+lOfoUBI4DVfdUNjVnJGVovWZmrcKtrFTTRzgXYK2O9cymSGjrERCtaAeHwMNnUWXlwZow==", "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", @@ -24686,9 +24719,10 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -24832,6 +24866,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/abstract-provider": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.3.0.tgz", + "integrity": "sha512-1+MLhGP1GwxBDBNwMWVmhCsvKwh4gK7oIfOrmlmePNeskg1NhIrYssraJBieaFNHUYfKEd/1DjiVZMw8Qu5Cxw==", "funding": [ { "type": "individual", @@ -24855,6 +24891,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/abstract-signer": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.3.0.tgz", + "integrity": "sha512-w8IFwOYqiPrtvosPuArZ3+QPR2nmdVTRrVY8uJYL3NNfMmQfTy3V3l2wbzX47UUlNbPJY+gKvzJAyvK1onZxJg==", "funding": [ { "type": "individual", @@ -24876,6 +24914,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/address": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.3.0.tgz", + "integrity": "sha512-29TgjzEBK+gUEUAOfWCG7s9IxLNLCqvr+oDSk6L9TXD0VLvZJKhJV479tKQqheVA81OeGxfpdxYtUVH8hqlCvA==", "funding": [ { "type": "individual", @@ -24897,6 +24937,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/base64": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.3.0.tgz", + "integrity": "sha512-JIqgtOmgKcbc2sjGWTXyXktqUhvFUDte8fPVsAaOrcPiJf6YotNF+nsrOYGC9pbHBEGSuSBp3QR0varkO8JHEw==", "funding": [ { "type": "individual", @@ -24926,6 +24968,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.3.0", "@ethersproject/properties": "^5.3.0" @@ -24933,6 +24976,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/bignumber": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.3.0.tgz", + "integrity": "sha512-5xguJ+Q1/zRMgHgDCaqAexx/8DwDVLRemw2i6uR8KyGjwGdXI8f32QZZ1cKGucBN6ekJvpUpHy6XAuQnTv0mPA==", "funding": [ { "type": "individual", @@ -24952,6 +24997,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/constants": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.3.0.tgz", + "integrity": "sha512-4y1feNOwEpgjAfiCFWOHznvv6qUF/H6uI0UKp8xdhftb+H+FbKflXg1pOgH5qs4Sr7EYBL+zPyPb+YD5g1aEyw==", "funding": [ { "type": "individual", @@ -24981,6 +25028,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/abi": "^5.3.0", "@ethersproject/abstract-provider": "^5.3.0", @@ -24996,6 +25044,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/hash": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.3.0.tgz", + "integrity": "sha512-gAFZSjUPQ32CIfoKSMtMEQ+IO0kQxqhwz9fCIFt2DtAq2u4pWt8mL9Z5P0r6KkLcQU8LE9FmuPPyd+JvBzmr1w==", "funding": [ { "type": "individual", @@ -25032,6 +25082,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/abstract-signer": "^5.3.0", "@ethersproject/basex": "^5.3.0", @@ -25061,6 +25112,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/abstract-signer": "^5.3.0", "@ethersproject/address": "^5.3.0", @@ -25079,6 +25131,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/keccak256": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.3.0.tgz", + "integrity": "sha512-Gv2YqgIUmRbYVNIibafT0qGaeGYLIA/EdWHJ7JcVxVSs2vyxafGxOJ5VpSBHWeOIsE6OOaCelYowhuuTicgdFQ==", "funding": [ { "type": "individual", @@ -25097,6 +25151,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/logger": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.3.0.tgz", + "integrity": "sha512-8bwJ2gxJGkZZnpQSq5uSiZSJjyVTWmlGft4oH8vxHdvO1Asy4TwVepAhPgxIQIMxXZFUNMych1YjIV4oQ4I7dA==", "funding": [ { "type": "individual", @@ -25111,6 +25167,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/networks": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.3.1.tgz", + "integrity": "sha512-6uQKHkYChlsfeiZhQ8IHIqGE/sQsf25o9ZxAYpMxi15dLPzz3IxOEF5KiSD32aHwsjXVBKBSlo+teAXLlYJybw==", "funding": [ { "type": "individual", @@ -25140,6 +25198,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.3.0", "@ethersproject/sha2": "^5.3.0" @@ -25147,6 +25206,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/properties": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.3.0.tgz", + "integrity": "sha512-PaHxJyM5/bfusk6vr3yP//JMnm4UEojpzuWGTmtL5X4uNhNnFNvlYilZLyDr4I9cTkIbipCMsAuIcXWsmdRnEw==", "funding": [ { "type": "individual", @@ -25176,6 +25237,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/abstract-provider": "^5.3.0", "@ethersproject/abstract-signer": "^5.3.0", @@ -25212,6 +25274,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.3.0", "@ethersproject/logger": "^5.3.0" @@ -25219,6 +25282,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/rlp": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.3.0.tgz", + "integrity": "sha512-oI0joYpsRanl9guDubaW+1NbcpK0vJ3F/6Wpcanzcnqq+oaW9O5E98liwkEDPcb16BUTLIJ+ZF8GPIHYxJ/5Pw==", "funding": [ { "type": "individual", @@ -25249,6 +25314,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.3.0", "@ethersproject/logger": "^5.3.0", @@ -25257,6 +25323,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/signing-key": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.3.0.tgz", + "integrity": "sha512-+DX/GwHAd0ok1bgedV1cKO0zfK7P/9aEyNoaYiRsGHpCecN7mhLqcdoUiUzE7Uz86LBsxm5ssK0qA1kBB47fbQ==", "funding": [ { "type": "individual", @@ -25291,6 +25359,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/bignumber": "^5.3.0", "@ethersproject/bytes": "^5.3.0", @@ -25301,6 +25370,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/strings": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.3.0.tgz", + "integrity": "sha512-j/AzIGZ503cvhuF2ldRSjB0BrKzpsBMtCieDtn4TYMMZMQ9zScJn9wLzTQl/bRNvJbBE6TOspK0r8/Ngae/f2Q==", "funding": [ { "type": "individual", @@ -25320,6 +25391,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/transactions": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.3.0.tgz", + "integrity": "sha512-cdfK8VVyW2oEBCXhURG0WQ6AICL/r6Gmjh0e4Bvbv6MCn/GBd8FeBH3rtl7ho+AW50csMKeGv3m3K1HSHB2jMQ==", "funding": [ { "type": "individual", @@ -25357,6 +25430,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/bignumber": "^5.3.0", "@ethersproject/constants": "^5.3.0", @@ -25377,6 +25451,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/abstract-provider": "^5.3.0", "@ethersproject/abstract-signer": "^5.3.0", @@ -25397,6 +25472,8 @@ }, "packages/ccip-server/node_modules/@ethersproject/web": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.3.0.tgz", + "integrity": "sha512-Ni6/DHnY6k/TD41LEkv0RQDx4jqWz5e/RZvrSecsxGYycF+MFy2z++T/yGc2peRunLOTIFwEksgEGGlbwfYmhQ==", "funding": [ { "type": "individual", @@ -25430,6 +25507,7 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.3.0", "@ethersproject/hash": "^5.3.0", @@ -25441,14 +25519,19 @@ "packages/ccip-server/node_modules/aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "license": "MIT" }, "packages/ccip-server/node_modules/bn.js": { "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "license": "MIT" }, "packages/ccip-server/node_modules/ethers": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.3.1.tgz", + "integrity": "sha512-xCKmC0gsZ9gks89ZfK3B1y6LlPdvX5fxDtu9SytnpdDJR1M7pmJI+4H0AxQPMgUYr7GtQdmECLR0gWdJQ+lZYw==", "funding": [ { "type": "individual", @@ -25495,6 +25578,8 @@ }, "packages/ccip-server/node_modules/ethers/node_modules/@ethersproject/abi": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.3.1.tgz", + "integrity": "sha512-F98FWTJG7nWWAQ4DcV6R0cSlrj67MWK3ylahuFbzkumem5cLWg1p7fZ3vIdRoS1c7TEf55Lvyx0w7ICR47IImw==", "funding": [ { "type": "individual", @@ -25520,6 +25605,8 @@ }, "packages/ccip-server/node_modules/ethers/node_modules/@ethersproject/bytes": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.3.0.tgz", + "integrity": "sha512-rqLJjdVqCcn7glPer7Fxh87PRqlnRScVAoxcIP3PmOUNApMWJ6yRdOFfo2KvPAdO7Le3yEI1o0YW+Yvr7XCYvw==", "funding": [ { "type": "individual", @@ -25537,12 +25624,15 @@ }, "packages/ccip-server/node_modules/js-sha3": { "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", "license": "MIT" }, "packages/ccip-server/node_modules/ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -25574,12 +25664,12 @@ "aes-js": "^3.1.2", "chai": "^4.2.0", "dotenv": "^16.4.5", - "hardhat": "^2.22.11", + "hardhat": "^2.22.12", "npm-run-all": "^4.1.5", "reflect-metadata": "^0.2.2", "solidity-coverage": "^0.8.12", "typeorm": "^0.3.20", - "viem": "^2.21.12" + "viem": "^2.21.19" }, "peerDependencies": { "@blockful/tsconfig": "*" @@ -25611,8 +25701,8 @@ "pg": "^8.13.0", "reflect-metadata": "^0.2.2", "typeorm": "^0.3.20", - "viem": "^2.21.16", - "winston": "^3.14.2" + "viem": "^2.21.19", + "winston": "^3.15.0" }, "devDependencies": { "@blockful/tsconfig": "*", diff --git a/packages/client/package.json b/packages/client/package.json index 5785ba27..e3097f4d 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -21,12 +21,12 @@ "aes-js": "^3.1.2", "chai": "^4.2.0", "dotenv": "^16.4.5", - "hardhat": "^2.22.11", + "hardhat": "^2.22.12", "npm-run-all": "^4.1.5", "reflect-metadata": "^0.2.2", "solidity-coverage": "^0.8.12", "typeorm": "^0.3.20", - "viem": "^2.21.12" + "viem": "^2.21.19" }, "peerDependencies": { "@blockful/tsconfig": "*" diff --git a/packages/client/src/write.ts b/packages/client/src/write.ts index e8e684b5..e659c97a 100644 --- a/packages/client/src/write.ts +++ b/packages/client/src/write.ts @@ -79,16 +79,16 @@ const _ = (async () => { let value = 0n try { - const [_value] = (await client.readContract({ - address: resolverAddr, - abi: l1Abi, - functionName: 'registerParams', - args: [toHex(name), duration], - })) as [bigint, bigint, Hex] - + const [_value /* commitTime */ /* extraData */, ,] = + (await client.readContract({ + address: resolverAddr, + abi: l1Abi, + functionName: 'registerParams', + args: [toHex(name), duration], + })) as [bigint, bigint, Hex] value = _value } catch { - // expected revert when the resolver doesn't implement registerParams + // interface not implemented by the resolver } // REGISTER NEW SUBDOMAIN diff --git a/packages/contracts/src/DatabaseResolver.sol b/packages/contracts/src/DatabaseResolver.sol index 232a4be5..f7978784 100644 --- a/packages/contracts/src/DatabaseResolver.sol +++ b/packages/contracts/src/DatabaseResolver.sol @@ -22,7 +22,6 @@ import {IWriteDeferral} from "./interfaces/IWriteDeferral.sol"; import {EnumerableSetUpgradeable} from "./utils/EnumerableSetUpgradeable.sol"; import { OffchainRegister, - OffchainRegisterParams, OffchainMulticallable } from "./interfaces/OffchainResolver.sol"; @@ -42,7 +41,6 @@ contract DatabaseResolver is ContentHashResolver, NameResolver, OffchainRegister, - OffchainRegisterParams, OffchainMulticallable, Ownable { @@ -145,29 +143,6 @@ contract DatabaseResolver is _offChainStorage(); } - /** - * @notice Returns the registration parameters for a given name and duration - * @param -name The DNS-encoded name to query - * @param -duration The duration in seconds for the registration - * @return price The price of the registration in wei per second - * @return commitTime the amount of time the commit should wait before being revealed - * @return extraData any given structure in an ABI encoded format - */ - function registerParams( - bytes calldata, /* name */ - uint256 /* duration */ - ) - external - view - returns ( - uint256, /* price */ - uint256, /* commitTime */ - bytes memory /* extraData */ - ) - { - _offChainLookup(msg.data); - } - //////// OFFCHAIN STORAGE TRANSFER DOMAIN //////// /** diff --git a/packages/gateway/cmd/database.ts b/packages/gateway/cmd/database.ts index 28bf5f9d..4802fbeb 100644 --- a/packages/gateway/cmd/database.ts +++ b/packages/gateway/cmd/database.ts @@ -20,7 +20,6 @@ import { withQuery, withRegisterDomain, withTransferDomain, - withRegisterParams, } from '../src/handlers' import { abi } from '../src/abi' import { getChain } from '../src/chain' @@ -104,7 +103,6 @@ const _ = (async () => { withSetAddrByCoin(repo, ownershipValidator), withGetContentHash(repo), withSetContentHash(repo, ownershipValidator), - withRegisterParams(), withRegisterDomain(repo), withTransferDomain(repo, ownershipValidator), ) diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 99a6bcd9..0090d27b 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -55,7 +55,7 @@ "pg": "^8.13.0", "reflect-metadata": "^0.2.2", "typeorm": "^0.3.20", - "viem": "^2.21.16", - "winston": "^3.14.2" + "viem": "^2.21.19", + "winston": "^3.15.0" } } diff --git a/packages/gateway/src/handlers/domain.ts b/packages/gateway/src/handlers/domain.ts index 762f6acd..ece2c218 100644 --- a/packages/gateway/src/handlers/domain.ts +++ b/packages/gateway/src/handlers/domain.ts @@ -1,4 +1,4 @@ -import { concat, keccak256, labelhash, stringToBytes } from 'viem' +import { concat, keccak256, labelhash } from 'viem' import * as ccip from '@blockful/ccip-server' @@ -29,21 +29,6 @@ interface ReadRepository { getDomain(params: NodeProps): Promise } -export function withRegisterParams(): ccip.HandlerDescription { - return { - type: 'registerParams(bytes memory name,uint256 duration)', - func: async ({ duration }) => { - const price = 0n - const commitTime = 0n - const extraData = stringToBytes('') - return { - data: [price, commitTime, extraData], - extraData: formatTTL(duration), - } - }, - } -} - export function withRegisterDomain( repo: WriteRepository & ReadRepository, ): ccip.HandlerDescription { From 63320eae6b0da664a7e533e3bdbf6649046b8b34 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Tue, 8 Oct 2024 14:51:12 -0300 Subject: [PATCH 09/17] chore: ttl as number --- .../migrations/1728326723263-TTLAsString.ts | 15 --------------- packages/gateway/src/entities/domain.ts | 4 ++-- packages/gateway/src/handlers/address.ts | 5 ++--- packages/gateway/src/handlers/domain.ts | 2 +- packages/gateway/src/handlers/text.ts | 3 +-- packages/gateway/src/repositories/memory.ts | 4 ++-- packages/gateway/src/types/dtos.ts | 4 ++-- 7 files changed, 10 insertions(+), 27 deletions(-) delete mode 100644 packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts diff --git a/packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts b/packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts deleted file mode 100644 index a53807b4..00000000 --- a/packages/gateway/src/datasources/migrations/1728326723263-TTLAsString.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { MigrationInterface, QueryRunner } from 'typeorm' - -export class TTLAsString1728326723263 implements MigrationInterface { - name = 'TTLAsString1728326723263' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) - await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" bigint NOT NULL`) - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) - await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" integer NOT NULL`) - } -} diff --git a/packages/gateway/src/entities/domain.ts b/packages/gateway/src/entities/domain.ts index a129bd40..9cf2f125 100644 --- a/packages/gateway/src/entities/domain.ts +++ b/packages/gateway/src/entities/domain.ts @@ -29,8 +29,8 @@ export class Domain { @Column({ nullable: true, length: 32 }) contenthash?: `0x${string}` - @Column('bigint') - ttl: string + @Column() + ttl: number @OneToMany(() => Address, (addr) => addr.domain, { cascade: true, diff --git a/packages/gateway/src/handlers/address.ts b/packages/gateway/src/handlers/address.ts index 6231ab1e..671c496e 100644 --- a/packages/gateway/src/handlers/address.ts +++ b/packages/gateway/src/handlers/address.ts @@ -89,7 +89,7 @@ export function withGetAddr(repo: ReadRepository): ccip.HandlerDescription { if (addr) return { data: [addr.value], - extraData: formatTTL(parseInt(addr.ttl)), + extraData: formatTTL(addr.ttl), } }, } @@ -102,8 +102,7 @@ export function withGetAddrByCoin( type: 'addr(bytes32 node, uint256 coinType)', func: async ({ node, coinType: coin }) => { const addr = await repo.getAddr({ node, coin: coin.toString() }) - if (addr) - return { data: [addr.value], extraData: formatTTL(parseInt(addr.ttl)) } + if (addr) return { data: [addr.value], extraData: formatTTL(addr.ttl) } }, } } diff --git a/packages/gateway/src/handlers/domain.ts b/packages/gateway/src/handlers/domain.ts index ece2c218..799be0d2 100644 --- a/packages/gateway/src/handlers/domain.ts +++ b/packages/gateway/src/handlers/domain.ts @@ -136,7 +136,7 @@ export function withGetContentHash( if (content) return { data: [content.value], - extraData: formatTTL(parseInt(content.ttl)), + extraData: formatTTL(content.ttl), } }, } diff --git a/packages/gateway/src/handlers/text.ts b/packages/gateway/src/handlers/text.ts index 178d9682..80356d87 100644 --- a/packages/gateway/src/handlers/text.ts +++ b/packages/gateway/src/handlers/text.ts @@ -59,8 +59,7 @@ export function withGetText(repo: ReadRepository): ccip.HandlerDescription { type: 'text(bytes32 node, string key) view returns (string)', func: async ({ node, key }) => { const text = await repo.getText({ node, key }) - if (text) - return { data: [text.value], extraData: formatTTL(parseInt(text.ttl)) } + if (text) return { data: [text.value], extraData: formatTTL(text.ttl) } }, } } diff --git a/packages/gateway/src/repositories/memory.ts b/packages/gateway/src/repositories/memory.ts index 9df2a5db..f777665b 100644 --- a/packages/gateway/src/repositories/memory.ts +++ b/packages/gateway/src/repositories/memory.ts @@ -194,7 +194,7 @@ export class InMemoryRepository { const domain = this.domains.get(node) let ttl = domain?.ttl if (!address) return - if (!domain || !ttl) ttl = '300' // default value + if (!domain || !ttl) ttl = 300 // default value return { value: address.address, ttl } } @@ -226,7 +226,7 @@ export class InMemoryRepository { const domain = this.domains.get(node) let ttl = domain?.ttl if (!text) return - if (!domain || !ttl) ttl = '300' // default value + if (!domain || !ttl) ttl = 300 // default value return { value: text.value, ttl } } diff --git a/packages/gateway/src/types/dtos.ts b/packages/gateway/src/types/dtos.ts index cd2b1685..6c33bae0 100644 --- a/packages/gateway/src/types/dtos.ts +++ b/packages/gateway/src/types/dtos.ts @@ -3,7 +3,7 @@ import { PubKey } from '.' export type Response = { value: string - ttl: string + ttl: number } export type WritingProps = { @@ -69,5 +69,5 @@ export type SetPubkeyProps = NodeProps & export type GetPubkeyResponse = { value: PubKey - ttl: string + ttl: number } From 1b7e494a5ae36ee532b46545e01e36110789168c Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Wed, 9 Oct 2024 14:11:35 -0300 Subject: [PATCH 10/17] refactor: ttl as string --- .../migrations/1728493485670-TTLAsString.ts | 15 +++++++++++++++ packages/gateway/src/entities/domain.ts | 4 ++-- packages/gateway/src/handlers/address.ts | 5 +++-- packages/gateway/src/handlers/domain.ts | 2 +- packages/gateway/src/handlers/text.ts | 3 ++- packages/gateway/src/repositories/memory.ts | 4 ++-- packages/gateway/src/types/dtos.ts | 4 ++-- 7 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts diff --git a/packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts b/packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts new file mode 100644 index 00000000..ade53a8d --- /dev/null +++ b/packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class TTLAsString1728493485670 implements MigrationInterface { + name = 'TTLAsString1728493485670' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) + await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" bigint NOT NULL`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) + await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" integer NOT NULL`) + } +} diff --git a/packages/gateway/src/entities/domain.ts b/packages/gateway/src/entities/domain.ts index 9cf2f125..c6dc92d4 100644 --- a/packages/gateway/src/entities/domain.ts +++ b/packages/gateway/src/entities/domain.ts @@ -29,8 +29,8 @@ export class Domain { @Column({ nullable: true, length: 32 }) contenthash?: `0x${string}` - @Column() - ttl: number + @Column({ type: 'bigint' }) + ttl: string @OneToMany(() => Address, (addr) => addr.domain, { cascade: true, diff --git a/packages/gateway/src/handlers/address.ts b/packages/gateway/src/handlers/address.ts index 671c496e..6231ab1e 100644 --- a/packages/gateway/src/handlers/address.ts +++ b/packages/gateway/src/handlers/address.ts @@ -89,7 +89,7 @@ export function withGetAddr(repo: ReadRepository): ccip.HandlerDescription { if (addr) return { data: [addr.value], - extraData: formatTTL(addr.ttl), + extraData: formatTTL(parseInt(addr.ttl)), } }, } @@ -102,7 +102,8 @@ export function withGetAddrByCoin( type: 'addr(bytes32 node, uint256 coinType)', func: async ({ node, coinType: coin }) => { const addr = await repo.getAddr({ node, coin: coin.toString() }) - if (addr) return { data: [addr.value], extraData: formatTTL(addr.ttl) } + if (addr) + return { data: [addr.value], extraData: formatTTL(parseInt(addr.ttl)) } }, } } diff --git a/packages/gateway/src/handlers/domain.ts b/packages/gateway/src/handlers/domain.ts index 799be0d2..ece2c218 100644 --- a/packages/gateway/src/handlers/domain.ts +++ b/packages/gateway/src/handlers/domain.ts @@ -136,7 +136,7 @@ export function withGetContentHash( if (content) return { data: [content.value], - extraData: formatTTL(content.ttl), + extraData: formatTTL(parseInt(content.ttl)), } }, } diff --git a/packages/gateway/src/handlers/text.ts b/packages/gateway/src/handlers/text.ts index 80356d87..178d9682 100644 --- a/packages/gateway/src/handlers/text.ts +++ b/packages/gateway/src/handlers/text.ts @@ -59,7 +59,8 @@ export function withGetText(repo: ReadRepository): ccip.HandlerDescription { type: 'text(bytes32 node, string key) view returns (string)', func: async ({ node, key }) => { const text = await repo.getText({ node, key }) - if (text) return { data: [text.value], extraData: formatTTL(text.ttl) } + if (text) + return { data: [text.value], extraData: formatTTL(parseInt(text.ttl)) } }, } } diff --git a/packages/gateway/src/repositories/memory.ts b/packages/gateway/src/repositories/memory.ts index f777665b..9df2a5db 100644 --- a/packages/gateway/src/repositories/memory.ts +++ b/packages/gateway/src/repositories/memory.ts @@ -194,7 +194,7 @@ export class InMemoryRepository { const domain = this.domains.get(node) let ttl = domain?.ttl if (!address) return - if (!domain || !ttl) ttl = 300 // default value + if (!domain || !ttl) ttl = '300' // default value return { value: address.address, ttl } } @@ -226,7 +226,7 @@ export class InMemoryRepository { const domain = this.domains.get(node) let ttl = domain?.ttl if (!text) return - if (!domain || !ttl) ttl = 300 // default value + if (!domain || !ttl) ttl = '300' // default value return { value: text.value, ttl } } diff --git a/packages/gateway/src/types/dtos.ts b/packages/gateway/src/types/dtos.ts index 6c33bae0..cd2b1685 100644 --- a/packages/gateway/src/types/dtos.ts +++ b/packages/gateway/src/types/dtos.ts @@ -3,7 +3,7 @@ import { PubKey } from '.' export type Response = { value: string - ttl: number + ttl: string } export type WritingProps = { @@ -69,5 +69,5 @@ export type SetPubkeyProps = NodeProps & export type GetPubkeyResponse = { value: PubKey - ttl: number + ttl: string } From 3034e9119b2b1d6decccdfaed3882fe3b5709296 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Wed, 9 Oct 2024 14:12:38 -0300 Subject: [PATCH 11/17] refactor: db resolver compliant to offchain resolver --- packages/client/src/write.ts | 4 +- packages/contracts/src/DatabaseResolver.sol | 6 +- packages/gateway/cmd/database.ts | 2 +- packages/gateway/cmd/ethereum.ts | 2 +- packages/gateway/cmd/metadata.ts | 2 +- packages/gateway/src/abi.ts | 3 +- packages/gateway/src/chain.ts | 22 ------ packages/gateway/src/handlers/domain.ts | 14 ++-- packages/gateway/src/resolvers/domain.ts | 13 +--- packages/gateway/src/utils.ts | 75 +++++++++++++++++++++ 10 files changed, 92 insertions(+), 51 deletions(-) delete mode 100644 packages/gateway/src/chain.ts create mode 100644 packages/gateway/src/utils.ts diff --git a/packages/client/src/write.ts b/packages/client/src/write.ts index e659c97a..db006262 100644 --- a/packages/client/src/write.ts +++ b/packages/client/src/write.ts @@ -34,7 +34,7 @@ let { RPC_URL: provider = 'http://127.0.0.1:8545/', L2_RPC_URL: providerL2 = 'http://127.0.0.1:8547', PRIVATE_KEY: - privateKey = '0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659', // local arbitrum PK + privateKey = '0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659', // local arbitrum PK } = process.env const chain = getChain(parseInt(chainId)) @@ -54,7 +54,7 @@ const _ = (async () => { throw new Error('RESOLVER_ADDRESS is required') } - const name = normalize('gibi.arb.eth') + const name = normalize('gibi.blockful.eth') const dnsName = toHex(packetToBytes(name)) const node = namehash(name) const signer = privateKeyToAccount(privateKey as Hex) diff --git a/packages/contracts/src/DatabaseResolver.sol b/packages/contracts/src/DatabaseResolver.sol index f7978784..70cc38ae 100644 --- a/packages/contracts/src/DatabaseResolver.sol +++ b/packages/contracts/src/DatabaseResolver.sol @@ -113,8 +113,7 @@ contract DatabaseResolver is /** * Forwards the registering of a domain to the L2 contracts - * @param -parentNode namehash of the parent node - * @param -label The name to be registered. + * @param -name DNS-encoded name to be registered. * @param -owner Owner of the domain * @param -duration duration The duration in seconds of the registration. * @param -secret The secret to be used for the registration based on commit/reveal @@ -125,8 +124,7 @@ contract DatabaseResolver is * @param -extraData any encoded additional data */ function register( - bytes32, /* parentNode */ - string calldata, /* name */ + bytes calldata, /* name */ address, /* owner */ uint256, /* duration */ bytes32, /* secret */ diff --git a/packages/gateway/cmd/database.ts b/packages/gateway/cmd/database.ts index 4802fbeb..78637ecc 100644 --- a/packages/gateway/cmd/database.ts +++ b/packages/gateway/cmd/database.ts @@ -22,7 +22,7 @@ import { withTransferDomain, } from '../src/handlers' import { abi } from '../src/abi' -import { getChain } from '../src/chain' +import { getChain } from '../src/utils' import { PostgresRepository } from '../src/repositories' import { withLogger, withSigner } from '../src/middlewares' import { NewDataSource } from '../src/datasources/postgres' diff --git a/packages/gateway/cmd/ethereum.ts b/packages/gateway/cmd/ethereum.ts index 6ee6b3ab..fe6f1068 100644 --- a/packages/gateway/cmd/ethereum.ts +++ b/packages/gateway/cmd/ethereum.ts @@ -10,7 +10,7 @@ import { abi } from '../src/abi' import { L1ProofService } from '../src/services' import { withLogger } from '../src/middlewares' import { withQuery, withGetStorageSlot } from '../src/handlers' -import { getChain } from '../src/chain' +import { getChain } from '../src/utils' config({ path: process.env.ENV_FILE || '../.env', diff --git a/packages/gateway/cmd/metadata.ts b/packages/gateway/cmd/metadata.ts index d71e802f..5735b12e 100644 --- a/packages/gateway/cmd/metadata.ts +++ b/packages/gateway/cmd/metadata.ts @@ -3,7 +3,7 @@ import { ApolloServer } from '@apollo/server' import { startStandaloneServer } from '@apollo/server/standalone' import { Hex, createPublicClient, getChainContractAddress, http } from 'viem' -import { getChain } from '../src/chain' +import { getChain } from '../src/utils' import { NewDataSource } from '../src/datasources/postgres' import { domainResolver } from '../src/resolvers' import { EthereumClient } from '../src/services' diff --git a/packages/gateway/src/abi.ts b/packages/gateway/src/abi.ts index 5fc03d5c..62699175 100644 --- a/packages/gateway/src/abi.ts +++ b/packages/gateway/src/abi.ts @@ -14,8 +14,7 @@ export const abi: string[] = [ 'function setPubkey(bytes32 node,bytes32 x, bytes32 y)', 'function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y)', 'function getStorageSlots(address addr, bytes32[] memory commands, bytes[] memory) external view returns(bytes memory witness)', - 'function registerParams(bytes memory name,uint256 duration) external view returns(uint256 price,uint256 commitTime,bytes memory extraData)', - 'function register(bytes32 parentNode, string calldata label, address owner, uint256 duration, bytes32 secret, address resolver, bytes[] calldata data, bool reverseRecord, uint16 fuses, bytes memory extraData)', + 'function register(bytes calldata name, address owner, uint256 duration, bytes32 secret, address resolver, bytes[] calldata data, bool reverseRecord, uint16 fuses, bytes memory extraData)', 'function transfer(bytes32 node, address owner)', 'function multicall(bytes[] calldata data) external returns (bytes[] memory results)', ] diff --git a/packages/gateway/src/chain.ts b/packages/gateway/src/chain.ts deleted file mode 100644 index 313a48e0..00000000 --- a/packages/gateway/src/chain.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { defineChain } from 'viem' -import * as chains from 'viem/chains' - -export function getChain(chainId: number): chains.Chain | undefined { - return [ - ...Object.values(chains), - defineChain({ - id: Number(chainId), - name: 'Arbitrum Local', - nativeCurrency: { - name: 'Arbitrum Sepolia Ether', - symbol: 'ETH', - decimals: 18, - }, - rpcUrls: { - default: { - http: ['http://127.0.0.1:8547'], - }, - }, - }), - ].find((chain) => chain.id === chainId) -} diff --git a/packages/gateway/src/handlers/domain.ts b/packages/gateway/src/handlers/domain.ts index ece2c218..c6c6e160 100644 --- a/packages/gateway/src/handlers/domain.ts +++ b/packages/gateway/src/handlers/domain.ts @@ -1,4 +1,4 @@ -import { concat, keccak256, labelhash } from 'viem' +import { namehash } from 'viem' import * as ccip from '@blockful/ccip-server' @@ -17,6 +17,7 @@ import { parseEncodedTextCalls, } from '../services' import { Domain } from '../entities' +import { decodeDNSName, extractParentFromName } from '../utils' interface WriteRepository { register(params: RegisterDomainProps) @@ -33,13 +34,14 @@ export function withRegisterDomain( repo: WriteRepository & ReadRepository, ): ccip.HandlerDescription { return { - type: 'register(bytes32 parentNode, string calldata label, address owner, uint256 duration, bytes32 secret, address resolver, bytes[] calldata data, bool reverseRecord, uint16 fuses, bytes memory extraData)', + type: 'register(bytes calldata name, address owner, uint256 duration, bytes32 secret, address resolver, bytes[] calldata data, bool reverseRecord, uint16 fuses, bytes memory extraData)', func: async ( - { parentNode, label, duration: ttl, owner, data }, + { name, duration: ttl, owner, data }, { signature }: { signature: TypedSignature }, ) => { try { - const node = keccak256(concat([parentNode, labelhash(label)])) + name = decodeDNSName(name) + const node = namehash(name) const existingDomain = await repo.getDomain({ node }) if (existingDomain) { @@ -50,11 +52,11 @@ export function withRegisterDomain( const texts = parseEncodedTextCalls(data, signature) await repo.register({ - name: label, + name, node, ttl: ttl.toString(), owner, - parent: parentNode, + parent: namehash(extractParentFromName(name)), resolver: signature.domain.verifyingContract, resolverVersion: signature.domain.version, addresses, diff --git a/packages/gateway/src/resolvers/domain.ts b/packages/gateway/src/resolvers/domain.ts index 702ff348..0ad28518 100644 --- a/packages/gateway/src/resolvers/domain.ts +++ b/packages/gateway/src/resolvers/domain.ts @@ -3,6 +3,7 @@ import { normalize } from 'viem/ens' import { DomainMetadata, NodeProps, GetDomainProps } from '../types' import { Address, Domain, Text } from '../entities' +import { extractLabelFromName, extractParentFromName } from '../utils' interface ReadRepository { getDomain(params: GetDomainProps): Promise @@ -112,18 +113,6 @@ export async function domainResolver({ } } -// gather the first part of the domain (e.g. floripa.blockful.eth -> floripa) -const extractLabelFromName = (name: string): string => { - const [, label] = /^(\w+)/.exec(name) || [] - return label -} - -// gather the last part of the domain (e.g. floripa.blockful.eth -> blockful.eth) -const extractParentFromName = (name: string): string => { - const [, parent] = /\w*\.(.*)$/.exec(name) || [] - return parent -} - // eslint-disable-next-line @typescript-eslint/no-explicit-any ;(BigInt.prototype as any).toJSON = function () { return this.toString() diff --git a/packages/gateway/src/utils.ts b/packages/gateway/src/utils.ts new file mode 100644 index 00000000..585a697e --- /dev/null +++ b/packages/gateway/src/utils.ts @@ -0,0 +1,75 @@ +import { defineChain } from 'viem' +import * as chains from 'viem/chains' + +export function getChain(chainId: number): chains.Chain | undefined { + return [ + ...Object.values(chains), + defineChain({ + id: Number(chainId), + name: 'Arbitrum Local', + nativeCurrency: { + name: 'Arbitrum Sepolia Ether', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['http://127.0.0.1:8547'], + }, + }, + }), + ].find((chain) => chain.id === chainId) +} + +// gather the first part of the domain (e.g. floripa.blockful.eth -> floripa) +export const extractLabelFromName = (name: string): string => { + const [, label] = /^(\w+)/.exec(name) || [] + return label +} + +// gather the last part of the domain (e.g. floripa.blockful.eth -> blockful.eth) +export const extractParentFromName = (name: string): string => { + const [, parent] = /\w*\.(.*)$/.exec(name) || [] + return parent +} + +export function decodeDNSName(hexString: string): string { + // Remove '0x' prefix if present + hexString = hexString.replace(/^0x/, '') + + // Convert hex string to byte array + const bytes = new Uint8Array( + hexString.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) ?? [], + ) + + if (bytes.length === 0) { + throw new Error('Invalid hex string: empty or malformed') + } + + const result: string[] = [] + let index = 0 + + while (index < bytes.length) { + const labelLength = bytes[index] + if (!labelLength) break // End of domain name + + index++ + const endIndex = index + labelLength + + if (endIndex > bytes.length) { + throw new Error( + 'Invalid DNS encoding: label length exceeds remaining bytes', + ) + } + + const label = new TextDecoder().decode(bytes.subarray(index, endIndex)) + result.push(label) + index = endIndex + } + + if (result.length === 0) { + throw new Error('Invalid DNS encoding: no labels found') + } + + return result.join('.') +} From 62c129e5bcad28cf1c09796ab3fcfa2375d46b55 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Wed, 9 Oct 2024 15:23:51 -0300 Subject: [PATCH 12/17] test: register with new arguments --- packages/client/test/db.e2e.spec.ts | 76 ++++++++++++++++++++++---- packages/gateway/test/api.spec.ts | 61 +++++++++++++++++---- packages/gateway/test/database.spec.ts | 64 ++++++++++++++++------ 3 files changed, 165 insertions(+), 36 deletions(-) diff --git a/packages/client/test/db.e2e.spec.ts b/packages/client/test/db.e2e.spec.ts index fa21e2c6..32278583 100644 --- a/packages/client/test/db.e2e.spec.ts +++ b/packages/client/test/db.e2e.spec.ts @@ -280,42 +280,55 @@ describe('DatabaseResolver', () => { describe('Subdomain created on database', async () => { const name = normalize('database.eth') const node = namehash(name) + const resolver = '0x6AEBB4AdC056F3B01d225fE34c20b1FdC21323A2' beforeEach(async () => { let domain = new Domain() domain.node = node domain.name = name domain.parent = namehash('eth') - domain.resolver = '0x6AEBB4AdC056F3B01d225fE34c20b1FdC21323A2' + domain.resolver = resolver domain.resolverVersion = '1' domain.owner = owner.address - domain.ttl = 300 + domain.ttl = '300' domain = await datasource.manager.save(domain) }) it('should register new domain', async () => { const name = normalize('newdomain.eth') + const dnsName = toHex(packetToBytes(name)) const node = namehash(name) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, - args: [toHex(name), 300, owner.address, []], + args: [ + dnsName, + owner.address, + 300n, + zeroHash, + resolver, + [], + false, + 0, + zeroHash, + ], universalResolverAddress, signer: owner, }) expect(response?.status).equal(200) - const d = await datasource.getRepository(Domain).countBy({ + const actual = await datasource.getRepository(Domain).countBy({ node, owner: owner.address, }) - expect(d).eq(1) + expect(actual).eq(1) }) it('should register new domain with records', async () => { const name = normalize('newdomain.eth') + const dnsName = toHex(packetToBytes(name)) const node = namehash(name) const calldata = [ encodeFunctionData({ @@ -338,7 +351,17 @@ describe('DatabaseResolver', () => { name, functionName: 'register', abi: abiDBResolver, - args: [toHex(name), 300, owner.address, calldata], + args: [ + dnsName, + owner.address, + 300n, + zeroHash, + resolver, + calldata, + false, + 0, + zeroHash, + ], universalResolverAddress, signer: owner, }) @@ -373,11 +396,22 @@ describe('DatabaseResolver', () => { }) it('should block register of duplicated domain with same owner', async () => { + const dnsName = toHex(packetToBytes(name)) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, - args: [toHex(name), 300, owner.address, []], + args: [ + dnsName, + owner.address, + 300n, + zeroHash, + resolver, + [], + false, + 0, + zeroHash, + ], universalResolverAddress, signer: owner, }) @@ -393,11 +427,22 @@ describe('DatabaseResolver', () => { it('should block register of duplicated domain with different owner', async () => { const newOwner = privateKeyToAccount(generatePrivateKey()) + const dnsName = toHex(packetToBytes(name)) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, - args: [toHex(name), 300, newOwner.address, []], + args: [ + dnsName, + newOwner.address, + 300n, + zeroHash, + resolver, + [], + false, + 0, + zeroHash, + ], universalResolverAddress, signer: newOwner, }) @@ -425,12 +470,23 @@ describe('DatabaseResolver', () => { it('should allow register a domain with different owner', async () => { const newOwner = privateKeyToAddress(generatePrivateKey()) const name = normalize('newdomain.eth') + const dnsName = toHex(packetToBytes(name)) const node = namehash(name) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, - args: [toHex(name), 300, newOwner, []], + args: [ + dnsName, + newOwner, + 300n, + zeroHash, + resolver, + [], + false, + 0, + zeroHash, + ], universalResolverAddress, signer: owner, }) @@ -1124,7 +1180,7 @@ describe('DatabaseResolver', () => { const d = new Domain() d.name = 'd1.public.eth' d.node = namehash('d1') - d.ttl = 300 + d.ttl = '300' d.parent = node d.resolver = '0xresolver' d.resolverVersion = '1' diff --git a/packages/gateway/test/api.spec.ts b/packages/gateway/test/api.spec.ts index d47e8f5f..be9ed3fb 100644 --- a/packages/gateway/test/api.spec.ts +++ b/packages/gateway/test/api.spec.ts @@ -19,8 +19,9 @@ import { toHex, Address as viemAddress, stringToHex, + zeroHash, } from 'viem' -import { namehash } from 'viem/ens' +import { namehash, packetToBytes } from 'viem/ens' import { generatePrivateKey, privateKeyToAddress } from 'viem/accounts' import request from 'supertest' @@ -74,7 +75,7 @@ describe('Gateway API', () => { node: namehash('public.eth'), parent: namehash('eth'), owner, - ttl: 300, + ttl: '300', contenthash: '0x4d1ae8fa44de34a527a9c6973d37dfda8befc18ca6ec73fd97535b4cf02189c6', // public goods addresses: [], @@ -109,12 +110,22 @@ describe('Gateway API', () => { resolver: TEST_ADDRESS, resolverVersion: '1', owner, - ttl: 300, + ttl: '300', addresses: [], texts: [], } - const args = [toHex(domain.name), domain.ttl, owner, []] + const args = [ + toHex(packetToBytes(domain.name)), + owner, + 300n, + zeroHash, + TEST_ADDRESS, + [], + false, + 0, + zeroHash, + ] const data = encodeFunctionData({ abi, functionName: 'register', @@ -150,7 +161,17 @@ describe('Gateway API', () => { server.add(serverAbi, withRegisterDomain(repo)) const app = server.makeApp('/') - const args = [toHex(domain.name), domain.ttl, owner, []] + const args = [ + toHex(packetToBytes(domain.name)), + owner, + 300n, + zeroHash, + TEST_ADDRESS, + [], + false, + 0, + zeroHash, + ] const data = encodeFunctionData({ abi, functionName: 'register', @@ -197,12 +218,22 @@ describe('Gateway API', () => { resolver: TEST_ADDRESS, resolverVersion: '1', owner: newOwner, - ttl: 300, + ttl: '300', addresses: [], texts: [], } - const args = [toHex(domain.name), domain.ttl, newOwner, []] + const args = [ + toHex(packetToBytes(domain.name)), + newOwner, + 300n, + zeroHash, + TEST_ADDRESS, + [], + false, + 0, + zeroHash, + ] const data = encodeFunctionData({ abi, functionName: 'register', @@ -248,7 +279,7 @@ describe('Gateway API', () => { resolver: TEST_ADDRESS, resolverVersion: '1', owner, - ttl: 300, + ttl: '300', addresses: [ { address: '0x3a872f8fed4421e7d5be5c98ab5ea0e0245169a0', @@ -297,7 +328,17 @@ describe('Gateway API', () => { ], }), ] - const args = [toHex(domain.name), domain.ttl, owner, calldata] + const args = [ + toHex(packetToBytes(domain.name)), + owner, + 300n, + zeroHash, + TEST_ADDRESS, + calldata, + false, + 0, + zeroHash, + ] const data = encodeFunctionData({ abi, functionName: 'register', @@ -491,7 +532,7 @@ describe('Gateway API', () => { }), ).toEqual(domain.contenthash) expect(parseInt(ttl.toString())).toBeCloseTo( - parseInt(formatTTL(domain.ttl)), + parseInt(formatTTL(parseInt(domain.ttl))), ) }) }) diff --git a/packages/gateway/test/database.spec.ts b/packages/gateway/test/database.spec.ts index 751fad6f..61dda095 100644 --- a/packages/gateway/test/database.spec.ts +++ b/packages/gateway/test/database.spec.ts @@ -16,8 +16,8 @@ import { assert, } from 'vitest' import * as ccip from '@blockful/ccip-server' -import { Hex, encodeFunctionData, pad, parseAbi, toHex } from 'viem' -import { namehash } from 'viem/ens' +import { Hex, encodeFunctionData, pad, parseAbi, toHex, zeroHash } from 'viem' +import { namehash, packetToBytes } from 'viem/ens' import { generatePrivateKey, privateKeyToAddress } from 'viem/accounts' import { doCall } from './helper' @@ -86,7 +86,17 @@ describe('Gateway Database', () => { sender: TEST_ADDRESS, method: 'register', pvtKey, - args: [toHex(name), 300, owner, []], + args: [ + toHex(packetToBytes(name)), + owner, + 300n, + zeroHash, + TEST_ADDRESS, + [], + false, + 0, + zeroHash, + ], }) const d = await datasource.getRepository(Domain).findOneBy({ @@ -106,7 +116,7 @@ describe('Gateway Database', () => { const domain = new Domain() domain.name = 'public.eth' domain.node = namehash('public.eth') - domain.ttl = 300 + domain.ttl = '300' domain.owner = owner domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS @@ -121,7 +131,17 @@ describe('Gateway Database', () => { sender: TEST_ADDRESS, method: 'register', pvtKey, - args: [toHex(domain.name), 400, owner, []], + args: [ + toHex(packetToBytes(domain.name)), + owner, + 300n, + zeroHash, + TEST_ADDRESS, + [], + false, + 0, + zeroHash, + ], }) expect(result.data.length).toEqual(0) @@ -164,7 +184,17 @@ describe('Gateway Database', () => { sender: TEST_ADDRESS, method: 'register', pvtKey, - args: [toHex(name), 300, owner, calldata], + args: [ + toHex(packetToBytes(name)), + owner, + 300n, + zeroHash, + TEST_ADDRESS, + calldata, + false, + 0, + zeroHash, + ], }) const actual = await datasource.getRepository(Domain).findOneBy({ @@ -208,7 +238,7 @@ describe('Gateway Database', () => { domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS domain.resolverVersion = '1' - domain.ttl = 300 + domain.ttl = '300' domain.owner = privateKeyToAddress(pvtKey) await datasource.manager.save(domain) @@ -274,7 +304,7 @@ describe('Gateway Database', () => { domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS domain.resolverVersion = '1' - domain.ttl = 300 + domain.ttl = '300' domain.owner = privateKeyToAddress(pvtKey) await datasource.manager.save(domain) @@ -310,7 +340,7 @@ describe('Gateway Database', () => { domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS domain.resolverVersion = '1' - domain.ttl = 300 + domain.ttl = '300' domain.owner = privateKeyToAddress(generatePrivateKey()) await datasource.manager.save(domain) const content = @@ -332,7 +362,7 @@ describe('Gateway Database', () => { const [value] = result.data expect(value).toEqual(content) expect(parseInt(result.ttl!)).toBeCloseTo( - parseInt(formatTTL(domain.ttl)), + parseInt(formatTTL(parseInt(domain.ttl))), ) }) @@ -362,7 +392,7 @@ describe('Gateway Database', () => { domain = new Domain() domain.name = 'public.eth' domain.node = namehash(domain.name) - domain.ttl = 300 + domain.ttl = '300' domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS domain.resolverVersion = '1' @@ -514,7 +544,7 @@ describe('Gateway Database', () => { const [avatar] = result.data expect(avatar).toEqual('blockful.png') expect(parseInt(result.ttl!)).toBeCloseTo( - parseInt(formatTTL(domain.ttl)), + parseInt(formatTTL(parseInt(domain.ttl))), 2, ) }) @@ -578,7 +608,7 @@ describe('Gateway Database', () => { domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS domain.resolverVersion = '1' - domain.ttl = 300 + domain.ttl = '300' pvtKey = generatePrivateKey() domain.owner = privateKeyToAddress(pvtKey) await datasource.manager.save(domain) @@ -702,7 +732,9 @@ describe('Gateway Database', () => { expect(result.data.length).toEqual(1) const [value] = result.data expect(value).toEqual('0x1234567890123456789012345678901234567890') - expect(parseInt(result.ttl!)).toBeCloseTo(parseInt(formatTTL(domain.ttl))) + expect(parseInt(result.ttl!)).toBeCloseTo( + parseInt(formatTTL(parseInt(domain.ttl))), + ) }) }) @@ -716,7 +748,7 @@ describe('Gateway Database', () => { domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS domain.resolverVersion = '1' - domain.ttl = 2000 + domain.ttl = '300' pvtKey = generatePrivateKey() domain.owner = privateKeyToAddress(pvtKey) domain = await datasource.manager.save(domain) @@ -835,7 +867,7 @@ describe('Gateway Database', () => { beforeEach(async () => { domain = new Domain() domain.node = namehash('public.eth') as `0x${string}` - domain.ttl = 2000 + domain.ttl = '300' domain.name = 'public.eth' domain.parent = namehash('eth') domain.resolver = TEST_ADDRESS From 701a41ed76df38a17377641a27977073b0f9d1e5 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Wed, 9 Oct 2024 16:38:34 -0300 Subject: [PATCH 13/17] chore: deploy latest version of the OffchainResolver --- Makefile | 5 ++--- README.md | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2bc5de03..57d2467a 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,6 @@ script_dir := packages/contracts/script deploy_dir := $(script_dir)/deploy PRIVATE_KEY?=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -L2_PRIVATE_KEY?=0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 ETHERSCAN_API_KEY?=VEJ7GISNRKFUESRPC4W4D3ZEM2P9B4J6C4 .PHONY: deploy-arb @@ -34,7 +33,7 @@ deploy-arb-resolver: --rpc-url arb_sepolia \ --broadcast \ -vvv \ - --private-key $(L2_PRIVATE_KEY) \ + --private-key $(PRIVATE_KEY) \ --verify; @@ -47,7 +46,7 @@ deploy-arb-full: --rpc-url arb_sepolia \ --broadcast \ -vvv \ - --private-key $(L2_PRIVATE_KEY) \ + --private-key $(PRIVATE_KEY) \ --verify \ && \ ) true; \ diff --git a/README.md b/README.md index b05b6f7f..e272a146 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,28 @@ This project not only makes ENS more efficient and cost-effective but also opens - **Increase Usability**: Make ENS more user-friendly and accessible. - **Reference implementation**: Create a reference on how to implement off-chain storage and management. +## Deployments + +### Mainnet + +| Contract | Network | Address | +| ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------- | +| DatabaseResolver | Ethereum | [0xBF3F57862717099319285c1E2664Cd583f35E333](https://etherscan.io/address/0xBF3F57862717099319285c1E2664Cd583f35E333) | + +### Sepolia + +| Contract | Network | Address | +| --------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- | +| ArbitrumVerifier | Ethereum | [0x8fc4a214705e3c40032e99f867d964c012bf8efb](https://sepolia.etherscan.io/address/0x8fc4a214705e3c40032e99f867d964c012bf8efb) | +| L1Resolver | Ethereum | [0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8](https://sepolia.etherscan.io/address/0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8) | +| ENSRegistry | Arbitrum | [0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50](https://sepolia.arbiscan.io/address/0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50) | +| ReverseRegistrar | Arbitrum | [0xb3c9ff08671bbadddd0436cc46fbfa005c8da0a7](https://sepolia.arbiscan.io/address/0xb3c9ff08671bbadddd0436cc46fbfa005c8da0a7) | +| BaseRegistrarImplementation | Arbitrum | [0x41eedE073217084A30f6f3Bc2c546BDa1F08b5ca](https://sepolia.arbiscan.io/address/0x41eedE073217084A30f6f3Bc2c546BDa1F08b5ca) | +| NameWrapper | Arbitrum | [0xff4f34ac12a84de527cf9e24856fc8d7c42cc379](https://sepolia.arbiscan.io/address/0xff4f34ac12a84de527cf9e24856fc8d7c42cc379) | +| ETHRegistrarController | Arbitrum | [0x263c644d8f5d4bdb44cfab020491ec6fc4ca5271](https://sepolia.arbiscan.io/address/0x263c644d8f5d4bdb44cfab020491ec6fc4ca5271) | +| SubdomainController | Arbitrum | [0x41eede073217084a30f6f3bc2c546bda1f08b5ca](https://sepolia.arbiscan.io/address/0x41eede073217084a30f6f3bc2c546bda1f08b5ca) | +| PublicResolver | Arbitrum | [0x0a33f065c9c8f0F5c56BB84b1593631725F0f3af](https://sepolia.arbiscan.io/address/0x0a33f065c9c8f0F5c56BB84b1593631725F0f3af) | + ## Components The External Resolver consists of three main components, each of them is a self-contained project with its own set of files and logic, ensuring seamless integration and collaboration between them. This modular architecture allows for flexibility and customization, making the External Resolver a versatile solution for various use cases. From 0d68dfe1740de63c7512306dc0ae543c4779c21b Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Thu, 10 Oct 2024 09:46:24 -0300 Subject: [PATCH 14/17] fix: add default ttl value on migration --- .../datasources/migrations/1728493485670-TTLAsString.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts b/packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts index ade53a8d..b42c7c0f 100644 --- a/packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts +++ b/packages/gateway/src/datasources/migrations/1728493485670-TTLAsString.ts @@ -5,11 +5,15 @@ export class TTLAsString1728493485670 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) - await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" bigint NOT NULL`) + await queryRunner.query( + `ALTER TABLE "domain" ADD "ttl" bigint NOT NULL DEFAULT 600`, + ) } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query(`ALTER TABLE "domain" DROP COLUMN "ttl"`) - await queryRunner.query(`ALTER TABLE "domain" ADD "ttl" integer NOT NULL`) + await queryRunner.query( + `ALTER TABLE "domain" ADD "ttl" integer NOT NULL DEFAULT 600`, + ) } } From 257879e706de43495930b072c158f11fd239fb59 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Thu, 10 Oct 2024 09:46:42 -0300 Subject: [PATCH 15/17] chore: add database resolver address to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e272a146..b4688db7 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ This project not only makes ENS more efficient and cost-effective but also opens | Contract | Network | Address | | --------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- | +| DatabaseResolver | Ethereum | [0xc1D4903Eba794035d2D81D210325b57a95C8a007](https://sepolia.etherscan.io/address/0xc1D4903Eba794035d2D81D210325b57a95C8a007) | | ArbitrumVerifier | Ethereum | [0x8fc4a214705e3c40032e99f867d964c012bf8efb](https://sepolia.etherscan.io/address/0x8fc4a214705e3c40032e99f867d964c012bf8efb) | | L1Resolver | Ethereum | [0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8](https://sepolia.etherscan.io/address/0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8) | | ENSRegistry | Arbitrum | [0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50](https://sepolia.arbiscan.io/address/0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50) | From 5bc59915e5aa4dfaaec921b14d5efcfbf0689442 Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Mon, 21 Oct 2024 14:42:10 -0300 Subject: [PATCH 16/17] refactor: dnsName to encodedName --- packages/client/src/l2.write.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/client/src/l2.write.ts b/packages/client/src/l2.write.ts index f1ccc15d..b03ffcdf 100644 --- a/packages/client/src/l2.write.ts +++ b/packages/client/src/l2.write.ts @@ -32,8 +32,7 @@ let { CHAIN_ID: chainId = '31337', RPC_URL: provider = 'http://127.0.0.1:8545/', L2_RPC_URL: providerL2 = 'http://127.0.0.1:8547', - PRIVATE_KEY: - privateKey = '0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659', // local arbitrum PK + PRIVATE_KEY: privateKey, } = process.env const chain = getChain(parseInt(chainId)) @@ -54,7 +53,7 @@ const _ = (async () => { } const name = normalize('gibi.arb.eth') - const dnsName = toHex(packetToBytes(name)) + const encodedName = toHex(packetToBytes(name)) const node = namehash(name) const signer = privateKeyToAccount(privateKey as Hex) @@ -69,7 +68,7 @@ const _ = (async () => { address: universalResolver as Hex, functionName: 'findResolver', abi: uAbi, - args: [dnsName], + args: [encodedName], })) as Hash[] const duration = 31556952000n @@ -108,7 +107,7 @@ const _ = (async () => { functionName: 'register', abi: l1Abi, args: [ - dnsName, // name + encodedName, // name signer.address, // owner duration, `0x${'a'.repeat(64)}` as Hex, // secret From f341b0ac66400215118f51ea78ebef70cff0719a Mon Sep 17 00:00:00 2001 From: lucas picollo Date: Mon, 21 Oct 2024 14:48:57 -0300 Subject: [PATCH 17/17] refactor: dnsName to encodedName --- README.md | 2 +- packages/client/src/write.ts | 14 +++++++------- packages/client/test/db.e2e.spec.ts | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b4688db7..457cc60c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This project not only makes ENS more efficient and cost-effective but also opens | L1Resolver | Ethereum | [0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8](https://sepolia.etherscan.io/address/0xF0c1d78C73B2fCBF17e1c4DbBBD9df30a9556BB8) | | ENSRegistry | Arbitrum | [0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50](https://sepolia.arbiscan.io/address/0x8d55e297c37993ebbd2e7a8d7688f7e5b35f1b50) | | ReverseRegistrar | Arbitrum | [0xb3c9ff08671bbadddd0436cc46fbfa005c8da0a7](https://sepolia.arbiscan.io/address/0xb3c9ff08671bbadddd0436cc46fbfa005c8da0a7) | -| BaseRegistrarImplementation | Arbitrum | [0x41eedE073217084A30f6f3Bc2c546BDa1F08b5ca](https://sepolia.arbiscan.io/address/0x41eedE073217084A30f6f3Bc2c546BDa1F08b5ca) | +| BaseRegistrarImplementation | Arbitrum | [0x2C6a113C513fa0fd404abcCE3aC8a4BE16ccb651](https://sepolia.arbiscan.io/address/0x2C6a113C513fa0fd404abcCE3aC8a4BE16ccb651) | | NameWrapper | Arbitrum | [0xff4f34ac12a84de527cf9e24856fc8d7c42cc379](https://sepolia.arbiscan.io/address/0xff4f34ac12a84de527cf9e24856fc8d7c42cc379) | | ETHRegistrarController | Arbitrum | [0x263c644d8f5d4bdb44cfab020491ec6fc4ca5271](https://sepolia.arbiscan.io/address/0x263c644d8f5d4bdb44cfab020491ec6fc4ca5271) | | SubdomainController | Arbitrum | [0x41eede073217084a30f6f3bc2c546bda1f08b5ca](https://sepolia.arbiscan.io/address/0x41eede073217084a30f6f3bc2c546bda1f08b5ca) | diff --git a/packages/client/src/write.ts b/packages/client/src/write.ts index db006262..0c59a2b8 100644 --- a/packages/client/src/write.ts +++ b/packages/client/src/write.ts @@ -14,6 +14,7 @@ import { namehash, toHex, walletActions, + zeroHash, } from 'viem' import { normalize, packetToBytes } from 'viem/ens' import { privateKeyToAccount } from 'viem/accounts' @@ -33,8 +34,7 @@ let { CHAIN_ID: chainId = '31337', RPC_URL: provider = 'http://127.0.0.1:8545/', L2_RPC_URL: providerL2 = 'http://127.0.0.1:8547', - PRIVATE_KEY: - privateKey = '0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659', // local arbitrum PK + PRIVATE_KEY: privateKey, } = process.env const chain = getChain(parseInt(chainId)) @@ -55,7 +55,7 @@ const _ = (async () => { } const name = normalize('gibi.blockful.eth') - const dnsName = toHex(packetToBytes(name)) + const encodedName = toHex(packetToBytes(name)) const node = namehash(name) const signer = privateKeyToAccount(privateKey as Hex) @@ -70,7 +70,7 @@ const _ = (async () => { address: universalResolver as Hex, functionName: 'findResolver', abi: uAbi, - args: [dnsName], + args: [encodedName], })) as Hash[] const duration = 31556952000n @@ -115,15 +115,15 @@ const _ = (async () => { functionName: 'register', abi: l1Abi, args: [ - dnsName, // name + encodedName, signer.address, // owner duration, - `0x${'a'.repeat(64)}` as Hex, // secret + zeroHash, resolver, data, // records calldata false, // reverseRecord 0, // fuses - `0x${'a'.repeat(64)}` as Hex, // extraData + zeroHash, ], address: resolverAddr, account: signer, diff --git a/packages/client/test/db.e2e.spec.ts b/packages/client/test/db.e2e.spec.ts index 32278583..a3f61ce0 100644 --- a/packages/client/test/db.e2e.spec.ts +++ b/packages/client/test/db.e2e.spec.ts @@ -296,14 +296,14 @@ describe('DatabaseResolver', () => { it('should register new domain', async () => { const name = normalize('newdomain.eth') - const dnsName = toHex(packetToBytes(name)) + const encodedName = toHex(packetToBytes(name)) const node = namehash(name) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, args: [ - dnsName, + encodedName, owner.address, 300n, zeroHash, @@ -328,7 +328,7 @@ describe('DatabaseResolver', () => { it('should register new domain with records', async () => { const name = normalize('newdomain.eth') - const dnsName = toHex(packetToBytes(name)) + const encodedName = toHex(packetToBytes(name)) const node = namehash(name) const calldata = [ encodeFunctionData({ @@ -352,7 +352,7 @@ describe('DatabaseResolver', () => { functionName: 'register', abi: abiDBResolver, args: [ - dnsName, + encodedName, owner.address, 300n, zeroHash, @@ -396,13 +396,13 @@ describe('DatabaseResolver', () => { }) it('should block register of duplicated domain with same owner', async () => { - const dnsName = toHex(packetToBytes(name)) + const encodedName = toHex(packetToBytes(name)) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, args: [ - dnsName, + encodedName, owner.address, 300n, zeroHash, @@ -427,13 +427,13 @@ describe('DatabaseResolver', () => { it('should block register of duplicated domain with different owner', async () => { const newOwner = privateKeyToAccount(generatePrivateKey()) - const dnsName = toHex(packetToBytes(name)) + const encodedName = toHex(packetToBytes(name)) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, args: [ - dnsName, + encodedName, newOwner.address, 300n, zeroHash, @@ -470,14 +470,14 @@ describe('DatabaseResolver', () => { it('should allow register a domain with different owner', async () => { const newOwner = privateKeyToAddress(generatePrivateKey()) const name = normalize('newdomain.eth') - const dnsName = toHex(packetToBytes(name)) + const encodedName = toHex(packetToBytes(name)) const node = namehash(name) const response = await offchainWriting({ name, functionName: 'register', abi: abiDBResolver, args: [ - dnsName, + encodedName, newOwner, 300n, zeroHash,