44from ape .exceptions import ProviderError
55from ape .logging import logger
66from ape .utils .basemodel import ManagerAccessMixin
7- from web3 .exceptions import CannotHandleRequest
7+ from web3 .exceptions import BadFunctionCallOutput , CannotHandleRequest , Web3RPCError
88from web3 .main import ENS as Web3ENS
99
10+ from ape_ens .exceptions import MissingRegistryError
1011from ape_ens .utils .namehash import namehash
1112
1213if TYPE_CHECKING :
@@ -37,7 +38,7 @@ class ENS(ManagerAccessMixin):
3738 """
3839
3940 def __init__ (self , backend : Optional ["Web3ENS" ] = None ) -> None :
40- self ._ens = backend
41+ self .__initialized_ens = backend
4142 self .local_registry : dict [str , AddressType ] = {}
4243
4344 @classmethod
@@ -112,16 +113,28 @@ def _get_mainnet_provider(self) -> "Web3Provider":
112113
113114 @cached_property
114115 def _web3_ens (self ) -> "Web3ENS" :
115- if ens := self ._ens :
116+ if ens := self .__initialized_ens :
116117 # Initialized with ENS (testing?)
117118 return ens
118119
119- return self ._mainnet_provider . web3 . ens
120+ return self ._create_web3_ens ()
120121
121122 @property
122123 def config (self ) -> "ENSConfig" :
123124 return self .config_manager .ens
124125
126+ def _create_web3_ens (self , registry_address : Optional ["AddressType" ] = None ) -> "Web3ENS" :
127+ if registry_address :
128+ return Web3ENS .from_web3 (self ._mainnet_provider .web3 , registry_address )
129+
130+ else :
131+ # Check config.
132+ if address := self .config .registry_address :
133+ return Web3ENS .from_web3 (self ._mainnet_provider .web3 , address )
134+
135+ # Use default (most common).
136+ return self ._mainnet_provider .web3 .ens
137+
125138 def can_resolve (self , name : str ) -> bool :
126139 """
127140 Returns ``True`` when ENS can resolve the name.
@@ -144,17 +157,29 @@ def can_resolve(self, name: str) -> bool:
144157
145158 return address is not None
146159
147- def resolve (self , name : str , use_cache : Optional [bool ] = None ) -> Optional ["AddressType" ]:
160+ def resolve (
161+ self ,
162+ name : str ,
163+ use_cache : Optional [bool ] = None ,
164+ registry_address : Optional ["AddressType" ] = None ,
165+ ) -> Optional ["AddressType" ]:
148166 """
149167 Resolve an ENS name.
150168
151169 Args:
152170 name (str): The name to resolve.
153171 use_cache (bool): Set to ``False`` to not use the in-memory cache.
172+ registry_address (Optional[AddressType]): Optionally, change the registry
173+ address.
154174
155175 Returns:
156176 AddressType | None
157177 """
178+ ens = (
179+ self ._create_web3_ens (registry_address = registry_address )
180+ if registry_address
181+ else self ._web3_ens
182+ )
158183 if use_cache is None :
159184 # Use default from config.
160185 use_cache = self .config .use_cache
@@ -168,37 +193,55 @@ def resolve(self, name: str, use_cache: Optional[bool] = None) -> Optional["Addr
168193 self .local_registry [name ] = address
169194 return address
170195
171- if address := self ._web3_ens .address (name ):
172- if use_cache :
173- self .local_registry [name ] = address
196+ try :
197+ address = ens .address (name )
198+ except (Web3RPCError , BadFunctionCallOutput ) as err :
199+ raise MissingRegistryError (str (err ))
174200
175- return address
201+ if use_cache and address is not None :
202+ self .local_registry [name ] = address
176203
177- return None
204+ return address
178205
179- def name (self , address : "AddressType" ) -> Optional [str ]:
206+ def name (
207+ self , address : "AddressType" , registry_address : Optional ["AddressType" ] = None
208+ ) -> Optional [str ]:
180209 """
181210 Reverse look-up an address to get the ENS name.
182211
183212 Args:
184213 address (AddressType): The address to resolve.
214+ registry_address (Optional[AddressType]): Optionally, change the registry.
185215
186216 Returns:
187217 str | None: The ENS name.
188218 """
189- return self ._web3_ens .name (address )
190-
191- def owner (self , name : str ) -> Optional ["AddressType" ]:
219+ ens = (
220+ self ._create_web3_ens (registry_address = registry_address )
221+ if registry_address
222+ else self ._web3_ens
223+ )
224+ return ens .name (address )
225+
226+ def owner (
227+ self , name : str , registry_address : Optional ["AddressType" ] = None
228+ ) -> Optional ["AddressType" ]:
192229 """
193230 Get the owner of an ENS domain.
194231
195232 Args:
196233 name (str): The ENS name to check.
234+ registry_address (Optional[AddressType]): Optionally, change the registry.
197235
198236 Returns:
199237 AddressType | None
200238 """
201- return self ._web3_ens .owner (name )
239+ ens = (
240+ self ._create_web3_ens (registry_address = registry_address )
241+ if registry_address
242+ else self ._web3_ens
243+ )
244+ return ens .owner (name )
202245
203246 def namehash (self , name : str ) -> "HexBytes" :
204247 """
0 commit comments