Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

247 refactor isolate backend calls using custom hooks #249

Draft
wants to merge 9 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BackButton, BlockchainCTA } from "@/components/atoms";
import { setDomainRecords } from "@/lib/utils/blockchain-txs";
import { setDomainRecords } from "@/ens-sdk";
import { useNameRegistration } from "@/lib/name-registration/useNameRegistration";
import {
TransactionErrorType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BackButton, BlockchainCTA } from "@/components/atoms";
import { register } from "@/lib/utils/blockchain-txs";
import { register } from "@/ens-sdk";
import { useNameRegistration } from "@/lib/name-registration/useNameRegistration";
import { TransactionErrorType } from "@/lib/wallet/txError";
import { PublicClient, TransactionReceipt } from "viem";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BackButton, BlockchainCTA } from "@/components/atoms";
import { setDomainAsPrimaryName } from "@/lib/utils/blockchain-txs";
import { setDomainAsPrimaryName } from "@/ens-sdk";
import { useNameRegistration } from "@/lib/name-registration/useNameRegistration";
import {
TransactionErrorType,
Expand Down
11 changes: 6 additions & 5 deletions components/molecules/registration/RegistrationSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ import {
EthIcon,
InfoCircleIcon,
} from "@/components/atoms";
import {
getGasPrice,
getNamePrice,
getNameRegistrationGasEstimate,
} from "@/lib/utils/blockchain-txs";

import { useEffect, useState } from "react";
import { formatEther, PublicClient } from "viem";
import { usePublicClient } from "wagmi";
import { ClientWithEns } from "@ensdomains/ensjs/dist/types/contracts/consts";
import {
getGasPrice,
getNamePrice,
getNameRegistrationGasEstimate,
} from "@/ens-sdk";

export const RegistrationSummary = () => {
const {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Button, WalletSVG } from "@ensdomains/thorin";
import { Button } from "@ensdomains/thorin";
import {
BackButton,
BlockchainCTA,
TransactionConfirmedInBlockchainCTA,
} from "@/components/atoms";
import { commit } from "@/lib/utils/blockchain-txs";
import { useNameRegistration } from "@/lib/name-registration/useNameRegistration";
import { useAccount, useBalance, usePublicClient } from "wagmi";
import { TransactionErrorType } from "@/lib/wallet/txError";
import { setNameRegistrationInLocalStorage } from "@/lib/name-registration/localStorage";
import { PublicClient } from "viem";
import { ClientWithEns } from "@ensdomains/ensjs/dist/types/contracts/consts";
import { commit } from "@/ens-sdk";

interface RequestToRegisterComponentProps {
handlePreviousStep: () => void;
Expand Down
2 changes: 1 addition & 1 deletion components/organisms/CreateSubdomainModalContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createSubdomain } from "@/lib/create-subdomain/service";
import { createSubdomain } from "@/ens-sdk";
import { Button, Input, Spinner } from "@ensdomains/thorin";
import { buildENSName } from "@namehash/ens-utils";
import { normalize } from "viem/ens";
Expand Down
2 changes: 1 addition & 1 deletion components/organisms/EditModalContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
TransactionErrorType,
getBlockchainTransactionError,
} from "@/lib/wallet/txError";
import { setDomainRecords } from "@/lib/utils/blockchain-txs";
import { setDomainRecords } from "@/ens-sdk";
import { buildENSName } from "@namehash/ens-utils";
import { getResolver } from "@ensdomains/ensjs/public";
import { useAccount, usePublicClient } from "wagmi";
Expand Down
115 changes: 115 additions & 0 deletions ens-sdk/ensOperations/commit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import ETHRegistrarABI from "@/lib/abi/eth-registrar.json";
import {
DEFAULT_REGISTRATION_DOMAIN_CONTROLLED_FUSES,
nameRegistrationSmartContracts,
} from "../../lib/name-registration/constants";

import {
publicActions,
createWalletClient,
custom,
Address,
Chain,
} from "viem";
import { SupportedNetwork } from "../../lib/wallet/chains";
import { ENSName } from "@namehash/ens-utils";
import {
TransactionErrorType,
getBlockchainTransactionError,
} from "../../lib/wallet/txError";
import { getNameRegistrationSecret } from "@/lib/name-registration/localStorage";
import { parseAccount } from "viem/utils";

import { EnsPublicClient } from "../types";
import { makeCommitment } from "./makeCommitment";

const walletConnectProjectId =
process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID;

if (!walletConnectProjectId) {
throw new Error("No wallet connect project ID informed");
}

/*
1st step of a name registration
*/

interface CommitParams {
ensName: ENSName;
durationInYears: bigint;
resolverAddress: Address;
authenticatedAddress: Address;
registerAndSetAsPrimaryName: boolean;
publicClient: EnsPublicClient;
chain: Chain;
}

/**
* Commits to registering an ENS name
*
* This is the first step in the two-step ENS registration process. It creates and submits
* a commitment to the blockchain, which must be followed by the actual registration after
* a waiting period.
*
* @param {CommitParams} params - The parameters for the commit operation
* @returns {Promise<`0x${string}` | TransactionErrorType>} - The transaction hash or an error
*/
export const commit = async ({
ensName,
durationInYears,
resolverAddress,
authenticatedAddress,
registerAndSetAsPrimaryName,
publicClient,
chain,
}: CommitParams): Promise<`0x${string}` | TransactionErrorType> => {
try {
const walletClient = createWalletClient({
account: authenticatedAddress,
chain: chain,
transport: custom(window.ethereum),
});

const client = walletClient.extend(publicActions);

if (!client) throw new Error("WalletClient not found");

const nameWithoutTLD = ensName.name.replace(".eth", "");

const commitmentWithConfigHash = await makeCommitment({
name: nameWithoutTLD,
data: [],
authenticatedAddress,
durationInYears: durationInYears,
secret: getNameRegistrationSecret(),
reverseRecord: registerAndSetAsPrimaryName,
resolverAddress: resolverAddress,
ownerControlledFuses: DEFAULT_REGISTRATION_DOMAIN_CONTROLLED_FUSES,
publicClient: publicClient,
});

if (!Object.values(SupportedNetwork).includes(chain.id)) {
throw new Error(`Unsupported network: ${chain.id}`);
}

const nameRegistrationContracts =
nameRegistrationSmartContracts[chain.id as SupportedNetwork];

const { request } = await client.simulateContract({
account: parseAccount(authenticatedAddress),
address: nameRegistrationContracts.ETH_REGISTRAR,
args: [commitmentWithConfigHash],
functionName: "commit",
abi: ETHRegistrarABI,
gas: 70000n,
});

const txHash = await client.writeContract(request);

return txHash;
} catch (error) {
console.error(error);
const errorType = getBlockchainTransactionError(error);
return errorType;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,28 @@ import {
Chain,
createWalletClient,
custom,
defineChain,
encodeFunctionData,
fromBytes,
Hash,
Hex,
keccak256,
namehash,
publicActions,
PublicClient,
stringToHex,
toHex,
} from "viem";
import { getRevertErrorData, handleDBStorage } from "../utils/blockchain-txs";
import { DomainData, MessageData } from "../utils/types";
import L1ResolverABI from "../abi/arbitrum-resolver.json";
import { EnsPublicClient, storeDataInDb } from "@/ens-sdk";
import { DomainData, MessageData } from "@/lib/utils/types";
import L1ResolverABI from "../../lib/abi/arbitrum-resolver.json";
import toast from "react-hot-toast";
import { getCoderByCoinName } from "@ensdomains/address-encoder";
import { ClientWithEns } from "@ensdomains/ensjs/dist/types/contracts/consts";
import * as chains from "viem/chains";
import { packetToBytes } from "viem/ens";
import { SECONDS_PER_YEAR } from "@namehash/ens-utils";
import { getNameRegistrationSecret } from "../name-registration/localStorage";
import { DEFAULT_REGISTRATION_DOMAIN_CONTROLLED_FUSES } from "../name-registration/constants";
import { getNameRegistrationSecret } from "../../lib/name-registration/localStorage";
import { DEFAULT_REGISTRATION_DOMAIN_CONTROLLED_FUSES } from "../../lib/name-registration/constants";
import { getChain } from "../utils";
import { getRevertErrorData } from "../utils/getRevertErrorData";

interface CreateSubdomainArgs {
resolverAddress: Address;
Expand All @@ -34,11 +33,27 @@ interface CreateSubdomainArgs {
address: string;
website: string;
description: string;
client: PublicClient & ClientWithEns;
client: EnsPublicClient;
chain: Chain;
}

// TO-DO: Fix function later to accept more text / address params
/**
* Creates a subdomain with associated records (website, description, and address) for an ENS name.
* This function is specifically designed to handle offchain and L2 domains.
*
* The function performs the following steps:
* 1. Prepares call data for setting text records (website and description) if provided.
* 2. Prepares call data for setting the address record if provided.
* 3. Calculates the registration fee and retrieves necessary parameters from the resolver contract.
* 4. Attempts to simulate the contract call for subdomain creation.
* 5. Handles two specific scenarios based on the simulation result:
* - If storage is handled by an off-chain database, it processes the request accordingly.
* - If storage is handled by an L2 network, it switches to the appropriate network,
* performs the transaction, and switches back to the original network.
*
* Note: This function does not support standard L1 ENS registrations. It is specifically
* tailored for offchain storage solutions and L2 network integrations.
*/
export const createSubdomain = async ({
resolverAddress,
signerAddress,
Expand Down Expand Up @@ -142,7 +157,7 @@ export const createSubdomain = async ({
MessageData,
];

const response = await handleDBStorage({
const response = await storeDataInDb({
domain,
url,
message,
Expand Down Expand Up @@ -192,36 +207,8 @@ export const createSubdomain = async ({

return { ok: true };
} else {
toast.error("error");
toast.error("Unsupported domain type");
console.error("writing failed: ", { error });
}
}
};

export function getChain(chainId: number) {
return [
...Object.values(chains),
defineChain({
id: Number(chainId),
name: "Arbitrum Local",
nativeCurrency: {
name: "Arbitrum Sepolia Ether",
symbol: "ETH",
decimals: 18,
},
rpcUrls: {
default: {
http: [
`https://arb-sepolia.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_TESTNET_KEY}`,
],
},
},
}),
].find((chain) => chain.id === chainId);
}

// gather the first part of the domain (e.g. floripa.blockful.eth -> floripa, floripa.normal.blockful.eth -> floripa.normal)
const extractLabelFromName = (name: string): string => {
const [, label] = /^(.+?)\.\w+\.\w+$/.exec(name) || [];
return label;
};
8 changes: 8 additions & 0 deletions ens-sdk/ensOperations/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export * from "./setDomainAsPrimaryName";
export * from "./setDomainRecords";
export * from "./storeDataInDb";
export * from "./commit";
export * from "./makeCommitment";
export * from "./register";
export * from "./sendCcipRequest";
export * from "./createSubdomain";
Loading