From 51e0e4c4904de725befb1e386f38df46b85adaff Mon Sep 17 00:00:00 2001 From: Arjun Dureja Date: Thu, 14 Aug 2025 20:44:23 -0400 Subject: [PATCH 1/5] Update registration flow for SCWs for ensip 19 --- apps/web/src/abis/L2ReverseRegistrarAbi.ts | 104 ++ .../abis/UpgradeableRegistrarControllerAbi.ts | 1057 +++++++++++++++++ apps/web/src/hooks/useRegisterNameCallback.ts | 17 +- 3 files changed, 1177 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/abis/L2ReverseRegistrarAbi.ts create mode 100644 apps/web/src/abis/UpgradeableRegistrarControllerAbi.ts diff --git a/apps/web/src/abis/L2ReverseRegistrarAbi.ts b/apps/web/src/abis/L2ReverseRegistrarAbi.ts new file mode 100644 index 00000000000..3e7177900db --- /dev/null +++ b/apps/web/src/abis/L2ReverseRegistrarAbi.ts @@ -0,0 +1,104 @@ +export default [ + { + type: 'function', + name: 'setName', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setNameForAddr', + inputs: [ + { + name: 'addr', + type: 'address', + internalType: 'address', + }, + { + name: 'name', + type: 'string', + internalType: 'string', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setNameForAddrWithSignature', + inputs: [ + { + name: 'addr', + type: 'address', + internalType: 'address', + }, + { + name: 'signatureExpiry', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'coinTypes', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setNameForOwnableWithSignature', + inputs: [ + { + name: 'contractAddr', + type: 'address', + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'signatureExpiry', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'coinTypes', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, +] as const; diff --git a/apps/web/src/abis/UpgradeableRegistrarControllerAbi.ts b/apps/web/src/abis/UpgradeableRegistrarControllerAbi.ts new file mode 100644 index 00000000000..f871d1fc576 --- /dev/null +++ b/apps/web/src/abis/UpgradeableRegistrarControllerAbi.ts @@ -0,0 +1,1057 @@ +export default [ + { + type: 'constructor', + inputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'MIN_NAME_LENGTH', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'MIN_REGISTRATION_DURATION', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'available', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'discountedRegister', + inputs: [ + { + name: 'request', + type: 'tuple', + internalType: 'struct UpgradeableRegistrarController.RegisterRequest', + components: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'duration', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'resolver', + type: 'address', + internalType: 'address', + }, + { + name: 'data', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'reverseRecord', + type: 'bool', + internalType: 'bool', + }, + { + name: 'coinTypes', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'signatureExpiry', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'discountKey', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'validationData', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'discountedRegisterPrice', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'duration', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'discountKey', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: 'price', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'discounts', + inputs: [ + { + name: 'discountKey', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct UpgradeableRegistrarController.DiscountDetails', + components: [ + { + name: 'active', + type: 'bool', + internalType: 'bool', + }, + { + name: 'discountValidator', + type: 'address', + internalType: 'address', + }, + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'discount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getActiveDiscounts', + inputs: [], + outputs: [ + { + name: '', + type: 'tuple[]', + internalType: 'struct UpgradeableRegistrarController.DiscountDetails[]', + components: [ + { + name: 'active', + type: 'bool', + internalType: 'bool', + }, + { + name: 'discountValidator', + type: 'address', + internalType: 'address', + }, + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'discount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'hasRegisteredWithDiscount', + inputs: [ + { + name: 'addresses', + type: 'address[]', + internalType: 'address[]', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'initialize', + inputs: [ + { + name: 'base_', + type: 'address', + internalType: 'contract IBaseRegistrar', + }, + { + name: 'prices_', + type: 'address', + internalType: 'contract IPriceOracle', + }, + { + name: 'reverseRegistrar_', + type: 'address', + internalType: 'contract IReverseRegistrar', + }, + { + name: 'owner_', + type: 'address', + internalType: 'address', + }, + { + name: 'rootNode_', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'rootName_', + type: 'string', + internalType: 'string', + }, + { + name: 'paymentReceiver_', + type: 'address', + internalType: 'address', + }, + { + name: 'legacyRegistrarController_', + type: 'address', + internalType: 'address', + }, + { + name: 'legacyL2Resolver_', + type: 'address', + internalType: 'address', + }, + { + name: 'l2ReverseRegistrar_', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'paymentReceiver', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'pendingOwner', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'prices', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract IPriceOracle', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'register', + inputs: [ + { + name: 'request', + type: 'tuple', + internalType: 'struct UpgradeableRegistrarController.RegisterRequest', + components: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'duration', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'resolver', + type: 'address', + internalType: 'address', + }, + { + name: 'data', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'reverseRecord', + type: 'bool', + internalType: 'bool', + }, + { + name: 'coinTypes', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'signatureExpiry', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'registerPrice', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'duration', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'renew', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'duration', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'renounceOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'rentPrice', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'duration', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'price', + type: 'tuple', + internalType: 'struct IPriceOracle.Price', + components: [ + { + name: 'base', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'premium', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'reverseRegistrar', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract IReverseRegistrar', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'setDiscountDetails', + inputs: [ + { + name: 'details', + type: 'tuple', + internalType: 'struct UpgradeableRegistrarController.DiscountDetails', + components: [ + { + name: 'active', + type: 'bool', + internalType: 'bool', + }, + { + name: 'discountValidator', + type: 'address', + internalType: 'address', + }, + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'discount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setL2ReverseRegistrar', + inputs: [ + { + name: 'l2ReverseRegistrar_', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setPaymentReceiver', + inputs: [ + { + name: 'paymentReceiver_', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setPriceOracle', + inputs: [ + { + name: 'prices_', + type: 'address', + internalType: 'contract IPriceOracle', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setReverseRecord', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + { + name: 'signatureExpiry', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'coinTypes', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setReverseRegistrar', + inputs: [ + { + name: 'reverse_', + type: 'address', + internalType: 'contract IReverseRegistrar', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [ + { + name: 'newOwner', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'valid', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'withdrawETH', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'DiscountApplied', + inputs: [ + { + name: 'registrant', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'discountKey', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DiscountUpdated', + inputs: [ + { + name: 'discountKey', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + { + name: 'details', + type: 'tuple', + indexed: false, + internalType: 'struct UpgradeableRegistrarController.DiscountDetails', + components: [ + { + name: 'active', + type: 'bool', + internalType: 'bool', + }, + { + name: 'discountValidator', + type: 'address', + internalType: 'address', + }, + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'discount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ETHPaymentProcessed', + inputs: [ + { + name: 'payee', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'price', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Initialized', + inputs: [ + { + name: 'version', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'L2ReverseRegistrarUpdated', + inputs: [ + { + name: 'newL2ReverseRegistrar', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'NameRegistered', + inputs: [ + { + name: 'name', + type: 'string', + indexed: false, + internalType: 'string', + }, + { + name: 'label', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'expires', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'NameRenewed', + inputs: [ + { + name: 'name', + type: 'string', + indexed: false, + internalType: 'string', + }, + { + name: 'label', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + { + name: 'expires', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferStarted', + inputs: [ + { + name: 'previousOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'previousOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'PaymentReceiverUpdated', + inputs: [ + { + name: 'newPaymentReceiver', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'PriceOracleUpdated', + inputs: [ + { + name: 'newPrices', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ReverseRegistrarUpdated', + inputs: [ + { + name: 'newReverseRegistrar', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'AlreadyRegisteredWithDiscount', + inputs: [ + { + name: 'sender', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'DurationTooShort', + inputs: [ + { + name: 'duration', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { + type: 'error', + name: 'InactiveDiscount', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'error', + name: 'InsufficientValue', + inputs: [], + }, + { + type: 'error', + name: 'InvalidDiscount', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidDiscountAmount', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'error', + name: 'InvalidInitialization', + inputs: [], + }, + { + type: 'error', + name: 'InvalidPaymentReceiver', + inputs: [], + }, + { + type: 'error', + name: 'InvalidValidator', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'validator', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'NameNotValid', + inputs: [ + { + name: 'name', + type: 'string', + internalType: 'string', + }, + ], + }, + { + type: 'error', + name: 'NotInitializing', + inputs: [], + }, + { + type: 'error', + name: 'OwnableInvalidOwner', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'OwnableUnauthorizedAccount', + inputs: [ + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'ResolverRequiredWhenDataSupplied', + inputs: [], + }, + { + type: 'error', + name: 'TransferFailed', + inputs: [], + }, + { + type: 'error', + name: 'ZeroAddress', + inputs: [], + }, +] as const; diff --git a/apps/web/src/hooks/useRegisterNameCallback.ts b/apps/web/src/hooks/useRegisterNameCallback.ts index 3fd2140cfbe..813e39688a7 100644 --- a/apps/web/src/hooks/useRegisterNameCallback.ts +++ b/apps/web/src/hooks/useRegisterNameCallback.ts @@ -21,6 +21,8 @@ import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react' import { encodeFunctionData, namehash } from 'viem'; import { useAccount } from 'wagmi'; import { secondsInYears } from 'apps/web/src/utils/secondsInYears'; +import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; +import L2ReverseRegistrarAbi from 'apps/web/src/abis/L2ReverseRegistrarAbi'; type UseRegisterNameCallbackReturnType = { callback: () => Promise; @@ -117,6 +119,9 @@ export function useRegisterNameCallback( resolver: USERNAME_L2_RESOLVER_ADDRESSES[basenameChain.id], // The address of the resolver to set for this name. data: [addressData, baseCointypeData, nameData], // Multicallable data bytes for setting records in the associated resolver upon registration. reverseRecord, // Bool to decide whether to set this name as the "primary" name for the `owner`. + coinTypes: [], + signatureExpiry: 0, + signature: '0x', }; try { @@ -132,7 +137,7 @@ export function useRegisterNameCallback( await initiateBatchCalls({ contracts: [ { - abi: REGISTER_CONTRACT_ABI, + abi: UpgradeableRegistrarControllerAbi, address: REGISTER_CONTRACT_ADDRESSES[basenameChain.id], functionName: isDiscounted ? 'discountedRegister' : 'register', args: isDiscounted @@ -140,6 +145,16 @@ export function useRegisterNameCallback( : [registerRequest], value, }, + ...(reverseRecord + ? [ + { + abi: L2ReverseRegistrarAbi, + address: USERNAME_L2_RESOLVER_ADDRESSES[basenameChain.id], + functionName: 'setName', + args: [normalizedName], + }, + ] + : []), ], account: address, chain: basenameChain, From 46525c316a20fc336bb77a92d67ae748a127466e Mon Sep 17 00:00:00 2001 From: Arjun Dureja Date: Tue, 9 Sep 2025 15:59:46 -0400 Subject: [PATCH 2/5] Add contract addresses --- apps/web/src/addresses/usernames.ts | 15 +++++++++++++++ apps/web/src/hooks/useRegisterNameCallback.ts | 12 +++++++----- apps/web/src/utils/proofs/sybil_resistance.ts | 3 ++- apps/web/src/utils/usernames.ts | 8 ++++---- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/apps/web/src/addresses/usernames.ts b/apps/web/src/addresses/usernames.ts index 9aeb0da6efd..1261ab1fafe 100644 --- a/apps/web/src/addresses/usernames.ts +++ b/apps/web/src/addresses/usernames.ts @@ -13,6 +13,21 @@ export const USERNAME_REGISTRAR_CONTROLLER_ADDRESSES: AddressMap = { [base.id]: '0x4cCb0BB02FCABA27e82a56646E81d8c5bC4119a5', }; +export const USERNAME_L2_REVERSE_REGISTRAR_ADDRESSES: AddressMap = { + [baseSepolia.id]: '0x00000BeEF055f7934784D6d81b6BC86665630dbA', + [base.id]: '0x0000000000D8e504002cC26E3Ec46D81971C1664', +}; + +export const UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES: AddressMap = { + [baseSepolia.id]: '0x82c858CDF64b3D893Fe54962680edFDDC37e94C8', + [base.id]: '0xa7d2607c6BD39Ae9521e514026CBB078405Ab322', +}; + +export const UPGRADEABLE_L2_RESOLVER_ADDRESSES: AddressMap = { + [baseSepolia.id]: '0x85C87e548091f204C2d0350b39ce1874f02197c6', + [base.id]: '0x426fA03fB86E510d0Dd9F70335Cf102a98b10875', +}; + export const USERNAME_EA_REGISTRAR_CONTROLLER_ADDRESSES: AddressMap = { [baseSepolia.id]: '0x3a0e8c2a0a28f396a5e5b69edb2e630311f1517a', [base.id]: '0xd3e6775Ed9B7dC12B205C8E608Dc3767B9e5eFdA', diff --git a/apps/web/src/hooks/useRegisterNameCallback.ts b/apps/web/src/hooks/useRegisterNameCallback.ts index 813e39688a7..f1f54df0b42 100644 --- a/apps/web/src/hooks/useRegisterNameCallback.ts +++ b/apps/web/src/hooks/useRegisterNameCallback.ts @@ -1,6 +1,9 @@ import { useErrors } from 'apps/web/contexts/Errors'; import L2ResolverAbi from 'apps/web/src/abis/L2Resolver'; -import { USERNAME_L2_RESOLVER_ADDRESSES } from 'apps/web/src/addresses/usernames'; +import { + UPGRADEABLE_L2_RESOLVER_ADDRESSES, + USERNAME_L2_REVERSE_REGISTRAR_ADDRESSES, +} from 'apps/web/src/addresses/usernames'; import useBaseEnsName from 'apps/web/src/hooks/useBaseEnsName'; import useBasenameChain from 'apps/web/src/hooks/useBasenameChain'; import useCapabilitiesSafe from 'apps/web/src/hooks/useCapabilitiesSafe'; @@ -21,7 +24,6 @@ import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react' import { encodeFunctionData, namehash } from 'viem'; import { useAccount } from 'wagmi'; import { secondsInYears } from 'apps/web/src/utils/secondsInYears'; -import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; import L2ReverseRegistrarAbi from 'apps/web/src/abis/L2ReverseRegistrarAbi'; type UseRegisterNameCallbackReturnType = { @@ -116,7 +118,7 @@ export function useRegisterNameCallback( name: normalizedName, // The name being registered. owner: address, // The address of the owner for the name. duration: secondsInYears(years), // The duration of the registration in seconds. - resolver: USERNAME_L2_RESOLVER_ADDRESSES[basenameChain.id], // The address of the resolver to set for this name. + resolver: UPGRADEABLE_L2_RESOLVER_ADDRESSES[basenameChain.id], // The address of the resolver to set for this name. data: [addressData, baseCointypeData, nameData], // Multicallable data bytes for setting records in the associated resolver upon registration. reverseRecord, // Bool to decide whether to set this name as the "primary" name for the `owner`. coinTypes: [], @@ -137,7 +139,7 @@ export function useRegisterNameCallback( await initiateBatchCalls({ contracts: [ { - abi: UpgradeableRegistrarControllerAbi, + abi: REGISTER_CONTRACT_ABI, address: REGISTER_CONTRACT_ADDRESSES[basenameChain.id], functionName: isDiscounted ? 'discountedRegister' : 'register', args: isDiscounted @@ -149,7 +151,7 @@ export function useRegisterNameCallback( ? [ { abi: L2ReverseRegistrarAbi, - address: USERNAME_L2_RESOLVER_ADDRESSES[basenameChain.id], + address: USERNAME_L2_REVERSE_REGISTRAR_ADDRESSES[basenameChain.id], functionName: 'setName', args: [normalizedName], }, diff --git a/apps/web/src/utils/proofs/sybil_resistance.ts b/apps/web/src/utils/proofs/sybil_resistance.ts index 07c2de8f38f..e1bc9f6c219 100644 --- a/apps/web/src/utils/proofs/sybil_resistance.ts +++ b/apps/web/src/utils/proofs/sybil_resistance.ts @@ -35,6 +35,7 @@ import { } from 'viem'; import { sign } from 'viem/accounts'; import { base, baseSepolia } from 'viem/chains'; +import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; const EXPIRY = process.env.USERNAMES_SIGNATURE_EXPIRATION_SECONDS ?? '30'; const previousClaimsKVPrefix = 'username:claims:'; @@ -77,7 +78,7 @@ export async function hasRegisteredWithDiscount( return publicClient.readContract({ address: REGISTER_CONTRACT_ADDRESSES[chainId], - abi: RegistrarControllerABI, + abi: UpgradeableRegistrarControllerAbi, functionName: 'hasRegisteredWithDiscount', args: [addresses], }); diff --git a/apps/web/src/utils/usernames.ts b/apps/web/src/utils/usernames.ts index cdd3b989055..f31b2700859 100644 --- a/apps/web/src/utils/usernames.ts +++ b/apps/web/src/utils/usernames.ts @@ -11,16 +11,15 @@ import { sha256, } from 'viem'; import { normalize } from 'viem/ens'; -import RegistrarControllerABI from 'apps/web/src/abis/RegistrarControllerABI'; import L2ResolverAbi from 'apps/web/src/abis/L2Resolver'; import RegistryAbi from 'apps/web/src/abis/RegistryAbi'; import BaseRegistrarAbi from 'apps/web/src/abis/BaseRegistrarAbi'; import { base, baseSepolia, mainnet } from 'viem/chains'; import { Basename } from '@coinbase/onchainkit/identity'; import { + UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES, USERNAME_BASE_REGISTRAR_ADDRESSES, USERNAME_BASE_REGISTRY_ADDRESSES, - USERNAME_REGISTRAR_CONTROLLER_ADDRESSES, } from 'apps/web/src/addresses/usernames'; import { @@ -56,6 +55,7 @@ import { ALLOWED_IMAGE_TYPE, MAX_IMAGE_SIZE_IN_MB, } from 'apps/web/app/(basenames)/api/basenames/avatar/ipfsUpload/route'; +import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; export const USERNAME_MIN_CHARACTER_LENGTH = 3; export const USERNAME_MAX_CHARACTER_LENGTH = 20; @@ -762,9 +762,9 @@ export const getBasenameImage = (username: string) => { export const USERNAMES_PINNED_CASTS_ENABLED = process.env.NEXT_PUBLIC_USERNAMES_PINNED_CASTS_ENABLED === 'true'; -export const REGISTER_CONTRACT_ABI = RegistrarControllerABI; +export const REGISTER_CONTRACT_ABI = UpgradeableRegistrarControllerAbi; -export const REGISTER_CONTRACT_ADDRESSES = USERNAME_REGISTRAR_CONTROLLER_ADDRESSES; +export const REGISTER_CONTRACT_ADDRESSES = UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES; export const isBasenameRenewalsKilled = process.env.NEXT_PUBLIC_KILL_BASENAMES_RENEWALS === 'true'; From 75e0ee3aed6f80c20a2ddc9dc381c6677f500fdc Mon Sep 17 00:00:00 2001 From: Arjun Dureja Date: Tue, 9 Sep 2025 18:28:43 -0400 Subject: [PATCH 3/5] Remove RegistrarController --- apps/web/src/abis/RegistrarControllerABI.ts | 500 ------------------ apps/web/src/addresses/usernames.ts | 5 - .../Basenames/RegistrationContext.tsx | 12 +- .../Basenames/RegistrationForm/index.tsx | 12 +- apps/web/src/hooks/useRentPrice.ts | 8 +- apps/web/src/utils/paymasterSponsor.ts | 4 +- apps/web/src/utils/proofs/sybil_resistance.ts | 1 - 7 files changed, 18 insertions(+), 524 deletions(-) delete mode 100644 apps/web/src/abis/RegistrarControllerABI.ts diff --git a/apps/web/src/abis/RegistrarControllerABI.ts b/apps/web/src/abis/RegistrarControllerABI.ts deleted file mode 100644 index d65b411015d..00000000000 --- a/apps/web/src/abis/RegistrarControllerABI.ts +++ /dev/null @@ -1,500 +0,0 @@ -export default [ - { - inputs: [ - { internalType: 'contract BaseRegistrar', name: 'base_', type: 'address' }, - { internalType: 'contract IPriceOracle', name: 'prices_', type: 'address' }, - { internalType: 'contract IReverseRegistrar', name: 'reverseRegistrar_', type: 'address' }, - { internalType: 'address', name: 'owner_', type: 'address' }, - { internalType: 'bytes32', name: 'rootNode_', type: 'bytes32' }, - { internalType: 'string', name: 'rootName_', type: 'string' }, - { internalType: 'address', name: 'paymentReceiver_', type: 'address' }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [{ internalType: 'address', name: 'target', type: 'address' }], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [{ internalType: 'address', name: 'account', type: 'address' }], - name: 'AddressInsufficientBalance', - type: 'error', - }, - { inputs: [], name: 'AlreadyInitialized', type: 'error' }, - { - inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], - name: 'AlreadyRegisteredWithDiscount', - type: 'error', - }, - { - inputs: [{ internalType: 'uint256', name: 'duration', type: 'uint256' }], - name: 'DurationTooShort', - type: 'error', - }, - { inputs: [], name: 'FailedInnerCall', type: 'error' }, - { - inputs: [{ internalType: 'bytes32', name: 'key', type: 'bytes32' }], - name: 'InactiveDiscount', - type: 'error', - }, - { inputs: [], name: 'InsufficientValue', type: 'error' }, - { - inputs: [ - { internalType: 'bytes32', name: 'key', type: 'bytes32' }, - { internalType: 'bytes', name: 'data', type: 'bytes' }, - ], - name: 'InvalidDiscount', - type: 'error', - }, - { - inputs: [{ internalType: 'bytes32', name: 'key', type: 'bytes32' }], - name: 'InvalidDiscountAmount', - type: 'error', - }, - { inputs: [], name: 'InvalidPaymentReceiver', type: 'error' }, - { - inputs: [ - { internalType: 'bytes32', name: 'key', type: 'bytes32' }, - { internalType: 'address', name: 'validator', type: 'address' }, - ], - name: 'InvalidValidator', - type: 'error', - }, - { - inputs: [{ internalType: 'string', name: 'name', type: 'string' }], - name: 'NameNotAvailable', - type: 'error', - }, - { inputs: [], name: 'NewOwnerIsZeroAddress', type: 'error' }, - { inputs: [], name: 'NoHandoverRequest', type: 'error' }, - { inputs: [], name: 'ResolverRequiredWhenDataSupplied', type: 'error' }, - { - inputs: [{ internalType: 'address', name: 'token', type: 'address' }], - name: 'SafeERC20FailedOperation', - type: 'error', - }, - { inputs: [], name: 'TransferFailed', type: 'error' }, - { inputs: [], name: 'Unauthorized', type: 'error' }, - { - anonymous: false, - inputs: [ - { indexed: true, internalType: 'address', name: 'registrant', type: 'address' }, - { indexed: true, internalType: 'bytes32', name: 'discountKey', type: 'bytes32' }, - ], - name: 'DiscountApplied', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { indexed: true, internalType: 'bytes32', name: 'discountKey', type: 'bytes32' }, - { - components: [ - { internalType: 'bool', name: 'active', type: 'bool' }, - { internalType: 'address', name: 'discountValidator', type: 'address' }, - { internalType: 'bytes32', name: 'key', type: 'bytes32' }, - { internalType: 'uint256', name: 'discount', type: 'uint256' }, - ], - indexed: false, - internalType: 'struct RegistrarController.DiscountDetails', - name: 'details', - type: 'tuple', - }, - ], - name: 'DiscountUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { indexed: true, internalType: 'address', name: 'payee', type: 'address' }, - { indexed: false, internalType: 'uint256', name: 'price', type: 'uint256' }, - ], - name: 'ETHPaymentProcessed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { indexed: false, internalType: 'string', name: 'name', type: 'string' }, - { indexed: true, internalType: 'bytes32', name: 'label', type: 'bytes32' }, - { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, - { indexed: false, internalType: 'uint256', name: 'expires', type: 'uint256' }, - ], - name: 'NameRegistered', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { indexed: false, internalType: 'string', name: 'name', type: 'string' }, - { indexed: true, internalType: 'bytes32', name: 'label', type: 'bytes32' }, - { indexed: false, internalType: 'uint256', name: 'expires', type: 'uint256' }, - ], - name: 'NameRenewed', - type: 'event', - }, - { - anonymous: false, - inputs: [{ indexed: true, internalType: 'address', name: 'pendingOwner', type: 'address' }], - name: 'OwnershipHandoverCanceled', - type: 'event', - }, - { - anonymous: false, - inputs: [{ indexed: true, internalType: 'address', name: 'pendingOwner', type: 'address' }], - name: 'OwnershipHandoverRequested', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { indexed: true, internalType: 'address', name: 'oldOwner', type: 'address' }, - { indexed: true, internalType: 'address', name: 'newOwner', type: 'address' }, - ], - name: 'OwnershipTransferred', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { indexed: false, internalType: 'address', name: 'newPaymentReceiver', type: 'address' }, - ], - name: 'PaymentReceiverUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [{ indexed: false, internalType: 'address', name: 'newPrices', type: 'address' }], - name: 'PriceOracleUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { indexed: false, internalType: 'address', name: 'newReverseRegistrar', type: 'address' }, - ], - name: 'ReverseRegistrarUpdated', - type: 'event', - }, - { - inputs: [], - name: 'MIN_NAME_LENGTH', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'MIN_REGISTRATION_DURATION', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [{ internalType: 'string', name: 'name', type: 'string' }], - name: 'available', - outputs: [{ internalType: 'bool', name: '', type: 'bool' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'cancelOwnershipHandover', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [{ internalType: 'address', name: 'pendingOwner', type: 'address' }], - name: 'completeOwnershipHandover', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { internalType: 'string', name: 'name', type: 'string' }, - { internalType: 'address', name: 'owner', type: 'address' }, - { internalType: 'uint256', name: 'duration', type: 'uint256' }, - { internalType: 'address', name: 'resolver', type: 'address' }, - { internalType: 'bytes[]', name: 'data', type: 'bytes[]' }, - { internalType: 'bool', name: 'reverseRecord', type: 'bool' }, - ], - internalType: 'struct RegistrarController.RegisterRequest', - name: 'request', - type: 'tuple', - }, - { internalType: 'bytes32', name: 'discountKey', type: 'bytes32' }, - { internalType: 'bytes', name: 'validationData', type: 'bytes' }, - ], - name: 'discountedRegister', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { internalType: 'string', name: 'name', type: 'string' }, - { internalType: 'uint256', name: 'duration', type: 'uint256' }, - { internalType: 'bytes32', name: 'discountKey', type: 'bytes32' }, - ], - name: 'discountedRegisterPrice', - outputs: [{ internalType: 'uint256', name: 'price', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [{ internalType: 'address', name: 'registrant', type: 'address' }], - name: 'discountedRegistrants', - outputs: [{ internalType: 'bool', name: 'hasRegisteredWithDiscount', type: 'bool' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [{ internalType: 'bytes32', name: 'key', type: 'bytes32' }], - name: 'discounts', - outputs: [ - { internalType: 'bool', name: 'active', type: 'bool' }, - { internalType: 'address', name: 'discountValidator', type: 'address' }, - { internalType: 'bytes32', name: 'key', type: 'bytes32' }, - { internalType: 'uint256', name: 'discount', type: 'uint256' }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'getActiveDiscounts', - outputs: [ - { - components: [ - { internalType: 'bool', name: 'active', type: 'bool' }, - { internalType: 'address', name: 'discountValidator', type: 'address' }, - { internalType: 'bytes32', name: 'key', type: 'bytes32' }, - { internalType: 'uint256', name: 'discount', type: 'uint256' }, - ], - internalType: 'struct RegistrarController.DiscountDetails[]', - name: '', - type: 'tuple[]', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [{ internalType: 'address[]', name: 'addresses', type: 'address[]' }], - name: 'hasRegisteredWithDiscount', - outputs: [{ internalType: 'bool', name: '', type: 'bool' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'launchTime', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'owner', - outputs: [{ internalType: 'address', name: 'result', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [{ internalType: 'address', name: 'pendingOwner', type: 'address' }], - name: 'ownershipHandoverExpiresAt', - outputs: [{ internalType: 'uint256', name: 'result', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'paymentReceiver', - outputs: [{ internalType: 'address', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'prices', - outputs: [{ internalType: 'contract IPriceOracle', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { internalType: 'address', name: '_token', type: 'address' }, - { internalType: 'address', name: '_to', type: 'address' }, - { internalType: 'uint256', name: '_amount', type: 'uint256' }, - ], - name: 'recoverFunds', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { internalType: 'string', name: 'name', type: 'string' }, - { internalType: 'address', name: 'owner', type: 'address' }, - { internalType: 'uint256', name: 'duration', type: 'uint256' }, - { internalType: 'address', name: 'resolver', type: 'address' }, - { internalType: 'bytes[]', name: 'data', type: 'bytes[]' }, - { internalType: 'bool', name: 'reverseRecord', type: 'bool' }, - ], - internalType: 'struct RegistrarController.RegisterRequest', - name: 'request', - type: 'tuple', - }, - ], - name: 'register', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { internalType: 'string', name: 'name', type: 'string' }, - { internalType: 'uint256', name: 'duration', type: 'uint256' }, - ], - name: 'registerPrice', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { internalType: 'string', name: 'name', type: 'string' }, - { internalType: 'uint256', name: 'duration', type: 'uint256' }, - ], - name: 'renew', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'renounceOwnership', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { internalType: 'string', name: 'name', type: 'string' }, - { internalType: 'uint256', name: 'duration', type: 'uint256' }, - ], - name: 'rentPrice', - outputs: [ - { - components: [ - { internalType: 'uint256', name: 'base', type: 'uint256' }, - { internalType: 'uint256', name: 'premium', type: 'uint256' }, - ], - internalType: 'struct IPriceOracle.Price', - name: 'price', - type: 'tuple', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'requestOwnershipHandover', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'reverseRegistrar', - outputs: [{ internalType: 'contract IReverseRegistrar', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'rootName', - outputs: [{ internalType: 'string', name: '', type: 'string' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'rootNode', - outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - components: [ - { internalType: 'bool', name: 'active', type: 'bool' }, - { internalType: 'address', name: 'discountValidator', type: 'address' }, - { internalType: 'bytes32', name: 'key', type: 'bytes32' }, - { internalType: 'uint256', name: 'discount', type: 'uint256' }, - ], - internalType: 'struct RegistrarController.DiscountDetails', - name: 'details', - type: 'tuple', - }, - ], - name: 'setDiscountDetails', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [{ internalType: 'uint256', name: 'launchTime_', type: 'uint256' }], - name: 'setLaunchTime', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [{ internalType: 'address', name: 'paymentReceiver_', type: 'address' }], - name: 'setPaymentReceiver', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [{ internalType: 'contract IPriceOracle', name: 'prices_', type: 'address' }], - name: 'setPriceOracle', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [{ internalType: 'contract IReverseRegistrar', name: 'reverse_', type: 'address' }], - name: 'setReverseRegistrar', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], - name: 'transferOwnership', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [{ internalType: 'string', name: 'name', type: 'string' }], - name: 'valid', - outputs: [{ internalType: 'bool', name: '', type: 'bool' }], - stateMutability: 'pure', - type: 'function', - }, - { inputs: [], name: 'withdrawETH', outputs: [], stateMutability: 'nonpayable', type: 'function' }, -] as const; diff --git a/apps/web/src/addresses/usernames.ts b/apps/web/src/addresses/usernames.ts index 1261ab1fafe..a025b33c2c6 100644 --- a/apps/web/src/addresses/usernames.ts +++ b/apps/web/src/addresses/usernames.ts @@ -8,11 +8,6 @@ export const USERNAME_L2_RESOLVER_ADDRESSES: AddressMap = { [base.id]: '0xC6d566A56A1aFf6508b41f6c90ff131615583BCD', }; -export const USERNAME_REGISTRAR_CONTROLLER_ADDRESSES: AddressMap = { - [baseSepolia.id]: '0x49aE3cC2e3AA768B1e5654f5D3C6002144A59581', - [base.id]: '0x4cCb0BB02FCABA27e82a56646E81d8c5bC4119a5', -}; - export const USERNAME_L2_REVERSE_REGISTRAR_ADDRESSES: AddressMap = { [baseSepolia.id]: '0x00000BeEF055f7934784D6d81b6BC86665630dbA', [base.id]: '0x0000000000D8e504002cC26E3Ec46D81971C1664', diff --git a/apps/web/src/components/Basenames/RegistrationContext.tsx b/apps/web/src/components/Basenames/RegistrationContext.tsx index 7b00fe7e2a7..0e18c31f86f 100644 --- a/apps/web/src/components/Basenames/RegistrationContext.tsx +++ b/apps/web/src/components/Basenames/RegistrationContext.tsx @@ -1,6 +1,5 @@ 'use client'; -import RegistrarControllerABI from 'apps/web/src/abis/RegistrarControllerABI'; -import { USERNAME_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; +import { UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; import { useAnalytics } from 'apps/web/contexts/Analytics'; import { useErrors } from 'apps/web/contexts/Errors'; import { @@ -36,6 +35,7 @@ import { BatchCallsStatus } from 'apps/web/src/hooks/useWriteContractsWithLogs'; import { WriteTransactionWithReceiptStatus } from 'apps/web/src/hooks/useWriteContractWithReceipt'; import useBaseEnsName from 'apps/web/src/hooks/useBaseEnsName'; import { Basename } from '@coinbase/onchainkit/identity'; +import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; export enum RegistrationSteps { Search = 'search', @@ -174,10 +174,10 @@ export default function RegistrationProvider({ children, code }: RegistrationPro // Has already registered with discount const { data: hasRegisteredWithDiscount } = useReadContract({ - abi: RegistrarControllerABI, - address: USERNAME_REGISTRAR_CONTROLLER_ADDRESSES[basenameChain.id], - functionName: 'discountedRegistrants', - args: [address ?? zeroAddress], + abi: UpgradeableRegistrarControllerAbi, + address: UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES[basenameChain.id], + functionName: 'hasRegisteredWithDiscount', + args: [[address ?? zeroAddress]], }); const { data: discountedPrice } = useDiscountedNameRegistrationPrice( diff --git a/apps/web/src/components/Basenames/RegistrationForm/index.tsx b/apps/web/src/components/Basenames/RegistrationForm/index.tsx index 7fd53187b29..f65143456d9 100644 --- a/apps/web/src/components/Basenames/RegistrationForm/index.tsx +++ b/apps/web/src/components/Basenames/RegistrationForm/index.tsx @@ -1,7 +1,6 @@ import { useAnalytics } from 'apps/web/contexts/Analytics'; import { useErrors } from 'apps/web/contexts/Errors'; -import RegistrarControllerABI from 'apps/web/src/abis/RegistrarControllerABI'; -import { USERNAME_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; +import { UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; import { PremiumExplainerModal } from 'apps/web/src/components/Basenames/PremiumExplainerModal'; import { useRegistration } from 'apps/web/src/components/Basenames/RegistrationContext'; import RegistrationLearnMoreModal from 'apps/web/src/components/Basenames/RegistrationLearnMoreModal'; @@ -29,6 +28,7 @@ import { formatEtherPrice } from 'apps/web/src/utils/formatEtherPrice'; import { formatUsdPrice } from 'apps/web/src/utils/formatUsdPrice'; import { ConnectButton, useConnectModal } from '@rainbow-me/rainbowkit'; import { Button, ButtonSizes, ButtonVariants } from 'apps/web/src/components/Button/Button'; +import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; export default function RegistrationForm() { const { chain: connectedChain, address } = useAccount(); @@ -100,10 +100,10 @@ export default function RegistrationForm() { ); const { data: hasRegisteredWithDiscount } = useReadContract({ - abi: RegistrarControllerABI, - address: USERNAME_REGISTRAR_CONTROLLER_ADDRESSES[basenameChain.id], - functionName: 'discountedRegistrants', - args: [address ?? zeroAddress], + abi: UpgradeableRegistrarControllerAbi, + address: UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES[basenameChain.id], + functionName: 'hasRegisteredWithDiscount', + args: [[address ?? zeroAddress]], }); const price = hasRegisteredWithDiscount ? initialPrice : discountedPrice ?? initialPrice; diff --git a/apps/web/src/hooks/useRentPrice.ts b/apps/web/src/hooks/useRentPrice.ts index 41532175503..a3a8041434a 100644 --- a/apps/web/src/hooks/useRentPrice.ts +++ b/apps/web/src/hooks/useRentPrice.ts @@ -1,8 +1,8 @@ -import { USERNAME_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; -import RegistrarControllerABI from 'apps/web/src/abis/RegistrarControllerABI'; +import { UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; import { useReadContract } from 'wagmi'; import { base } from 'viem/chains'; import { normalizeEnsDomainName } from 'apps/web/src/utils/usernames'; +import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; function secondsInYears(years: number) { const secondsPerYear = 365.25 * 24 * 60 * 60; // .25 accounting for leap years @@ -20,8 +20,8 @@ export function useRentPrice(name: string, years: number) { const normalizedName = normalizeEnsDomainName(name); const { data }: RentPriceResponseType = useReadContract({ - abi: RegistrarControllerABI, - address: USERNAME_REGISTRAR_CONTROLLER_ADDRESSES[base.id], + abi: UpgradeableRegistrarControllerAbi, + address: UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES[base.id], functionName: 'rentPrice', args: [normalizedName, secondsInYears(years)], chainId: base.id, diff --git a/apps/web/src/utils/paymasterSponsor.ts b/apps/web/src/utils/paymasterSponsor.ts index dd3d44a38f6..187f6fc3977 100644 --- a/apps/web/src/utils/paymasterSponsor.ts +++ b/apps/web/src/utils/paymasterSponsor.ts @@ -1,4 +1,4 @@ -import RegistrarControllerABI from 'apps/web/src/abis/RegistrarControllerABI'; +import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; import { ENTRYPOINT_ADDRESS_V06, UserOperation } from 'permissionless'; import { Address, @@ -108,7 +108,7 @@ export async function willSponsor({ } const innerCalldata = decodeFunctionData({ - abi: RegistrarControllerABI, + abi: UpgradeableRegistrarControllerAbi, data: calls[callToCheckIndex].data, }); if (!['register', 'discountedRegister'].includes(innerCalldata.functionName)) { diff --git a/apps/web/src/utils/proofs/sybil_resistance.ts b/apps/web/src/utils/proofs/sybil_resistance.ts index e1bc9f6c219..c567a2d8cb4 100644 --- a/apps/web/src/utils/proofs/sybil_resistance.ts +++ b/apps/web/src/utils/proofs/sybil_resistance.ts @@ -1,7 +1,6 @@ import { getAttestations } from '@coinbase/onchainkit/identity'; import { getKv } from 'apps/web/src/utils/datastores/kv'; import { CoinbaseProofResponse } from 'apps/web/app/(basenames)/api/proofs/coinbase/route'; -import RegistrarControllerABI from 'apps/web/src/abis/RegistrarControllerABI'; import { USERNAME_CB1_DISCOUNT_VALIDATORS, USERNAME_CB_DISCOUNT_VALIDATORS, From af9c94aee9b51b1b6c839f7c61b510b272999a0e Mon Sep 17 00:00:00 2001 From: Arjun Dureja Date: Tue, 9 Sep 2025 18:33:20 -0400 Subject: [PATCH 4/5] update --- .../components/Basenames/RegistrationContext.tsx | 14 +++++++++----- .../Basenames/RegistrationForm/index.tsx | 12 +++++++----- apps/web/src/hooks/useRentPrice.ts | 12 +++++++----- apps/web/src/utils/paymasterSponsor.ts | 5 ++--- apps/web/src/utils/proofs/sybil_resistance.ts | 5 ++--- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/apps/web/src/components/Basenames/RegistrationContext.tsx b/apps/web/src/components/Basenames/RegistrationContext.tsx index 0e18c31f86f..23d08d284a0 100644 --- a/apps/web/src/components/Basenames/RegistrationContext.tsx +++ b/apps/web/src/components/Basenames/RegistrationContext.tsx @@ -1,5 +1,4 @@ 'use client'; -import { UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; import { useAnalytics } from 'apps/web/contexts/Analytics'; import { useErrors } from 'apps/web/contexts/Errors'; import { @@ -9,7 +8,13 @@ import { } from 'apps/web/src/hooks/useAggregatedDiscountValidators'; import useBasenameChain from 'apps/web/src/hooks/useBasenameChain'; import { useRegisterNameCallback } from 'apps/web/src/hooks/useRegisterNameCallback'; -import { Discount, formatBaseEthDomain, isValidDiscount } from 'apps/web/src/utils/usernames'; +import { + Discount, + formatBaseEthDomain, + isValidDiscount, + REGISTER_CONTRACT_ABI, + REGISTER_CONTRACT_ADDRESSES, +} from 'apps/web/src/utils/usernames'; import { ActionType } from 'libs/base-ui/utils/logEvent'; import { useRouter } from 'next/navigation'; import { @@ -35,7 +40,6 @@ import { BatchCallsStatus } from 'apps/web/src/hooks/useWriteContractsWithLogs'; import { WriteTransactionWithReceiptStatus } from 'apps/web/src/hooks/useWriteContractWithReceipt'; import useBaseEnsName from 'apps/web/src/hooks/useBaseEnsName'; import { Basename } from '@coinbase/onchainkit/identity'; -import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; export enum RegistrationSteps { Search = 'search', @@ -174,8 +178,8 @@ export default function RegistrationProvider({ children, code }: RegistrationPro // Has already registered with discount const { data: hasRegisteredWithDiscount } = useReadContract({ - abi: UpgradeableRegistrarControllerAbi, - address: UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES[basenameChain.id], + abi: REGISTER_CONTRACT_ABI, + address: REGISTER_CONTRACT_ADDRESSES[basenameChain.id], functionName: 'hasRegisteredWithDiscount', args: [[address ?? zeroAddress]], }); diff --git a/apps/web/src/components/Basenames/RegistrationForm/index.tsx b/apps/web/src/components/Basenames/RegistrationForm/index.tsx index f65143456d9..cae6463d344 100644 --- a/apps/web/src/components/Basenames/RegistrationForm/index.tsx +++ b/apps/web/src/components/Basenames/RegistrationForm/index.tsx @@ -1,6 +1,5 @@ import { useAnalytics } from 'apps/web/contexts/Analytics'; import { useErrors } from 'apps/web/contexts/Errors'; -import { UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; import { PremiumExplainerModal } from 'apps/web/src/components/Basenames/PremiumExplainerModal'; import { useRegistration } from 'apps/web/src/components/Basenames/RegistrationContext'; import RegistrationLearnMoreModal from 'apps/web/src/components/Basenames/RegistrationLearnMoreModal'; @@ -18,7 +17,11 @@ import { useNameRegistrationPrice, } from 'apps/web/src/hooks/useNameRegistrationPrice'; import { useRentPrice } from 'apps/web/src/hooks/useRentPrice'; -import { formatBaseEthDomain } from 'apps/web/src/utils/usernames'; +import { + formatBaseEthDomain, + REGISTER_CONTRACT_ABI, + REGISTER_CONTRACT_ADDRESSES, +} from 'apps/web/src/utils/usernames'; import classNames from 'classnames'; import { ActionType } from 'libs/base-ui/utils/logEvent'; import { ChangeEvent, useCallback, useState } from 'react'; @@ -28,7 +31,6 @@ import { formatEtherPrice } from 'apps/web/src/utils/formatEtherPrice'; import { formatUsdPrice } from 'apps/web/src/utils/formatUsdPrice'; import { ConnectButton, useConnectModal } from '@rainbow-me/rainbowkit'; import { Button, ButtonSizes, ButtonVariants } from 'apps/web/src/components/Button/Button'; -import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; export default function RegistrationForm() { const { chain: connectedChain, address } = useAccount(); @@ -100,8 +102,8 @@ export default function RegistrationForm() { ); const { data: hasRegisteredWithDiscount } = useReadContract({ - abi: UpgradeableRegistrarControllerAbi, - address: UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES[basenameChain.id], + abi: REGISTER_CONTRACT_ABI, + address: REGISTER_CONTRACT_ADDRESSES[basenameChain.id], functionName: 'hasRegisteredWithDiscount', args: [[address ?? zeroAddress]], }); diff --git a/apps/web/src/hooks/useRentPrice.ts b/apps/web/src/hooks/useRentPrice.ts index a3a8041434a..4b5f7fc6661 100644 --- a/apps/web/src/hooks/useRentPrice.ts +++ b/apps/web/src/hooks/useRentPrice.ts @@ -1,8 +1,10 @@ -import { UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES } from 'apps/web/src/addresses/usernames'; import { useReadContract } from 'wagmi'; import { base } from 'viem/chains'; -import { normalizeEnsDomainName } from 'apps/web/src/utils/usernames'; -import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; +import { + normalizeEnsDomainName, + REGISTER_CONTRACT_ABI, + REGISTER_CONTRACT_ADDRESSES, +} from 'apps/web/src/utils/usernames'; function secondsInYears(years: number) { const secondsPerYear = 365.25 * 24 * 60 * 60; // .25 accounting for leap years @@ -20,8 +22,8 @@ export function useRentPrice(name: string, years: number) { const normalizedName = normalizeEnsDomainName(name); const { data }: RentPriceResponseType = useReadContract({ - abi: UpgradeableRegistrarControllerAbi, - address: UPGRADEABLE_REGISTRAR_CONTROLLER_ADDRESSES[base.id], + abi: REGISTER_CONTRACT_ABI, + address: REGISTER_CONTRACT_ADDRESSES[base.id], functionName: 'rentPrice', args: [normalizedName, secondsInYears(years)], chainId: base.id, diff --git a/apps/web/src/utils/paymasterSponsor.ts b/apps/web/src/utils/paymasterSponsor.ts index 187f6fc3977..8878ddcfdd0 100644 --- a/apps/web/src/utils/paymasterSponsor.ts +++ b/apps/web/src/utils/paymasterSponsor.ts @@ -1,4 +1,3 @@ -import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; import { ENTRYPOINT_ADDRESS_V06, UserOperation } from 'permissionless'; import { Address, @@ -18,7 +17,7 @@ import { coinbaseSmartWalletABI, magicSpendAddress, } from '../constants'; -import { REGISTER_CONTRACT_ADDRESSES } from 'apps/web/src/utils/usernames'; +import { REGISTER_CONTRACT_ABI, REGISTER_CONTRACT_ADDRESSES } from 'apps/web/src/utils/usernames'; import { logger } from 'apps/web/src/utils/logger'; const baseSepoliaClient = createPublicClient({ @@ -108,7 +107,7 @@ export async function willSponsor({ } const innerCalldata = decodeFunctionData({ - abi: UpgradeableRegistrarControllerAbi, + abi: REGISTER_CONTRACT_ABI, data: calls[callToCheckIndex].data, }); if (!['register', 'discountedRegister'].includes(innerCalldata.functionName)) { diff --git a/apps/web/src/utils/proofs/sybil_resistance.ts b/apps/web/src/utils/proofs/sybil_resistance.ts index c567a2d8cb4..ff7cf78519e 100644 --- a/apps/web/src/utils/proofs/sybil_resistance.ts +++ b/apps/web/src/utils/proofs/sybil_resistance.ts @@ -23,7 +23,7 @@ import { ProofsException, VerifiedAccount, } from 'apps/web/src/utils/proofs/types'; -import { REGISTER_CONTRACT_ADDRESSES } from 'apps/web/src/utils/usernames'; +import { REGISTER_CONTRACT_ABI, REGISTER_CONTRACT_ADDRESSES } from 'apps/web/src/utils/usernames'; import { Address, encodeAbiParameters, @@ -34,7 +34,6 @@ import { } from 'viem'; import { sign } from 'viem/accounts'; import { base, baseSepolia } from 'viem/chains'; -import UpgradeableRegistrarControllerAbi from 'apps/web/src/abis/UpgradeableRegistrarControllerAbi'; const EXPIRY = process.env.USERNAMES_SIGNATURE_EXPIRATION_SECONDS ?? '30'; const previousClaimsKVPrefix = 'username:claims:'; @@ -77,7 +76,7 @@ export async function hasRegisteredWithDiscount( return publicClient.readContract({ address: REGISTER_CONTRACT_ADDRESSES[chainId], - abi: UpgradeableRegistrarControllerAbi, + abi: REGISTER_CONTRACT_ABI, functionName: 'hasRegisteredWithDiscount', args: [addresses], }); From bfb47269ccc5839d72fb216954fe208b7ac3fe4c Mon Sep 17 00:00:00 2001 From: Arjun Dureja Date: Tue, 9 Sep 2025 18:58:34 -0400 Subject: [PATCH 5/5] update --- apps/web/src/hooks/useBasenamesLaunchTime.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/apps/web/src/hooks/useBasenamesLaunchTime.ts b/apps/web/src/hooks/useBasenamesLaunchTime.ts index 540f7be2053..93529a54d1a 100644 --- a/apps/web/src/hooks/useBasenamesLaunchTime.ts +++ b/apps/web/src/hooks/useBasenamesLaunchTime.ts @@ -1,13 +1,4 @@ -import useBasenameChain from 'apps/web/src/hooks/useBasenameChain'; -import { REGISTER_CONTRACT_ABI, REGISTER_CONTRACT_ADDRESSES } from 'apps/web/src/utils/usernames'; -import { useReadContract } from 'wagmi'; - export function useBasenamesLaunchTime() { - const { basenameChain } = useBasenameChain(); - return useReadContract({ - address: REGISTER_CONTRACT_ADDRESSES[basenameChain.id], - abi: REGISTER_CONTRACT_ABI, - functionName: 'launchTime' as const, - chainId: basenameChain.id, - }); + // Temporarily hardcoded from RegistrarController + return { data: 1724184000n }; }