diff --git a/package-lock.json b/package-lock.json index 796b8f6..784caa1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@helia/unixfs": "1.x", "blockstore-level": "^1.1.4", "datastore-level": "^10.1.4", + "dns-over-http-resolver": "2.1.3", "fastify": "4.24.3", "fastify-metrics": "10.3.2", "file-type": "18.x", @@ -9803,18 +9804,14 @@ } }, "node_modules/dns-over-http-resolver": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-2.1.2.tgz", - "integrity": "sha512-Bjbf6aZjr3HMnwGslZnoW3MJVqgbTsh39EZWpikx2yLl9xEjw4eZhlOHCFhkOu89zoWaS4rqe2Go53TXW4Byiw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-2.1.3.tgz", + "integrity": "sha512-zjRYFhq+CsxPAouQWzOsxNMvEN+SHisjzhX8EMxd2Y0EG3thvn6wXQgMJLnTDImkhe4jhLbOQpXtL10nALBOSA==", "dependencies": { "debug": "^4.3.1", "native-fetch": "^4.0.2", "receptacle": "^1.3.2", "undici": "^5.12.0" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" } }, "node_modules/dns-packet": { diff --git a/package.json b/package.json index e8c27e0..037d8c2 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@helia/unixfs": "1.x", "blockstore-level": "^1.1.4", "datastore-level": "^10.1.4", + "dns-over-http-resolver": "2.1.3", "fastify": "4.24.3", "fastify-metrics": "10.3.2", "file-type": "18.x", diff --git a/src/heliaFetch.ts b/src/heliaFetch.ts index 47551de..b2a1f40 100644 --- a/src/heliaFetch.ts +++ b/src/heliaFetch.ts @@ -2,6 +2,7 @@ import { unixfs, type UnixFS } from '@helia/unixfs' import { MemoryBlockstore } from 'blockstore-core' import { MemoryDatastore } from 'datastore-core' import debug from 'debug' +import DOHResolver from 'dns-over-http-resolver' import { createHelia, type Helia } from 'helia' import { LRUCache } from 'lru-cache' import { CID } from 'multiformats/cid' @@ -13,8 +14,6 @@ const ROOT_FILE_PATTERNS = [ 'index.shtml' ] -const DELEGATED_ROUTING_API = 'https://node3.delegate.ipfs.io/api/v0/name/resolve/' - interface HeliaPathParts { namespace: string address: string @@ -25,8 +24,8 @@ interface HeliaPathParts { * Fetches files from IPFS or IPNS */ export class HeliaFetch { + private readonly dohResolver = new DOHResolver() private fs!: UnixFS - private readonly delegatedRoutingApi: string private readonly log: debug.Debugger private readonly PARSE_PATH_REGEX = /^\/(?ip[fn]s)\/(?
[^/$]+)(?[^$^?]*)/ private readonly rootFilePatterns: string[] @@ -40,12 +39,10 @@ export class HeliaFetch { constructor ({ node, rootFilePatterns = ROOT_FILE_PATTERNS, - delegatedRoutingApi = DELEGATED_ROUTING_API, logger }: { node?: Helia rootFilePatterns?: string[] - delegatedRoutingApi?: string logger?: debug.Debugger } = {}) { // setup a logger @@ -59,7 +56,6 @@ export class HeliaFetch { this.node = node } this.rootFilePatterns = rootFilePatterns - this.delegatedRoutingApi = delegatedRoutingApi this.ready = this.init() this.log('Initialized') } @@ -160,9 +156,12 @@ export class HeliaFetch { */ private async fetchIpns (address: string, options?: Parameters[1]): Promise> { if (!this.ipnsResolutionCache.has(address)) { - this.log('Fetching from Delegate Routing:', address) - const { Path } = await (await fetch(this.delegatedRoutingApi + address)).json() - this.ipnsResolutionCache.set(address, Path ?? 'not-found') + this.log('Fetching from DNS over HTTP:', address) + const txtRecords = await this.dohResolver.resolveTxt(`_dnslink.${address}`) + const pathEntry = txtRecords.find(([record]) => record.startsWith('dnslink=')) + const path = pathEntry?.[0].replace('dnslink=', '') + this.log('Got Path from DNS over HTTP:', path) + this.ipnsResolutionCache.set(address, path ?? 'not-found') } if (this.ipnsResolutionCache.get(address) === 'not-found') { this.log('No Path found:', address)