2021-02-04 19:15:23 +01:00
|
|
|
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';
|
2018-10-21 11:48:15 +02:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
export default async function resolveEnsToIpfsContentId({ provider, name }) {
|
2021-02-04 19:15:23 +01:00
|
|
|
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
|
2021-02-04 19:15:23 +01:00
|
|
|
const chainId = Number.parseInt(await eth.net_version(), 10);
|
|
|
|
const registryAddress = getRegistryForChainId(chainId);
|
2019-04-04 14:07:24 +02:00
|
|
|
if (!registryAddress) {
|
2020-11-03 00:41:28 +01:00
|
|
|
throw new Error(
|
|
|
|
`EnsIpfsResolver - no known ens-ipfs registry for chainId "${chainId}"`,
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2018-10-21 11:48:15 +02:00
|
|
|
}
|
2021-02-04 19:15:23 +01:00
|
|
|
const Registry = contract(registryAbi).at(registryAddress);
|
2018-10-21 11:48:15 +02:00
|
|
|
// lookup resolver
|
2021-02-04 19:15:23 +01:00
|
|
|
const resolverLookupResult = await Registry.resolver(hash);
|
|
|
|
const resolverAddress = resolverLookupResult[0];
|
2018-10-21 11:48:15 +02:00
|
|
|
if (hexValueIsEmpty(resolverAddress)) {
|
2021-02-04 19:15:23 +01:00
|
|
|
throw new Error(`EnsIpfsResolver - no resolver found for name "${name}"`);
|
2018-10-21 11:48:15 +02:00
|
|
|
}
|
2021-02-04 19:15:23 +01:00
|
|
|
const Resolver = contract(resolverAbi).at(resolverAddress);
|
2019-04-04 17:15:57 +02:00
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
const isEIP1577Compliant = await Resolver.supportsInterface('0xbc1c58d1');
|
|
|
|
const isLegacyResolver = await Resolver.supportsInterface('0xd8389dc5');
|
2019-04-04 17:15:57 +02:00
|
|
|
if (isEIP1577Compliant[0]) {
|
2021-02-04 19:15:23 +01:00
|
|
|
const contentLookupResult = await Resolver.contenthash(hash);
|
|
|
|
const rawContentHash = contentLookupResult[0];
|
|
|
|
let decodedContentHash = contentHash.decode(rawContentHash);
|
|
|
|
const type = contentHash.getCodec(rawContentHash);
|
2019-12-12 20:28:07 +01:00
|
|
|
|
2020-05-14 12:26:27 +02:00
|
|
|
if (type === 'ipfs-ns' || type === 'ipns-ns') {
|
2020-11-03 00:41:28 +01:00
|
|
|
decodedContentHash = contentHash.helpers.cidV0ToV1Base32(
|
|
|
|
decodedContentHash,
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2019-12-12 20:28:07 +01:00
|
|
|
}
|
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
return { type, hash: decodedContentHash };
|
2019-04-04 17:15:57 +02:00
|
|
|
}
|
|
|
|
if (isLegacyResolver[0]) {
|
|
|
|
// lookup content id
|
2021-02-04 19:15:23 +01:00
|
|
|
const contentLookupResult = await Resolver.content(hash);
|
|
|
|
const content = contentLookupResult[0];
|
2019-04-04 17:15:57 +02:00
|
|
|
if (hexValueIsEmpty(content)) {
|
2020-11-03 00:41:28 +01:00
|
|
|
throw new Error(
|
|
|
|
`EnsIpfsResolver - no content ID found for name "${name}"`,
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2019-04-04 17:15:57 +02:00
|
|
|
}
|
2021-02-04 19:15:23 +01:00
|
|
|
return { type: 'swarm-ns', hash: content.slice(2) };
|
2018-10-21 11:48:15 +02:00
|
|
|
}
|
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()`,
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2018-10-21 11:48:15 +02:00
|
|
|
}
|
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
function hexValueIsEmpty(value) {
|
|
|
|
return [
|
|
|
|
undefined,
|
|
|
|
null,
|
|
|
|
'0x',
|
|
|
|
'0x0',
|
|
|
|
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
2021-02-04 19:15:23 +01:00
|
|
|
].includes(value);
|
2018-10-21 11:48:15 +02:00
|
|
|
}
|
|
|
|
|
2020-01-30 16:33:28 +01:00
|
|
|
/**
|
|
|
|
* Returns the registry address for the given chain ID
|
2020-11-10 18:30:41 +01:00
|
|
|
* @param {number} chainId - the chain ID
|
2020-01-30 16:33:28 +01:00
|
|
|
* @returns {string|null} the registry address if known, null otherwise
|
|
|
|
*/
|
2020-11-03 00:41:28 +01:00
|
|
|
function getRegistryForChainId(chainId) {
|
2018-10-21 11:48:15 +02:00
|
|
|
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
|
2021-02-04 19:15:23 +01:00
|
|
|
return '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
|
2019-11-27 17:08:35 +01:00
|
|
|
default:
|
2021-02-04 19:15:23 +01:00
|
|
|
return null;
|
2018-10-21 11:48:15 +02:00
|
|
|
}
|
|
|
|
}
|