2022-09-05 23:57:11 +03:00
"use strict" ;
2022-12-10 02:24:58 +03:00
/ * *
* About ENS Resolver
*
* @ _section : api / providers / ens - resolver : ENS Resolver [ about - ens - rsolver ]
* /
2022-09-05 23:57:11 +03:00
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
exports . EnsResolver = exports . BasicMulticoinProviderPlugin = exports . MulticoinProviderPlugin = void 0 ;
2022-09-27 10:45:27 +03:00
const index _js _1 = require ( "../address/index.js" ) ;
2022-10-20 12:03:32 +03:00
const index _js _2 = require ( "../constants/index.js" ) ;
const index _js _3 = require ( "../hash/index.js" ) ;
const index _js _4 = require ( "../utils/index.js" ) ;
2022-09-05 23:57:11 +03:00
const BN _1 = BigInt ( 1 ) ;
const Empty = new Uint8Array ( [ ] ) ;
function parseBytes ( result , start ) {
if ( result === "0x" ) {
return null ;
}
2022-10-20 12:03:32 +03:00
const offset = ( 0 , index _js _4 . toNumber ) ( ( 0 , index _js _4 . dataSlice ) ( result , start , start + 32 ) ) ;
const length = ( 0 , index _js _4 . toNumber ) ( ( 0 , index _js _4 . dataSlice ) ( result , offset , offset + 32 ) ) ;
return ( 0 , index _js _4 . dataSlice ) ( result , offset + 32 , offset + 32 + length ) ;
2022-09-05 23:57:11 +03:00
}
function parseString ( result , start ) {
try {
const bytes = parseBytes ( result , start ) ;
if ( bytes != null ) {
2022-10-20 12:03:32 +03:00
return ( 0 , index _js _4 . toUtf8String ) ( bytes ) ;
2022-09-05 23:57:11 +03:00
}
}
catch ( error ) { }
return null ;
}
function numPad ( value ) {
2022-12-10 02:24:58 +03:00
const result = ( 0 , index _js _4 . toBeArray ) ( value ) ;
2022-09-05 23:57:11 +03:00
if ( result . length > 32 ) {
throw new Error ( "internal; should not happen" ) ;
}
const padded = new Uint8Array ( 32 ) ;
padded . set ( result , 32 - result . length ) ;
return padded ;
}
function bytesPad ( value ) {
if ( ( value . length % 32 ) === 0 ) {
return value ;
}
const result = new Uint8Array ( Math . ceil ( value . length / 32 ) * 32 ) ;
result . set ( value ) ;
return result ;
}
// ABI Encodes a series of (bytes, bytes, ...)
function encodeBytes ( datas ) {
const result = [ ] ;
let byteCount = 0 ;
// Add place-holders for pointers as we add items
for ( let i = 0 ; i < datas . length ; i ++ ) {
result . push ( Empty ) ;
byteCount += 32 ;
}
for ( let i = 0 ; i < datas . length ; i ++ ) {
2022-10-20 12:03:32 +03:00
const data = ( 0 , index _js _4 . getBytes ) ( datas [ i ] ) ;
2022-09-05 23:57:11 +03:00
// Update the bytes offset
result [ i ] = numPad ( byteCount ) ;
// The length and padded value of data
result . push ( numPad ( data . length ) ) ;
result . push ( bytesPad ( data ) ) ;
byteCount += 32 + Math . ceil ( data . length / 32 ) * 32 ;
}
2022-10-20 12:03:32 +03:00
return ( 0 , index _js _4 . concat ) ( result ) ;
2022-09-27 10:45:27 +03:00
}
function callAddress ( value ) {
2022-11-09 10:57:02 +03:00
( 0 , index _js _4 . assertArgument ) ( value . length === 66 && ( 0 , index _js _4 . dataSlice ) ( value , 0 , 12 ) === "0x000000000000000000000000" , "invalid call address" , "value" , value ) ;
2022-09-27 10:45:27 +03:00
return ( 0 , index _js _1 . getAddress ) ( "0x" + value . substring ( 26 ) ) ;
2022-09-05 23:57:11 +03:00
}
// @TODO: This should use the fetch-data:ipfs gateway
// Trim off the ipfs:// prefix and return the default gateway URL
function getIpfsLink ( link ) {
if ( link . match ( /^ipfs:\/\/ipfs\//i ) ) {
link = link . substring ( 12 ) ;
}
else if ( link . match ( /^ipfs:\/\//i ) ) {
link = link . substring ( 7 ) ;
}
else {
2022-11-09 10:57:02 +03:00
( 0 , index _js _4 . assertArgument ) ( false , "unsupported IPFS format" , "link" , link ) ;
2022-09-05 23:57:11 +03:00
}
return ` https:/ \/ gateway.ipfs.io/ipfs/ ${ link } ` ;
}
;
;
2022-12-10 02:24:58 +03:00
/ * *
* A provider plugin super - class for processing multicoin address types .
* /
2022-09-05 23:57:11 +03:00
class MulticoinProviderPlugin {
name ;
constructor ( name ) {
2022-10-20 12:03:32 +03:00
( 0 , index _js _4 . defineProperties ) ( this , { name } ) ;
2022-09-05 23:57:11 +03:00
}
2022-11-09 10:57:02 +03:00
connect ( proivder ) {
2022-09-05 23:57:11 +03:00
return this ;
}
supportsCoinType ( coinType ) {
return false ;
}
async encodeAddress ( coinType , address ) {
throw new Error ( "unsupported coin" ) ;
}
async decodeAddress ( coinType , data ) {
throw new Error ( "unsupported coin" ) ;
}
}
exports . MulticoinProviderPlugin = MulticoinProviderPlugin ;
2022-11-09 10:57:02 +03:00
const BasicMulticoinPluginId = "org.ethers.plugins.BasicMulticoinProviderPlugin" ;
2022-12-10 02:24:58 +03:00
/ * *
* A basic multicoin provider plugin .
* /
2022-09-05 23:57:11 +03:00
class BasicMulticoinProviderPlugin extends MulticoinProviderPlugin {
constructor ( ) {
super ( BasicMulticoinPluginId ) ;
}
}
exports . BasicMulticoinProviderPlugin = BasicMulticoinProviderPlugin ;
const matcherIpfs = new RegExp ( "^(ipfs):/\/(.*)$" , "i" ) ;
const matchers = [
new RegExp ( "^(https):/\/(.*)$" , "i" ) ,
new RegExp ( "^(data):(.*)$" , "i" ) ,
matcherIpfs ,
new RegExp ( "^eip155:[0-9]+/(erc[0-9]+):(.*)$" , "i" ) ,
] ;
2022-12-10 02:24:58 +03:00
/ * *
* A connected object to a resolved ENS name resolver , which can be
* used to query additional details .
* /
2022-09-05 23:57:11 +03:00
class EnsResolver {
2022-12-10 02:24:58 +03:00
/ * *
* The connected provider .
* /
2022-09-05 23:57:11 +03:00
provider ;
2022-12-10 02:24:58 +03:00
/ * *
* The address of the resolver .
* /
2022-09-05 23:57:11 +03:00
address ;
2022-12-10 02:24:58 +03:00
/ * *
* The name this resovler was resolved against .
* /
2022-09-05 23:57:11 +03:00
name ;
// For EIP-2544 names, the ancestor that provided the resolver
# supports2544 ;
constructor ( provider , address , name ) {
2022-10-20 12:03:32 +03:00
( 0 , index _js _4 . defineProperties ) ( this , { provider , address , name } ) ;
2022-09-05 23:57:11 +03:00
this . # supports2544 = null ;
}
2022-12-10 02:24:58 +03:00
/ * *
* Resolves to true if the resolver supports wildcard resolution .
* /
2022-09-05 23:57:11 +03:00
async supportsWildcard ( ) {
if ( ! this . # supports2544 ) {
// supportsInterface(bytes4 = selector("resolve(bytes,bytes)"))
this . # supports2544 = this . provider . call ( {
to : this . address ,
data : "0x01ffc9a79061b92300000000000000000000000000000000000000000000000000000000"
} ) . then ( ( result ) => {
2022-10-20 12:03:32 +03:00
return ( ( 0 , index _js _4 . getBigInt ) ( result ) === BN _1 ) ;
2022-09-05 23:57:11 +03:00
} ) . catch ( ( error ) => {
if ( error . code === "CALL_EXCEPTION" ) {
return false ;
}
// Rethrow the error: link is down, etc. Let future attempts retry.
this . # supports2544 = null ;
throw error ;
} ) ;
}
return await this . # supports2544 ;
}
2022-12-10 02:24:58 +03:00
/ * *
* Fetch the % % selector % % with % % parameters % % using call , resolving
* recursively if the resolver supports it .
* /
2022-11-30 23:44:23 +03:00
async _fetch ( selector , parameters ) {
if ( parameters == null ) {
parameters = "0x" ;
}
2022-09-05 23:57:11 +03:00
// e.g. keccak256("addr(bytes32,uint256)")
2022-10-20 12:03:32 +03:00
const addrData = ( 0 , index _js _4 . concat ) ( [ selector , ( 0 , index _js _3 . namehash ) ( this . name ) , parameters ] ) ;
2022-09-05 23:57:11 +03:00
const tx = {
to : this . address ,
2022-10-20 12:03:32 +03:00
from : index _js _2 . ZeroAddress ,
2022-09-05 23:57:11 +03:00
enableCcipRead : true ,
data : addrData
} ;
// Wildcard support; use EIP-2544 to resolve the request
let wrapped = false ;
if ( await this . supportsWildcard ( ) ) {
wrapped = true ;
// selector("resolve(bytes,bytes)")
2022-10-20 12:03:32 +03:00
tx . data = ( 0 , index _js _4 . concat ) ( [ "0x9061b923" , encodeBytes ( [ ( 0 , index _js _3 . dnsEncode ) ( this . name ) , addrData ] ) ] ) ;
2022-09-05 23:57:11 +03:00
}
try {
let data = await this . provider . call ( tx ) ;
2022-11-09 10:57:02 +03:00
( 0 , index _js _4 . assert ) ( ( ( 0 , index _js _4 . getBytes ) ( data ) . length % 32 ) !== 4 , "execution reverted during JSON-RPC call (could not parse reason; invalid data length)" , "CALL_EXCEPTION" , {
action : "call" , data , reason : null , transaction : tx ,
invocation : null , revert : null
} ) ;
2022-09-05 23:57:11 +03:00
if ( wrapped ) {
return parseBytes ( data , 0 ) ;
}
return data ;
}
catch ( error ) {
if ( error . code !== "CALL_EXCEPTION" ) {
throw error ;
}
}
return null ;
}
2022-12-10 02:24:58 +03:00
/ * *
* Resolves to the address for % % coinType % % or null if the
* provided % % coinType % % has not been configured .
* /
2022-11-30 23:44:23 +03:00
async getAddress ( coinType ) {
if ( coinType == null ) {
coinType = 60 ;
}
2022-09-05 23:57:11 +03:00
if ( coinType === 60 ) {
try {
// keccak256("addr(bytes32)")
const result = await this . _fetch ( "0x3b3b57de" ) ;
// No address
2022-10-20 12:03:32 +03:00
if ( result == null || result === "0x" || result === index _js _2 . ZeroHash ) {
2022-09-05 23:57:11 +03:00
return null ;
}
2022-09-27 10:45:27 +03:00
return callAddress ( result ) ;
2022-09-05 23:57:11 +03:00
}
catch ( error ) {
if ( error . code === "CALL_EXCEPTION" ) {
return null ;
}
throw error ;
}
}
let coinPlugin = null ;
for ( const plugin of this . provider . plugins ) {
if ( ! ( plugin instanceof MulticoinProviderPlugin ) ) {
continue ;
}
if ( plugin . supportsCoinType ( coinType ) ) {
coinPlugin = plugin ;
break ;
}
}
if ( coinPlugin == null ) {
return null ;
}
// keccak256("addr(bytes32,uint256")
const data = parseBytes ( ( await this . _fetch ( "0xf1cb7e06" , numPad ( coinType ) ) ) || "0x" , 0 ) ;
// No address
if ( data == null || data === "0x" ) {
return null ;
}
// Compute the address
const address = await coinPlugin . encodeAddress ( coinType , data ) ;
if ( address != null ) {
return address ;
}
2022-11-09 10:57:02 +03:00
( 0 , index _js _4 . assert ) ( false , ` invalid coin data ` , "UNSUPPORTED_OPERATION" , {
2022-09-05 23:57:11 +03:00
operation : ` getAddress( ${ coinType } ) ` ,
info : { coinType , data }
} ) ;
}
2022-12-10 02:24:58 +03:00
/ * *
* Resovles to the EIP - 643 text record for % % key % % , or ` ` null ` `
* if unconfigured .
* /
2022-09-05 23:57:11 +03:00
async getText ( key ) {
// The key encoded as parameter to fetchBytes
2022-10-20 12:03:32 +03:00
let keyBytes = ( 0 , index _js _4 . toUtf8Bytes ) ( key ) ;
2022-09-05 23:57:11 +03:00
// The nodehash consumes the first slot, so the string pointer targets
// offset 64, with the length at offset 64 and data starting at offset 96
2022-10-20 12:03:32 +03:00
const calldata = ( 0 , index _js _4 . getBytes ) ( ( 0 , index _js _4 . concat ) ( [ numPad ( 64 ) , numPad ( keyBytes . length ) , keyBytes ] ) ) ;
2022-09-05 23:57:11 +03:00
const hexBytes = parseBytes ( ( await this . _fetch ( "0x59d1d43c" , bytesPad ( calldata ) ) ) || "0x" , 0 ) ;
if ( hexBytes == null || hexBytes === "0x" ) {
return null ;
}
2022-10-20 12:03:32 +03:00
return ( 0 , index _js _4 . toUtf8String ) ( hexBytes ) ;
2022-09-05 23:57:11 +03:00
}
2022-12-10 02:24:58 +03:00
/ * *
* Rsolves to the content - hash or ` ` null ` ` if unconfigured .
* /
2022-09-05 23:57:11 +03:00
async getContentHash ( ) {
// keccak256("contenthash()")
const hexBytes = parseBytes ( ( await this . _fetch ( "0xbc1c58d1" ) ) || "0x" , 0 ) ;
// No contenthash
if ( hexBytes == null || hexBytes === "0x" ) {
return null ;
}
// IPFS (CID: 1, Type: 70=DAG-PB, 72=libp2p-key)
const ipfs = hexBytes . match ( /^0x(e3010170|e5010172)(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/ ) ;
if ( ipfs ) {
const scheme = ( ipfs [ 1 ] === "e3010170" ) ? "ipfs" : "ipns" ;
const length = parseInt ( ipfs [ 4 ] , 16 ) ;
if ( ipfs [ 5 ] . length === length * 2 ) {
2022-10-20 12:03:32 +03:00
return ` ${ scheme } :/ \/ ${ ( 0 , index _js _4 . encodeBase58 ) ( "0x" + ipfs [ 2 ] ) } ` ;
2022-09-05 23:57:11 +03:00
}
}
// Swarm (CID: 1, Type: swarm-manifest; hash/length hard-coded to keccak256/32)
const swarm = hexBytes . match ( /^0xe40101fa011b20([0-9a-f]*)$/ ) ;
if ( swarm && swarm [ 1 ] . length === 64 ) {
return ` bzz:/ \/ ${ swarm [ 1 ] } ` ;
}
2022-11-09 10:57:02 +03:00
( 0 , index _js _4 . assert ) ( false , ` invalid or unsupported content hash data ` , "UNSUPPORTED_OPERATION" , {
2022-09-05 23:57:11 +03:00
operation : "getContentHash()" ,
info : { data : hexBytes }
} ) ;
}
2022-12-10 02:24:58 +03:00
/ * *
* Resolves to the avatar url or ` ` null ` ` if the avatar is either
* unconfigured or incorrectly configured ( e . g . references an NFT
* not owned by the address ) .
*
* If diagnosing issues with configurations , the [ [ _getAvatar ] ]
* method may be useful .
* /
2022-09-05 23:57:11 +03:00
async getAvatar ( ) {
return ( await this . _getAvatar ( ) ) . url ;
}
2022-12-10 02:24:58 +03:00
/ * *
* When resolving an avatar , there are many steps involved , such
* fetching metadata and possibly validating ownership of an
* NFT .
*
* This method can be used to examine each step and the value it
* was working from .
* /
2022-09-05 23:57:11 +03:00
async _getAvatar ( ) {
const linkage = [ { type : "name" , value : this . name } ] ;
try {
// test data for ricmoo.eth
//const avatar = "eip155:1/erc721:0x265385c7f4132228A0d54EB1A9e7460b91c0cC68/29233";
const avatar = await this . getText ( "avatar" ) ;
if ( avatar == null ) {
linkage . push ( { type : "!avatar" , value : "" } ) ;
throw new Error ( "!avatar" ) ;
}
linkage . push ( { type : "avatar" , value : avatar } ) ;
for ( let i = 0 ; i < matchers . length ; i ++ ) {
const match = avatar . match ( matchers [ i ] ) ;
if ( match == null ) {
continue ;
}
const scheme = match [ 1 ] . toLowerCase ( ) ;
switch ( scheme ) {
case "https" :
case "data" :
linkage . push ( { type : "url" , value : avatar } ) ;
return { linkage , url : avatar } ;
case "ipfs" : {
const url = getIpfsLink ( avatar ) ;
linkage . push ( { type : "ipfs" , value : avatar } ) ;
linkage . push ( { type : "url" , value : url } ) ;
return { linkage , url } ;
}
case "erc721" :
case "erc1155" : {
// Depending on the ERC type, use tokenURI(uint256) or url(uint256)
const selector = ( scheme === "erc721" ) ? "0xc87b56dd" : "0x0e89341c" ;
linkage . push ( { type : scheme , value : avatar } ) ;
// The owner of this name
const owner = await this . getAddress ( ) ;
if ( owner == null ) {
linkage . push ( { type : "!owner" , value : "" } ) ;
throw new Error ( "!owner" ) ;
}
const comps = ( match [ 2 ] || "" ) . split ( "/" ) ;
if ( comps . length !== 2 ) {
linkage . push ( { type : ` ! ${ scheme } caip ` , value : ( match [ 2 ] || "" ) } ) ;
throw new Error ( "!caip" ) ;
}
2022-09-27 10:45:27 +03:00
const addr = ( 0 , index _js _1 . getAddress ) ( comps [ 0 ] ) ;
2022-09-05 23:57:11 +03:00
const tokenId = numPad ( comps [ 1 ] ) ;
// Check that this account owns the token
if ( scheme === "erc721" ) {
// ownerOf(uint256 tokenId)
2022-09-27 10:45:27 +03:00
const tokenOwner = callAddress ( await this . provider . call ( {
2022-10-20 12:03:32 +03:00
to : addr , data : ( 0 , index _js _4 . concat ) ( [ "0x6352211e" , tokenId ] )
2022-09-05 23:57:11 +03:00
} ) ) ;
if ( owner !== tokenOwner ) {
linkage . push ( { type : "!owner" , value : tokenOwner } ) ;
throw new Error ( "!owner" ) ;
}
linkage . push ( { type : "owner" , value : tokenOwner } ) ;
}
else if ( scheme === "erc1155" ) {
// balanceOf(address owner, uint256 tokenId)
2022-10-20 12:03:32 +03:00
const balance = ( 0 , index _js _4 . getBigInt ) ( await this . provider . call ( {
to : addr , data : ( 0 , index _js _4 . concat ) ( [ "0x00fdd58e" , ( 0 , index _js _4 . zeroPadValue ) ( owner , 32 ) , tokenId ] )
2022-09-05 23:57:11 +03:00
} ) ) ;
if ( ! balance ) {
linkage . push ( { type : "!balance" , value : "0" } ) ;
throw new Error ( "!balance" ) ;
}
linkage . push ( { type : "balance" , value : balance . toString ( ) } ) ;
}
// Call the token contract for the metadata URL
const tx = {
to : comps [ 0 ] ,
2022-10-20 12:03:32 +03:00
data : ( 0 , index _js _4 . concat ) ( [ selector , tokenId ] )
2022-09-05 23:57:11 +03:00
} ;
let metadataUrl = parseString ( await this . provider . call ( tx ) , 0 ) ;
if ( metadataUrl == null ) {
linkage . push ( { type : "!metadata-url" , value : "" } ) ;
throw new Error ( "!metadata-url" ) ;
}
linkage . push ( { type : "metadata-url-base" , value : metadataUrl } ) ;
// ERC-1155 allows a generic {id} in the URL
if ( scheme === "erc1155" ) {
2022-10-20 12:03:32 +03:00
metadataUrl = metadataUrl . replace ( "{id}" , ( 0 , index _js _4 . hexlify ) ( tokenId ) . substring ( 2 ) ) ;
2022-09-05 23:57:11 +03:00
linkage . push ( { type : "metadata-url-expanded" , value : metadataUrl } ) ;
}
// Transform IPFS metadata links
if ( metadataUrl . match ( /^ipfs:/i ) ) {
metadataUrl = getIpfsLink ( metadataUrl ) ;
}
linkage . push ( { type : "metadata-url" , value : metadataUrl } ) ;
// Get the token metadata
let metadata = { } ;
2022-10-20 12:03:32 +03:00
const response = await ( new index _js _4 . FetchRequest ( metadataUrl ) ) . send ( ) ;
2022-09-05 23:57:11 +03:00
response . assertOk ( ) ;
try {
metadata = response . bodyJson ;
}
catch ( error ) {
try {
linkage . push ( { type : "!metadata" , value : response . bodyText } ) ;
}
catch ( error ) {
const bytes = response . body ;
if ( bytes ) {
2022-10-20 12:03:32 +03:00
linkage . push ( { type : "!metadata" , value : ( 0 , index _js _4 . hexlify ) ( bytes ) } ) ;
2022-09-05 23:57:11 +03:00
}
throw error ;
}
throw error ;
}
if ( ! metadata ) {
linkage . push ( { type : "!metadata" , value : "" } ) ;
throw new Error ( "!metadata" ) ;
}
linkage . push ( { type : "metadata" , value : JSON . stringify ( metadata ) } ) ;
// Pull the image URL out
let imageUrl = metadata . image ;
if ( typeof ( imageUrl ) !== "string" ) {
linkage . push ( { type : "!imageUrl" , value : "" } ) ;
throw new Error ( "!imageUrl" ) ;
}
if ( imageUrl . match ( /^(https:\/\/|data:)/i ) ) {
// Allow
}
else {
// Transform IPFS link to gateway
const ipfs = imageUrl . match ( matcherIpfs ) ;
if ( ipfs == null ) {
linkage . push ( { type : "!imageUrl-ipfs" , value : imageUrl } ) ;
throw new Error ( "!imageUrl-ipfs" ) ;
}
linkage . push ( { type : "imageUrl-ipfs" , value : imageUrl } ) ;
imageUrl = getIpfsLink ( imageUrl ) ;
}
linkage . push ( { type : "url" , value : imageUrl } ) ;
return { linkage , url : imageUrl } ;
}
}
}
}
catch ( error ) {
console . log ( "EE" , error ) ;
}
return { linkage , url : null } ;
}
static async # getResolver ( provider , name ) {
const network = await provider . getNetwork ( ) ;
const ensPlugin = network . getPlugin ( "org.ethers.network-plugins.ens" ) ;
// No ENS...
2022-11-09 10:57:02 +03:00
( 0 , index _js _4 . assert ) ( ensPlugin , "network does not support ENS" , "UNSUPPORTED_OPERATION" , {
operation : "getResolver" , info : { network : network . name }
} ) ;
2022-09-05 23:57:11 +03:00
try {
// keccak256("resolver(bytes32)")
const addrData = await provider . call ( {
to : ensPlugin . address ,
2022-10-20 12:03:32 +03:00
data : ( 0 , index _js _4 . concat ) ( [ "0x0178b8bf" , ( 0 , index _js _3 . namehash ) ( name ) ] ) ,
2022-09-05 23:57:11 +03:00
enableCcipRead : true
} ) ;
2022-09-27 10:45:27 +03:00
const addr = callAddress ( addrData ) ;
2022-10-20 12:03:32 +03:00
if ( addr === ( 0 , index _js _4 . dataSlice ) ( index _js _2 . ZeroHash , 0 , 20 ) ) {
2022-09-05 23:57:11 +03:00
return null ;
}
return addr ;
}
catch ( error ) {
// ENS registry cannot throw errors on resolver(bytes32),
// so probably a link error
throw error ;
}
return null ;
}
2022-12-10 02:24:58 +03:00
/ * *
* Resolve to the ENS resolver for % % name % % using % % provider % % or
* ` ` null ` ` if uncinfigured .
* /
2022-09-05 23:57:11 +03:00
static async fromName ( provider , name ) {
let currentName = name ;
while ( true ) {
if ( currentName === "" || currentName === "." ) {
return null ;
}
// Optimization since the eth node cannot change and does
// not have a wildcar resolver
if ( name !== "eth" && currentName === "eth" ) {
return null ;
}
// Check the current node for a resolver
const addr = await EnsResolver . # getResolver ( provider , currentName ) ;
// Found a resolver!
if ( addr != null ) {
const resolver = new EnsResolver ( provider , addr , name ) ;
// Legacy resolver found, using EIP-2544 so it isn't safe to use
if ( currentName !== name && ! ( await resolver . supportsWildcard ( ) ) ) {
return null ;
}
return resolver ;
}
// Get the parent node
currentName = currentName . split ( "." ) . slice ( 1 ) . join ( "." ) ;
}
}
}
exports . EnsResolver = EnsResolver ;
//# sourceMappingURL=ens-resolver.js.map