You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.7 KiB
77 lines
2.7 KiB
import namehash from 'eth-ens-namehash'
|
|
import Eth from 'ethjs-query'
|
|
import EthContract from 'ethjs-contract'
|
|
import registryAbi from './contracts/registry'
|
|
import resolverAbi from './contracts/resolver'
|
|
import contentHash from 'content-hash'
|
|
|
|
export default resolveEnsToIpfsContentId
|
|
|
|
|
|
async function resolveEnsToIpfsContentId ({ provider, name }) {
|
|
const eth = new Eth(provider)
|
|
const hash = namehash.hash(name)
|
|
const contract = new EthContract(eth)
|
|
// lookup registry
|
|
const chainId = Number.parseInt(await eth.net_version(), 10)
|
|
const registryAddress = getRegistryForChainId(chainId)
|
|
if (!registryAddress) {
|
|
throw new Error(`EnsIpfsResolver - no known ens-ipfs registry for chainId "${chainId}"`)
|
|
}
|
|
const Registry = contract(registryAbi).at(registryAddress)
|
|
// lookup resolver
|
|
const resolverLookupResult = await Registry.resolver(hash)
|
|
const resolverAddress = resolverLookupResult[0]
|
|
if (hexValueIsEmpty(resolverAddress)) {
|
|
throw new Error(`EnsIpfsResolver - no resolver found for name "${name}"`)
|
|
}
|
|
const Resolver = contract(resolverAbi).at(resolverAddress)
|
|
|
|
const isEIP1577Compliant = await Resolver.supportsInterface('0xbc1c58d1')
|
|
const isLegacyResolver = await Resolver.supportsInterface('0xd8389dc5')
|
|
if (isEIP1577Compliant[0]) {
|
|
const contentLookupResult = await Resolver.contenthash(hash)
|
|
const rawContentHash = contentLookupResult[0]
|
|
let decodedContentHash = contentHash.decode(rawContentHash)
|
|
const type = contentHash.getCodec(rawContentHash)
|
|
|
|
if (type === 'ipfs-ns') {
|
|
decodedContentHash = contentHash.helpers.cidV0ToV1Base32(decodedContentHash)
|
|
}
|
|
|
|
return { type: type, hash: decodedContentHash }
|
|
}
|
|
if (isLegacyResolver[0]) {
|
|
// lookup content id
|
|
const contentLookupResult = await Resolver.content(hash)
|
|
const content = contentLookupResult[0]
|
|
if (hexValueIsEmpty(content)) {
|
|
throw new Error(`EnsIpfsResolver - no content ID found for name "${name}"`)
|
|
}
|
|
return { type: 'swarm-ns', hash: content.slice(2) }
|
|
}
|
|
throw new Error(`EnsIpfsResolver - the resolver for name "${name}" is not standard, it should either supports contenthash() or content()`)
|
|
}
|
|
|
|
function hexValueIsEmpty (value) {
|
|
return [undefined, null, '0x', '0x0', '0x0000000000000000000000000000000000000000000000000000000000000000'].includes(value)
|
|
}
|
|
|
|
function getRegistryForChainId (chainId) {
|
|
switch (chainId) {
|
|
// mainnet
|
|
case 1:
|
|
return '0x314159265dd8dbb310642f98f50c066173c1259b'
|
|
// ropsten
|
|
case 3:
|
|
return '0x112234455c3a32fd11230c42e7bccd4a84e02010'
|
|
// rinkeby
|
|
case 4:
|
|
return '0xe7410170f87102df0055eb195163a03b7f2bff4a'
|
|
// goerli
|
|
case 5:
|
|
return '0x112234455c3a32fd11230c42e7bccd4a84e02010'
|
|
default:
|
|
return null
|
|
}
|
|
}
|
|
|