1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-23 20:05:27 +02:00
metamask-extension/app/scripts/lib/ens-ipfs/resolver.js

88 lines
2.8 KiB
JavaScript
Raw Normal View History

import namehash from 'eth-ens-namehash'
import Eth from 'ethjs-query'
import EthContract from 'ethjs-contract'
import contentHash from 'content-hash'
import registryAbi from './contracts/registry'
import resolverAbi from './contracts/resolver'
2020-11-03 00:41:28 +01:00
export default async function resolveEnsToIpfsContentId({ provider, name }) {
const eth = new Eth(provider)
const hash = namehash.hash(name)
const contract = new EthContract(eth)
2019-04-04 14:07:24 +02:00
// lookup registry
const chainId = Number.parseInt(await eth.net_version(), 10)
2019-04-04 14:07:24 +02:00
const registryAddress = getRegistryForChainId(chainId)
if (!registryAddress) {
2020-11-03 00:41:28 +01:00
throw new Error(
`EnsIpfsResolver - no known ens-ipfs registry for chainId "${chainId}"`,
)
}
2019-04-04 14:07:24 +02:00
const Registry = contract(registryAbi).at(registryAddress)
// lookup resolver
2019-04-04 14:07:24 +02:00
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)
2019-04-04 17:15:57 +02:00
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)
2019-04-04 17:15:57 +02:00
const type = contentHash.getCodec(rawContentHash)
if (type === 'ipfs-ns' || type === 'ipns-ns') {
2020-11-03 00:41:28 +01:00
decodedContentHash = contentHash.helpers.cidV0ToV1Base32(
decodedContentHash,
)
}
return { type, hash: decodedContentHash }
2019-04-04 17:15:57 +02:00
}
if (isLegacyResolver[0]) {
// lookup content id
const contentLookupResult = await Resolver.content(hash)
const content = contentLookupResult[0]
if (hexValueIsEmpty(content)) {
2020-11-03 00:41:28 +01:00
throw new Error(
`EnsIpfsResolver - no content ID found for name "${name}"`,
)
2019-04-04 17:15:57 +02:00
}
2019-12-03 21:50:55 +01:00
return { type: 'swarm-ns', hash: content.slice(2) }
}
2020-11-03 00:41:28 +01:00
throw new Error(
`EnsIpfsResolver - the resolver for name "${name}" is not standard, it should either supports contenthash() or content()`,
)
}
2020-11-03 00:41:28 +01:00
function hexValueIsEmpty(value) {
return [
undefined,
null,
'0x',
'0x0',
'0x0000000000000000000000000000000000000000000000000000000000000000',
].includes(value)
}
2020-01-30 16:33:28 +01:00
/**
* Returns the registry address for the given chain ID
* @param {number} chainId the chain ID
* @returns {string|null} the registry address if known, null otherwise
*/
2020-11-03 00:41:28 +01:00
function getRegistryForChainId(chainId) {
switch (chainId) {
case 1:
case 3:
2019-05-04 18:56:45 +02:00
case 4:
case 5:
2020-01-30 16:33:28 +01:00
// Mainnet, Ropsten, Rinkeby, and Goerli, respectively, use the same address
return '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'
default:
return null
}
}