aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/lib/ens-ipfs/resolver.js
blob: 3f0fb00a20e0cd42ee47fcb7c5d61faad64f7df7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const namehash = require('eth-ens-namehash')
const Eth = require('ethjs-query')
const EthContract = require('ethjs-contract')
const registryAbi = require('./contracts/registry')
const resolverAbi = require('./contracts/resolver')
const contentHash = require('content-hash')

module.exports = 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]
    const decodedContentHash = contentHash.decode(rawContentHash)
    const type = contentHash.getCodec(rawContentHash)
    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'
  }
}