diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0bc3b42..d401a77 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ updates: schedule: interval: daily time: "10:00" - open-pull-requests-limit: 10 + open-pull-requests-limit: 20 commit-message: prefix: "deps" prefix-development: "deps(dev)" diff --git a/.github/workflows/js-test-and-release.yml b/.github/workflows/js-test-and-release.yml index 35d87d1..1d7ff79 100644 --- a/.github/workflows/js-test-and-release.yml +++ b/.github/workflows/js-test-and-release.yml @@ -9,7 +9,9 @@ on: permissions: contents: write + id-token: write packages: write + pull-requests: write concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} diff --git a/.github/workflows/semantic-pull-request.yml b/.github/workflows/semantic-pull-request.yml new file mode 100644 index 0000000..bd00f09 --- /dev/null +++ b/.github/workflows/semantic-pull-request.yml @@ -0,0 +1,12 @@ +name: Semantic PR + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + uses: pl-strflt/.github/.github/workflows/reusable-semantic-pull-request.yml@v0.3 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..16d65d7 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,13 @@ +name: Close and mark stale issue + +on: + schedule: + - cron: '0 0 * * *' + +permissions: + issues: write + pull-requests: write + +jobs: + stale: + uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3 diff --git a/.gitignore b/.gitignore index 7d54fd5..7ad9e67 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,3 @@ node_modules package-lock.json yarn.lock .vscode -.env -.envrc -.tool-versions diff --git a/README.md b/README.md index 4523f8f..c4a5655 100644 --- a/README.md +++ b/README.md @@ -13,30 +13,23 @@ > An implementation of IPNS for Helia -## Table of contents - -- [Structure](#structure) -- [API Docs](#api-docs) -- [License](#license) -- [Contribute](#contribute) - -## Structure +# Packages - [`/packages/interop`](./packages/interop) Interop tests for @helia/ipns - [`/packages/ipns`](./packages/ipns) An implementation of IPNS for Helia -## API Docs +# API Docs - -## License +# License Licensed under either of - Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) - MIT ([LICENSE-MIT](LICENSE-MIT) / ) -## Contribute +# Contribute Contributions welcome! Please check out [the issues](https://github.com/ipfs/helia-ipns/issues). diff --git a/package.json b/package.json index c95b525..e75278d 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,10 @@ "bugs": { "url": "https://github.com/ipfs/helia-ipns/issues" }, + "publishConfig": { + "access": "public", + "provenance": true + }, "keywords": [ "ipfs" ], @@ -36,7 +40,7 @@ "docs:no-publish": "NODE_OPTIONS=--max_old_space_size=8192 aegir docs --publish false -- --exclude packages/interop" }, "devDependencies": { - "aegir": "^41.1.14", + "aegir": "^42.0.1", "npm-run-all": "^4.1.5" }, "type": "module", diff --git a/packages/interop/README.md b/packages/interop/README.md index fbdb814..c2ea550 100644 --- a/packages/interop/README.md +++ b/packages/interop/README.md @@ -13,35 +13,14 @@ > Interop tests for @helia/ipns -## Table of contents - -- [Install](#install) - - [Browser ` -``` - -## License +# License Licensed under either of - Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) - MIT ([LICENSE-MIT](LICENSE-MIT) / ) -## Contribute +# Contribute Contributions welcome! Please check out [the issues](https://github.com/ipfs/helia-ipns/issues). diff --git a/packages/interop/package.json b/packages/interop/package.json index f27fc5e..bc49eff 100644 --- a/packages/interop/package.json +++ b/packages/interop/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "description": "Interop tests for @helia/ipns", "license": "Apache-2.0 OR MIT", - "homepage": "https://github.com/ipfs/helia-ipns/tree/master/packages/interop#readme", + "homepage": "https://github.com/ipfs/helia-ipns/tree/main/packages/interop#readme", "repository": { "type": "git", "url": "git+https://github.com/ipfs/helia-ipns.git" @@ -11,6 +11,10 @@ "bugs": { "url": "https://github.com/ipfs/helia-ipns/issues" }, + "publishConfig": { + "access": "public", + "provenance": true + }, "keywords": [ "IPFS" ], @@ -49,32 +53,34 @@ "test:electron-main": "aegir test -t electron-main" }, "devDependencies": { - "@chainsafe/libp2p-gossipsub": "^10.1.0", - "@chainsafe/libp2p-noise": "^13.0.0", - "@chainsafe/libp2p-yamux": "^5.0.0", - "@helia/interface": "^2.0.0", + "@chainsafe/libp2p-gossipsub": "^11.0.1", + "@chainsafe/libp2p-noise": "^14.1.0", + "@chainsafe/libp2p-yamux": "^6.0.1", + "@helia/interface": "^3.0.0", "@helia/ipns": "^3.0.0", - "@libp2p/interface": "^0.1.2", - "@libp2p/kad-dht": "^10.0.4", - "@libp2p/peer-id": "^3.0.2", - "@libp2p/peer-id-factory": "^3.0.3", - "@libp2p/tcp": "^8.0.4", - "@libp2p/websockets": "^7.0.4", - "aegir": "^41.1.14", + "@libp2p/identify": "^1.0.9", + "@libp2p/interface": "^1.1.1", + "@libp2p/kad-dht": "^12.0.2", + "@libp2p/keychain": "^4.0.5", + "@libp2p/peer-id": "^4.0.4", + "@libp2p/peer-id-factory": "^4.0.3", + "@libp2p/tcp": "^9.0.10", + "@libp2p/websockets": "^8.0.10", + "aegir": "^42.0.1", "blockstore-core": "^4.0.1", "datastore-core": "^9.0.3", - "helia": "^2.0.1", + "helia": "^3.0.0", "ipfsd-ctl": "^13.0.0", - "ipns": "^7.0.1", + "ipns": "^8.0.0", "it-all": "^3.0.2", "it-last": "^3.0.1", "it-map": "^3.0.3", - "kubo": "^0.24.0", + "kubo": "^0.25.0", "kubo-rpc-client": "^3.0.0", - "libp2p": "^0.46.6", + "libp2p": "^1.1.1", "merge-options": "^3.0.4", - "multiformats": "^12.0.1", - "uint8arrays": "^4.0.3", + "multiformats": "^13.0.0", + "uint8arrays": "^5.0.1", "wherearewe": "^2.0.1" }, "browser": { diff --git a/packages/interop/test/fixtures/create-helia.ts b/packages/interop/test/fixtures/create-helia.ts index a3826ef..0a8ea11 100644 --- a/packages/interop/test/fixtures/create-helia.ts +++ b/packages/interop/test/fixtures/create-helia.ts @@ -6,10 +6,10 @@ import { MemoryDatastore } from 'datastore-core' import { createHelia } from 'helia' import { createLibp2p, type Libp2pOptions } from 'libp2p' import type { Helia } from '@helia/interface' +import type { Identify } from '@libp2p/identify' import type { Libp2p } from '@libp2p/interface' -import type { IdentifyService } from 'libp2p/identify' -export async function createHeliaNode (config: Libp2pOptions = {}): Promise>> { +export async function createHeliaNode (config: Libp2pOptions = {}): Promise>> { const blockstore = new MemoryBlockstore() const datastore = new MemoryDatastore() diff --git a/packages/interop/test/fixtures/create-peer-ids.ts b/packages/interop/test/fixtures/create-peer-ids.ts index 01faee2..60e0094 100644 --- a/packages/interop/test/fixtures/create-peer-ids.ts +++ b/packages/interop/test/fixtures/create-peer-ids.ts @@ -3,7 +3,7 @@ import map from 'it-map' import { sha256 } from 'multiformats/hashes/sha2' import { compare as uint8ArrayCompare } from 'uint8arrays/compare' import { xor as uint8ArrayXor } from 'uint8arrays/xor' -import type { PeerId } from '@libp2p/interface/peer-id' +import type { PeerId } from '@libp2p/interface' /** * Sort peers by distance to the KadID of the passed buffer diff --git a/packages/interop/test/fixtures/key-types.ts b/packages/interop/test/fixtures/key-types.ts index 4cd7991..cadea32 100644 --- a/packages/interop/test/fixtures/key-types.ts +++ b/packages/interop/test/fixtures/key-types.ts @@ -1,4 +1,4 @@ -import type { PeerIdType } from '@libp2p/interface/peer-id' +import type { PeerIdType } from '@libp2p/interface' export const keyTypes: PeerIdType[] = [ 'Ed25519', diff --git a/packages/interop/test/dht.spec.ts b/packages/interop/test/libp2p.spec.ts similarity index 82% rename from packages/interop/test/dht.spec.ts rename to packages/interop/test/libp2p.spec.ts index bef69b9..87cfc9d 100644 --- a/packages/interop/test/dht.spec.ts +++ b/packages/interop/test/libp2p.spec.ts @@ -1,14 +1,16 @@ /* eslint-env mocha */ import { ipns } from '@helia/ipns' -import { dht } from '@helia/ipns/routing' -import { kadDHT, type DualKadDHT } from '@libp2p/kad-dht' +import { libp2p } from '@helia/ipns/routing' +import { identify } from '@libp2p/identify' +import { kadDHT, removePublicAddressesMapper, type KadDHT } from '@libp2p/kad-dht' +import { keychain, type Keychain } from '@libp2p/keychain' +import { peerIdFromString } from '@libp2p/peer-id' import { createEd25519PeerId, createRSAPeerId, createSecp256k1PeerId } from '@libp2p/peer-id-factory' import { expect } from 'aegir/chai' import { ipnsSelector } from 'ipns/selector' import { ipnsValidator } from 'ipns/validator' import last from 'it-last' -import { identifyService } from 'libp2p/identify' import { CID } from 'multiformats/cid' import * as raw from 'multiformats/codecs/raw' import { sha256 } from 'multiformats/hashes/sha2' @@ -23,13 +25,12 @@ import { keyTypes } from './fixtures/key-types.js' import { waitFor } from './fixtures/wait-for.js' import type { Helia } from '@helia/interface' import type { IPNS } from '@helia/ipns' -import type { Libp2p } from '@libp2p/interface' +import type { Libp2p, PeerId } from '@libp2p/interface' import type { Controller } from 'ipfsd-ctl' -import type { PeerId } from 'kubo-rpc-client/dist/src/types.js' keyTypes.forEach(type => { - describe(`dht routing with ${type} keys`, () => { - let helia: Helia> + describe(`libp2p routing with ${type} keys`, () => { + let helia: Helia> let kubo: Controller let name: IPNS @@ -51,7 +52,7 @@ keyTypes.forEach(type => { helia = await createHeliaNode({ services: { - identify: identifyService(), + identify: identify(), dht: kadDHT({ validators: { ipns: ipnsValidator @@ -60,8 +61,14 @@ keyTypes.forEach(type => { ipns: ipnsSelector }, // skips waiting for the initial self-query to find peers - allowQueryWithZeroPeers: true - }) + allowQueryWithZeroPeers: true, + + // use lan-only mode + protocol: '/ipfs/lan/kad/1.0.0', + peerInfoMapper: removePublicAddressesMapper, + clientMode: false + }), + keychain: keychain() } }) kubo = await createKuboNode() @@ -83,10 +90,10 @@ keyTypes.forEach(type => { const [closest] = await sortClosestPeers(routingKey, [ helia.libp2p.peerId, - kubo.peer.id + peerIdFromString(kubo.peer.id.toString()) ]) - if (resolver === 'kubo' && closest.equals(kubo.peer.id)) { + if (resolver === 'kubo' && closest.equals(peerIdFromString(kubo.peer.id.toString()))) { break } @@ -102,7 +109,7 @@ keyTypes.forEach(type => { await waitFor(async () => { let found = false - for await (const event of helia.libp2p.services.dht.findPeer(kubo.peer.id)) { + for await (const event of helia.libp2p.services.dht.findPeer(peerIdFromString(kubo.peer.id.toString()))) { if (event.name === 'FINAL_PEER') { found = true } @@ -118,6 +125,7 @@ keyTypes.forEach(type => { await waitFor(async () => { let found = false + // @ts-expect-error kubo deps are out of date for await (const event of kubo.api.dht.findPeer(helia.libp2p.peerId)) { if (event.name === 'FINAL_PEER') { found = true @@ -133,7 +141,7 @@ keyTypes.forEach(type => { name = ipns(helia, { routers: [ - dht(helia) + libp2p(helia) ] }) } @@ -152,11 +160,11 @@ keyTypes.forEach(type => { await createNodes('kubo') const keyName = 'my-ipns-key' - await helia.libp2p.keychain.importPeer(keyName, key) + await helia.libp2p.services.keychain.importPeer(keyName, key) await name.publish(key, value) - const resolved = await last(kubo.api.name.resolve(key)) + const resolved = await last(kubo.api.name.resolve(key.toString())) if (resolved == null) { throw new Error('kubo failed to resolve name') diff --git a/packages/interop/test/pubsub.spec.ts b/packages/interop/test/pubsub.spec.ts index ff32652..b8feb78 100644 --- a/packages/interop/test/pubsub.spec.ts +++ b/packages/interop/test/pubsub.spec.ts @@ -4,10 +4,11 @@ import { gossipsub } from '@chainsafe/libp2p-gossipsub' import { ipns } from '@helia/ipns' import { pubsub } from '@helia/ipns/routing' +import { identify } from '@libp2p/identify' +import { keychain, type Keychain } from '@libp2p/keychain' import { peerIdFromKeys } from '@libp2p/peer-id' import { expect } from 'aegir/chai' import last from 'it-last' -import { identifyService } from 'libp2p/identify' import { base36 } from 'multiformats/bases/base36' import { CID } from 'multiformats/cid' import * as raw from 'multiformats/codecs/raw' @@ -23,6 +24,7 @@ import { keyTypes } from './fixtures/key-types.js' import { waitFor } from './fixtures/wait-for.js' import type { Helia } from '@helia/interface' import type { IPNS } from '@helia/ipns' +import type { Identify } from '@libp2p/identify' import type { Libp2p } from '@libp2p/interface' import type { PubSub } from '@libp2p/interface/pubsub' import type { Controller } from 'ipfsd-ctl' @@ -34,15 +36,16 @@ const LIBP2P_KEY_CODEC = 0x72 // resolution because Kubo will use the DHT as well keyTypes.filter(keyType => keyType !== 'RSA').forEach(keyType => { describe(`pubsub routing with ${keyType} keys`, () => { - let helia: Helia> + let helia: Helia> let kubo: Controller let name: IPNS beforeEach(async () => { - helia = await createHeliaNode({ + helia = await createHeliaNode<{ identify: Identify, pubsub: PubSub, keychain: Keychain }>({ services: { - identify: identifyService(), - pubsub: gossipsub() + identify: identify(), + pubsub: gossipsub(), + keychain: keychain() } }) kubo = await createKuboNode({ @@ -75,8 +78,8 @@ keyTypes.filter(keyType => keyType !== 'RSA').forEach(keyType => { const cid = CID.createV1(raw.code, digest) const keyName = 'my-ipns-key' - await helia.libp2p.keychain.createKey(keyName, keyType) - const peerId = await helia.libp2p.keychain.exportPeerId(keyName) + await helia.libp2p.services.keychain.createKey(keyName, keyType) + const peerId = await helia.libp2p.services.keychain.exportPeerId(keyName) if (peerId.publicKey == null) { throw new Error('No public key present') @@ -87,6 +90,7 @@ keyTypes.filter(keyType => keyType !== 'RSA').forEach(keyType => { .with.property('message', 'PublishError.InsufficientPeers') // should fail to resolve the first time as kubo was not subscribed to the pubsub channel + // @ts-expect-error kubo deps are out of date await expect(last(kubo.api.name.resolve(peerId, { timeout: 100 }))).to.eventually.be.undefined() @@ -107,6 +111,7 @@ keyTypes.filter(keyType => keyType !== 'RSA').forEach(keyType => { await name.publish(peerId, cid) // kubo should now be able to resolve IPNS name + // @ts-expect-error kubo deps are out of date const resolved = await last(kubo.api.name.resolve(peerId, { timeout: 100 })) diff --git a/packages/ipns/README.md b/packages/ipns/README.md index 025a5fa..5819b72 100644 --- a/packages/ipns/README.md +++ b/packages/ipns/README.md @@ -17,27 +17,27 @@ IPNS operations using a Helia node -## Example +## Example - Using libp2p and pubsub routers With IPNSRouting routers: ```typescript import { createHelia } from 'helia' import { ipns } from '@helia/ipns' -import { dht, pubsub } from '@helia/ipns/routing' +import { libp2p, pubsub } from '@helia/ipns/routing' import { unixfs } from '@helia/unixfs' const helia = await createHelia() const name = ipns(helia, { routers: [ - dht(helia), + libp2p(helia), pubsub(helia) ] }) // create a public key to publish as an IPNS name -const keyInfo = await helia.libp2p.keychain.createKey('my-key') -const peerId = await helia.libp2p.keychain.exportPeerId(keyInfo.name) +const keyInfo = await helia.libp2p.services.keychain.createKey('my-key') +const peerId = await helia.libp2p.services.keychain.exportPeerId(keyInfo.name) // store some data to publish const fs = unixfs(helia) @@ -50,7 +50,7 @@ await name.publish(peerId, cid) const cid = name.resolve(peerId) ``` -## Example +## Example - Using custom DNS over HTTPS resolvers With default DNSResolver resolvers: @@ -70,7 +70,7 @@ const name = ipns(helia, { const cid = name.resolveDns('some-domain-with-dnslink-entry.com') ``` -## Example +## Example - Resolving a domain with a dnslink entry Calling `resolveDns` with the `@helia/ipns` instance: @@ -90,7 +90,7 @@ console.info(cid) // QmWebsite ``` -## Example +## Example - Using DNS-Over-HTTPS This example uses the Mozilla provided RFC 1035 DNS over HTTPS service. This uses binary DNS records so requires extra dependencies to process the @@ -109,7 +109,7 @@ const cid = name.resolveDns('ipfs.io', { }) ``` -## Example +## Example - Using DNS-JSON-Over-HTTPS DNS-JSON-Over-HTTPS resolvers use the RFC 8427 `application/dns-json` and can result in a smaller browser bundle due to the response being plain JSON. @@ -124,3 +124,40 @@ const cid = name.resolveDns('ipfs.io', { ] }) ``` + +# Install + +```console +$ npm i @helia/ipns +``` + +## Browser ` +``` + +# API Docs + +- + +# License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +# Contribute + +Contributions welcome! Please check out [the issues](https://github.com/ipfs/helia-ipns/issues). + +Also see our [contributing document](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md) for more information on how we work, and about contributing in general. + +Please be aware that all interactions related to this repo are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) diff --git a/packages/ipns/package.json b/packages/ipns/package.json index 9eceaad..cc8f801 100644 --- a/packages/ipns/package.json +++ b/packages/ipns/package.json @@ -3,7 +3,7 @@ "version": "3.0.1", "description": "An implementation of IPNS for Helia", "license": "Apache-2.0 OR MIT", - "homepage": "https://github.com/ipfs/helia-ipns/tree/master/packages/ipns#readme", + "homepage": "https://github.com/ipfs/helia-ipns/tree/main/packages/ipns#readme", "repository": { "type": "git", "url": "git+https://github.com/ipfs/helia-ipns.git" @@ -11,6 +11,10 @@ "bugs": { "url": "https://github.com/ipfs/helia-ipns/issues" }, + "publishConfig": { + "access": "public", + "provenance": true + }, "keywords": [ "IPFS" ], @@ -43,13 +47,13 @@ "types": "./dist/src/index.d.ts", "import": "./dist/src/index.js" }, - "./routing": { - "types": "./dist/src/routing/index.d.ts", - "import": "./dist/src/routing/index.js" - }, "./dns-resolvers": { "types": "./dist/src/dns-resolvers/index.d.ts", "import": "./dist/src/dns-resolvers/index.js" + }, + "./routing": { + "types": "./dist/src/routing/index.d.ts", + "import": "./dist/src/routing/index.js" } }, "eslintConfig": { @@ -159,28 +163,28 @@ "release": "aegir release" }, "dependencies": { - "@libp2p/interface": "^0.1.4", - "@libp2p/kad-dht": "^10.0.11", - "@libp2p/logger": "^3.0.2", - "@libp2p/peer-id": "^3.0.2", - "dns-over-http-resolver": "^2.1.3", + "@libp2p/interface": "^1.1.1", + "@libp2p/kad-dht": "^12.0.2", + "@libp2p/logger": "^4.0.4", + "@libp2p/peer-id": "^4.0.4", + "dns-over-http-resolver": "^3.0.0", "dns-packet": "^5.6.0", "hashlru": "^2.3.0", "interface-datastore": "^8.0.0", - "ipns": "^7.0.1", + "ipns": "^8.0.0", "is-ipfs": "^8.0.1", - "multiformats": "^12.0.1", - "p-queue": "^7.3.0", + "multiformats": "^13.0.0", + "p-queue": "^8.0.1", "progress-events": "^1.0.0", - "uint8arrays": "^4.0.3" + "uint8arrays": "^5.0.1" }, "devDependencies": { - "@libp2p/peer-id-factory": "^3.0.3", + "@libp2p/peer-id-factory": "^4.0.3", "@types/dns-packet": "^5.6.4", - "aegir": "^41.1.14", + "aegir": "^42.0.1", "datastore-core": "^9.0.3", "sinon": "^17.0.0", - "sinon-ts": "^1.0.0" + "sinon-ts": "^2.0.0" }, "browser": { "./dist/src/dns-resolvers/resolver.js": "./dist/src/dns-resolvers/resolver.browser.js" diff --git a/packages/ipns/src/index.ts b/packages/ipns/src/index.ts index bed58b4..16dcee3 100644 --- a/packages/ipns/src/index.ts +++ b/packages/ipns/src/index.ts @@ -3,27 +3,27 @@ * * IPNS operations using a Helia node * - * @example + * @example Using libp2p and pubsub routers * * With {@link IPNSRouting} routers: * * ```typescript * import { createHelia } from 'helia' * import { ipns } from '@helia/ipns' - * import { dht, pubsub } from '@helia/ipns/routing' + * import { libp2p, pubsub } from '@helia/ipns/routing' * import { unixfs } from '@helia/unixfs' * * const helia = await createHelia() * const name = ipns(helia, { * routers: [ - * dht(helia), + * libp2p(helia), * pubsub(helia) * ] * }) * * // create a public key to publish as an IPNS name - * const keyInfo = await helia.libp2p.keychain.createKey('my-key') - * const peerId = await helia.libp2p.keychain.exportPeerId(keyInfo.name) + * const keyInfo = await helia.libp2p.services.keychain.createKey('my-key') + * const peerId = await helia.libp2p.services.keychain.exportPeerId(keyInfo.name) * * // store some data to publish * const fs = unixfs(helia) @@ -36,7 +36,7 @@ * const cid = name.resolve(peerId) * ``` * - * @example + * @example Using custom DNS over HTTPS resolvers * * With default {@link DNSResolver} resolvers: * @@ -56,7 +56,7 @@ * const cid = name.resolveDns('some-domain-with-dnslink-entry.com') * ``` * - * @example + * @example Resolving a domain with a dnslink entry * * Calling `resolveDns` with the `@helia/ipns` instance: * @@ -76,7 +76,7 @@ * // QmWebsite * ``` * - * @example + * @example Using DNS-Over-HTTPS * * This example uses the Mozilla provided RFC 1035 DNS over HTTPS service. This * uses binary DNS records so requires extra dependencies to process the @@ -95,7 +95,7 @@ * }) * ``` * - * @example + * @example Using DNS-JSON-Over-HTTPS * * DNS-JSON-Over-HTTPS resolvers use the RFC 8427 `application/dns-json` and can * result in a smaller browser bundle due to the response being plain JSON. @@ -112,7 +112,7 @@ * ``` */ -import { CodeError } from '@libp2p/interface/errors' +import { CodeError } from '@libp2p/interface' import { logger } from '@libp2p/logger' import { peerIdFromString } from '@libp2p/peer-id' import { create, marshal, peerIdToRoutingKey, unmarshal } from 'ipns' @@ -124,8 +124,7 @@ import { defaultResolver } from './dns-resolvers/default.js' import { localStore, type LocalStore } from './routing/local-store.js' import type { IPNSRouting, IPNSRoutingEvents } from './routing/index.js' import type { DNSResponse } from './utils/dns.js' -import type { AbortOptions } from '@libp2p/interface' -import type { PeerId } from '@libp2p/interface/peer-id' +import type { AbortOptions, PeerId } from '@libp2p/interface' import type { Datastore } from 'interface-datastore' import type { IPNSRecord } from 'ipns' import type { ProgressEvent, ProgressOptions } from 'progress-events' diff --git a/packages/ipns/src/routing/index.ts b/packages/ipns/src/routing/index.ts index 232c221..b29d15c 100644 --- a/packages/ipns/src/routing/index.ts +++ b/packages/ipns/src/routing/index.ts @@ -1,4 +1,4 @@ -import type { DHTProgressEvents } from './dht.js' +import type { Libp2pContentRoutingProgressEvents } from './libp2p.js' import type { DatastoreProgressEvents } from './local-store.js' import type { PubSubProgressEvents } from './pubsub.js' import type { AbortOptions } from '@libp2p/interface' @@ -19,8 +19,8 @@ export interface IPNSRouting { export type IPNSRoutingEvents = DatastoreProgressEvents | - DHTProgressEvents | + Libp2pContentRoutingProgressEvents | PubSubProgressEvents -export { dht } from './dht.js' +export { libp2p } from './libp2p.js' export { pubsub } from './pubsub.js' diff --git a/packages/ipns/src/routing/dht.ts b/packages/ipns/src/routing/libp2p.ts similarity index 58% rename from packages/ipns/src/routing/dht.ts rename to packages/ipns/src/routing/libp2p.ts index ea13b79..cb015b5 100644 --- a/packages/ipns/src/routing/dht.ts +++ b/packages/ipns/src/routing/libp2p.ts @@ -1,21 +1,21 @@ import { CustomProgressEvent, type ProgressEvent } from 'progress-events' import type { GetOptions, PutOptions } from './index.js' import type { IPNSRouting } from '../index.js' -import type { ContentRouting } from '@libp2p/interface/content-routing' +import type { ContentRouting } from '@libp2p/interface' -export interface DHTRoutingComponents { +export interface Libp2pContentRoutingComponents { libp2p: { contentRouting: ContentRouting } } -export type DHTProgressEvents = - ProgressEvent<'ipns:routing:dht:error', Error> +export type Libp2pContentRoutingProgressEvents = + ProgressEvent<'ipns:routing:libp2p:error', Error> -export class DHTRouting implements IPNSRouting { +export class Libp2pContentRouting implements IPNSRouting { private readonly contentRouting: ContentRouting - constructor (components: DHTRoutingComponents) { + constructor (components: Libp2pContentRoutingComponents) { this.contentRouting = components.libp2p.contentRouting } @@ -23,7 +23,7 @@ export class DHTRouting implements IPNSRouting { try { await this.contentRouting.put(routingKey, marshaledRecord, options) } catch (err: any) { - options.onProgress?.(new CustomProgressEvent('ipns:routing:dht:error', err)) + options.onProgress?.(new CustomProgressEvent('ipns:routing:libp2p:error', err)) } } @@ -31,13 +31,17 @@ export class DHTRouting implements IPNSRouting { try { return await this.contentRouting.get(routingKey, options) } catch (err: any) { - options.onProgress?.(new CustomProgressEvent('ipns:routing:dht:error', err)) + options.onProgress?.(new CustomProgressEvent('ipns:routing:libp2p:error', err)) } throw new Error('Not found') } } -export function dht (components: DHTRoutingComponents): IPNSRouting { - return new DHTRouting(components) +/** + * The libp2p routing uses any available Content Routers configured on the + * passed libp2p node. This could be KadDHT, HTTP API Delegated Routing, etc. + */ +export function libp2p (components: Libp2pContentRoutingComponents): IPNSRouting { + return new Libp2pContentRouting(components) } diff --git a/packages/ipns/src/routing/pubsub.ts b/packages/ipns/src/routing/pubsub.ts index 9b08141..4377069 100644 --- a/packages/ipns/src/routing/pubsub.ts +++ b/packages/ipns/src/routing/pubsub.ts @@ -1,4 +1,4 @@ -import { CodeError } from '@libp2p/interface/errors' +import { CodeError } from '@libp2p/interface' import { logger } from '@libp2p/logger' import { peerIdToRoutingKey } from 'ipns' import { ipnsSelector } from 'ipns/selector' @@ -9,8 +9,7 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' import { toString as uint8ArrayToString } from 'uint8arrays/to-string' import { localStore, type LocalStore } from './local-store.js' import type { GetOptions, IPNSRouting, PutOptions } from './index.js' -import type { PeerId } from '@libp2p/interface/peer-id' -import type { Message, PublishResult, PubSub } from '@libp2p/interface/pubsub' +import type { PeerId, Message, PublishResult, PubSub } from '@libp2p/interface' import type { Datastore } from 'interface-datastore' const log = logger('helia:ipns:routing:pubsub') @@ -30,14 +29,6 @@ export type PubSubProgressEvents = ProgressEvent<'ipns:pubsub:subscribe', { topic: string }> | ProgressEvent<'ipns:pubsub:error', Error> -/** - * This IPNS routing receives IPNS record updates via dedicated - * pubsub topic. - * - * Note we must first be subscribed to the topic in order to receive - * updated records, so the first call to `.get` should be expected - * to fail! - */ class PubSubRouting implements IPNSRouting { private subscriptions: string[] private readonly localStore: LocalStore @@ -192,6 +183,14 @@ function topicToKey (topic: string): Uint8Array { return uint8ArrayFromString(key, 'base64url') } +/** + * This IPNS routing receives IPNS record updates via dedicated + * pubsub topic. + * + * Note we must first be subscribed to the topic in order to receive + * updated records, so the first call to `.get` should be expected + * to fail! + */ export function pubsub (components: PubsubRoutingComponents): IPNSRouting { return new PubSubRouting(components) } diff --git a/packages/ipns/src/utils/dns.ts b/packages/ipns/src/utils/dns.ts index 0590efc..a913aa6 100644 --- a/packages/ipns/src/utils/dns.ts +++ b/packages/ipns/src/utils/dns.ts @@ -1,4 +1,4 @@ -import { CodeError } from '@libp2p/interface/errors' +import { CodeError } from '@libp2p/interface' import * as isIPFS from 'is-ipfs' import type { DNSResolver, ResolveDnsLinkOptions } from '../index.js' diff --git a/packages/ipns/typedoc.json b/packages/ipns/typedoc.json index 0c509d8..6873a0a 100644 --- a/packages/ipns/typedoc.json +++ b/packages/ipns/typedoc.json @@ -1,6 +1,7 @@ { "entryPoints": [ "./src/index.ts", + "./src/dns-resolvers/index.ts", "./src/routing/index.ts" ] }