diff --git a/.gitignore b/.gitignore index c31542c23e..7ad9e674ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ node_modules +build dist .docs .coverage +node_modules package-lock.json yarn.lock -.vscode \ No newline at end of file +.vscode diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/interop/package.json b/interop/package.json index a973758599..78108d265b 100644 --- a/interop/package.json +++ b/interop/package.json @@ -7,9 +7,6 @@ "main": "index.js", "author": "Glen De Cauwsemaecker / @marcopolo", "license": "MIT", - "engines": { - "node": ">=18" - }, "scripts": { "start": "node index.js", "build": "aegir build", diff --git a/package.json b/package.json index 4834f79835..8f198fb6ac 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "dep-check": "aegir run dep-check", "release": "run-s build npm:release", "npm:release": "aegir exec npm -- publish", - "release:rc": "aegir release-rc" + "release:rc": "aegir release-rc", + "docs": "NODE_OPTIONS=--max_old_space_size=4096 aegir docs" }, "devDependencies": { "aegir": "^39.0.5" diff --git a/packages/interface-address-manager/CHANGELOG.md b/packages/interface-address-manager/CHANGELOG.md new file mode 100644 index 0000000000..6ecab8d4eb --- /dev/null +++ b/packages/interface-address-manager/CHANGELOG.md @@ -0,0 +1,111 @@ +## [@libp2p/interface-address-manager-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v3.0.0...@libp2p/interface-address-manager-v3.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-address-manager-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v2.0.5...@libp2p/interface-address-manager-v3.0.0) (2023-04-21) + + +### ⚠ BREAKING CHANGES + +* add libp2p events (#373) + +### Features + +* add libp2p events ([#373](https://github.com/libp2p/js-libp2p-interfaces/issues/373)) ([071c718](https://github.com/libp2p/js-libp2p-interfaces/commit/071c718808902858818ca86167b51b242b67a5a5)) + +## [@libp2p/interface-address-manager-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v2.0.4...@libp2p/interface-address-manager-v2.0.5) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-address-manager-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v2.0.3...@libp2p/interface-address-manager-v2.0.4) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-address-manager-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v2.0.2...@libp2p/interface-address-manager-v2.0.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-address-manager-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v2.0.1...@libp2p/interface-address-manager-v2.0.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + + +### Dependencies + +* update sibling dependencies ([947cedc](https://github.com/libp2p/js-libp2p-interfaces/commit/947cedcc25aa147768ee5b76577d069491db6ef6)) + +## [@libp2p/interface-address-manager-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v2.0.0...@libp2p/interface-address-manager-v2.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-address-manager-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v1.0.3...@libp2p/interface-address-manager-v2.0.0) (2022-10-07) + + +### ⚠ BREAKING CHANGES + +* add observed address methods (#269) + +### Features + +* add observed address methods ([#269](https://github.com/libp2p/js-libp2p-interfaces/issues/269)) ([0b157d5](https://github.com/libp2p/js-libp2p-interfaces/commit/0b157d5666caaaaa8676265cab3e4b010872ee41)) + +## [@libp2p/interface-address-manager-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v1.0.2...@libp2p/interface-address-manager-v1.0.3) (2022-09-21) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-address-manager-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v1.0.1...@libp2p/interface-address-manager-v1.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-address-manager-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-address-manager-v1.0.0...@libp2p/interface-address-manager-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-address-manager-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-address-manager/LICENSE b/packages/interface-address-manager/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-address-manager/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-address-manager/LICENSE-APACHE b/packages/interface-address-manager/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-address-manager/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-address-manager/LICENSE-MIT b/packages/interface-address-manager/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-address-manager/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-address-manager/README.md b/packages/interface-address-manager/README.md new file mode 100644 index 0000000000..04c77b6cf7 --- /dev/null +++ b/packages/interface-address-manager/README.md @@ -0,0 +1,43 @@ +# @libp2p/interface-address-manager + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Address Manager interface for libp2p + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-address-manager +``` + +## Usage + +```js +import type { AddressManager } from '@libp2p/interfaces-address-manager' +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-address-manager/package.json b/packages/interface-address-manager/package.json new file mode 100644 index 0000000000..f02b1d170b --- /dev/null +++ b/packages/interface-address-manager/package.json @@ -0,0 +1,139 @@ +{ + "name": "@libp2p/interface-address-manager", + "version": "3.0.1", + "description": "Address Manager interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-address-manager#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@multiformats/multiaddr": "^12.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-address-manager/src/index.ts b/packages/interface-address-manager/src/index.ts new file mode 100644 index 0000000000..622e0cb315 --- /dev/null +++ b/packages/interface-address-manager/src/index.ts @@ -0,0 +1,43 @@ +import type { Multiaddr } from '@multiformats/multiaddr' + +export interface AddressManager { + /** + * Get peer listen multiaddrs + */ + getListenAddrs: () => Multiaddr[] + + /** + * Get peer announcing multiaddrs + */ + getAnnounceAddrs: () => Multiaddr[] + + /** + * Get observed multiaddrs - these addresses may not have been confirmed as + * publicly dialable yet + */ + getObservedAddrs: () => Multiaddr[] + + /** + * Signal that we have confidence an observed multiaddr is publicly dialable - + * this will make it appear in the output of getAddresses() + */ + confirmObservedAddr: (addr: Multiaddr) => void + + /** + * Signal that we do not have confidence an observed multiaddr is publicly dialable - + * this will remove it from the output of getObservedAddrs() + */ + removeObservedAddr: (addr: Multiaddr) => void + + /** + * Add peer observed addresses. These will then appear in the output of getObservedAddrs + * but not getAddresses() until their dialability has been confirmed via a call to + * confirmObservedAddr. + */ + addObservedAddr: (addr: Multiaddr) => void + + /** + * Get the current node's addresses + */ + getAddresses: () => Multiaddr[] +} diff --git a/packages/interface-address-manager/tsconfig.json b/packages/interface-address-manager/tsconfig.json new file mode 100644 index 0000000000..5fe8ea40d7 --- /dev/null +++ b/packages/interface-address-manager/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ] +} diff --git a/packages/interface-compliance-tests/CHANGELOG.md b/packages/interface-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..35f9edbfff --- /dev/null +++ b/packages/interface-compliance-tests/CHANGELOG.md @@ -0,0 +1,530 @@ +## [@libp2p/interface-compliance-tests-v3.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v3.0.6...@libp2p/interface-compliance-tests-v3.0.7) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-compliance-tests-v3.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v3.0.5...@libp2p/interface-compliance-tests-v3.0.6) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-compliance-tests-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v3.0.4...@libp2p/interface-compliance-tests-v3.0.5) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-compliance-tests-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v3.0.3...@libp2p/interface-compliance-tests-v3.0.4) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-compliance-tests-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v3.0.2...@libp2p/interface-compliance-tests-v3.0.3) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-compliance-tests-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v3.0.1...@libp2p/interface-compliance-tests-v3.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-compliance-tests-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v3.0.0...@libp2p/interface-compliance-tests-v3.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## [@libp2p/interface-compliance-tests-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v2.0.3...@libp2p/interface-compliance-tests-v3.0.0) (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) + +## [@libp2p/interface-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v2.0.2...@libp2p/interface-compliance-tests-v2.0.3) (2022-05-24) + + +### Bug Fixes + +* only close muxed stream for reading ([#220](https://github.com/libp2p/js-libp2p-interfaces/issues/220)) ([f2f7141](https://github.com/libp2p/js-libp2p-interfaces/commit/f2f7141f01af715e600201ac9e7e52fbbb5c7e1b)) + +## [@libp2p/interface-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v2.0.1...@libp2p/interface-compliance-tests-v2.0.2) (2022-05-24) + + +### Bug Fixes + +* accept abort options in connection.newStream ([#219](https://github.com/libp2p/js-libp2p-interfaces/issues/219)) ([8bfcbc9](https://github.com/libp2p/js-libp2p-interfaces/commit/8bfcbc9ee883336f213cdfc83e477549ca368df5)) +* chunk data in mock muxer ([#218](https://github.com/libp2p/js-libp2p-interfaces/issues/218)) ([14604f6](https://github.com/libp2p/js-libp2p-interfaces/commit/14604f69a858bf8c16ce118420c5e49f3f5331ea)) + +## [@libp2p/interface-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v2.0.0...@libp2p/interface-compliance-tests-v2.0.1) (2022-05-23) + + +### Bug Fixes + +* make stream return types synchronous ([#217](https://github.com/libp2p/js-libp2p-interfaces/issues/217)) ([2fe61b7](https://github.com/libp2p/js-libp2p-interfaces/commit/2fe61b7fbeda2e549edf095a927d623aa8eb476b)) + +## [@libp2p/interface-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.34...@libp2p/interface-compliance-tests-v2.0.0) (2022-05-20) + + +### ⚠ BREAKING CHANGES + +* This adds closeWrite and closeRead checks in the tests, which will cause test failures for muxers that don't implement those + +### Bug Fixes + +* close streams when connection is closed ([#214](https://github.com/libp2p/js-libp2p-interfaces/issues/214)) ([88fcd58](https://github.com/libp2p/js-libp2p-interfaces/commit/88fcd586276e03dd740c7095f05e21754ac1f3b5)), closes [#90](https://github.com/libp2p/js-libp2p-interfaces/issues/90) +* update interfaces ([#215](https://github.com/libp2p/js-libp2p-interfaces/issues/215)) ([72e6890](https://github.com/libp2p/js-libp2p-interfaces/commit/72e6890826dadbd6e7cbba5536bde350ca4286e6)) + +## [@libp2p/interface-compliance-tests-v1.1.34](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.33...@libp2p/interface-compliance-tests-v1.1.34) (2022-05-10) + + +### Trivial Changes + +* **deps:** bump sinon from 13.0.2 to 14.0.0 ([#211](https://github.com/libp2p/js-libp2p-interfaces/issues/211)) ([8859f70](https://github.com/libp2p/js-libp2p-interfaces/commit/8859f70943c0bcdb210f54a338ae901739e5e6f2)) + +## [@libp2p/interface-compliance-tests-v1.1.33](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.32...@libp2p/interface-compliance-tests-v1.1.33) (2022-05-06) + + +### Bug Fixes + +* add tag to peer discovery interface ([#210](https://github.com/libp2p/js-libp2p-interfaces/issues/210)) ([f99c833](https://github.com/libp2p/js-libp2p-interfaces/commit/f99c833c8436f8434f380d890ec5d267279312d7)) + +## [@libp2p/interface-compliance-tests-v1.1.32](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.31...@libp2p/interface-compliance-tests-v1.1.32) (2022-05-04) + + +### Bug Fixes + +* move startable and events interfaces ([#209](https://github.com/libp2p/js-libp2p-interfaces/issues/209)) ([8ce8a08](https://github.com/libp2p/js-libp2p-interfaces/commit/8ce8a08c94b0738aa32da516558977b195ddd8ed)) + +## [@libp2p/interface-compliance-tests-v1.1.31](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.30...@libp2p/interface-compliance-tests-v1.1.31) (2022-05-03) + + +### Bug Fixes + +* only send handled protocols ([#207](https://github.com/libp2p/js-libp2p-interfaces/issues/207)) ([1f7afc2](https://github.com/libp2p/js-libp2p-interfaces/commit/1f7afc29d72fde708064ec6479011dbc0a225962)) + +## [@libp2p/interface-compliance-tests-v1.1.30](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.29...@libp2p/interface-compliance-tests-v1.1.30) (2022-05-01) + + +### Bug Fixes + +* move connection manager mock to connection manager module ([#205](https://github.com/libp2p/js-libp2p-interfaces/issues/205)) ([a367375](https://github.com/libp2p/js-libp2p-interfaces/commit/a367375accc690d7b4608c9a3313f91df700efd8)) + +## [@libp2p/interface-compliance-tests-v1.1.29](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.28...@libp2p/interface-compliance-tests-v1.1.29) (2022-04-28) + + +### Bug Fixes + +* pubsub should not be startable ([#204](https://github.com/libp2p/js-libp2p-interfaces/issues/204)) ([59bd924](https://github.com/libp2p/js-libp2p-interfaces/commit/59bd9245a207268525bdd26a05c5306fe436fcc4)) + +## [@libp2p/interface-compliance-tests-v1.1.28](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.27...@libp2p/interface-compliance-tests-v1.1.28) (2022-04-28) + + +### Bug Fixes + +* pubsub and dht are always set ([#203](https://github.com/libp2p/js-libp2p-interfaces/issues/203)) ([86860c1](https://github.com/libp2p/js-libp2p-interfaces/commit/86860c1836a2464b2ad380b09542e3f3271ae287)) + +## [@libp2p/interface-compliance-tests-v1.1.27](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.26...@libp2p/interface-compliance-tests-v1.1.27) (2022-04-26) + + +### Bug Fixes + +* add delays for gossipsub ([#202](https://github.com/libp2p/js-libp2p-interfaces/issues/202)) ([cf85799](https://github.com/libp2p/js-libp2p-interfaces/commit/cf85799fdd0d4848ad2187bbbb0dd6ac5e8cb254)) + +## [@libp2p/interface-compliance-tests-v1.1.26](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.25...@libp2p/interface-compliance-tests-v1.1.26) (2022-04-25) + + +### Bug Fixes + +* stop pubsub after test ([#200](https://github.com/libp2p/js-libp2p-interfaces/issues/200)) ([2d2650c](https://github.com/libp2p/js-libp2p-interfaces/commit/2d2650cb8cabce137665aafd55a2fb14cbd5dacd)) + +## [@libp2p/interface-compliance-tests-v1.1.25](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.24...@libp2p/interface-compliance-tests-v1.1.25) (2022-04-22) + + +### Bug Fixes + +* update pubsub interface in line with gossipsub ([#199](https://github.com/libp2p/js-libp2p-interfaces/issues/199)) ([3f55596](https://github.com/libp2p/js-libp2p-interfaces/commit/3f555965cddea3ef03e7217b755c82aa4107e093)) + +## [@libp2p/interface-compliance-tests-v1.1.24](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.23...@libp2p/interface-compliance-tests-v1.1.24) (2022-04-21) + + +### Bug Fixes + +* test PubSub interface and not PubSubBaseProtocol ([#198](https://github.com/libp2p/js-libp2p-interfaces/issues/198)) ([96c15c9](https://github.com/libp2p/js-libp2p-interfaces/commit/96c15c9780821a3cb763e48854d64377bf562692)) + +## [@libp2p/interface-compliance-tests-v1.1.23](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.22...@libp2p/interface-compliance-tests-v1.1.23) (2022-04-20) + + +### Bug Fixes + +* emit pubsub messages using 'message' event ([#197](https://github.com/libp2p/js-libp2p-interfaces/issues/197)) ([df9b685](https://github.com/libp2p/js-libp2p-interfaces/commit/df9b685cea30653109f2fa2cb5583a3bca7b09bb)) + +## [@libp2p/interface-compliance-tests-v1.1.22](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.21...@libp2p/interface-compliance-tests-v1.1.22) (2022-04-19) + + +### Bug Fixes + +* move dev deps to prod ([#195](https://github.com/libp2p/js-libp2p-interfaces/issues/195)) ([3e1ffc7](https://github.com/libp2p/js-libp2p-interfaces/commit/3e1ffc7b174e74be483943ad4e5fcab823ae3f6d)) + +## [@libp2p/interface-compliance-tests-v1.1.21](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.20...@libp2p/interface-compliance-tests-v1.1.21) (2022-04-08) + + +### Bug Fixes + +* swap protobufjs for protons ([#191](https://github.com/libp2p/js-libp2p-interfaces/issues/191)) ([d72b30c](https://github.com/libp2p/js-libp2p-interfaces/commit/d72b30cfca4b9145e0b31db28e8fa3329a180e83)) + + +### Trivial Changes + +* update aegir ([#192](https://github.com/libp2p/js-libp2p-interfaces/issues/192)) ([41c1494](https://github.com/libp2p/js-libp2p-interfaces/commit/41c14941e8b67d6601a90b4d48a2776573d55e60)) + +## [@libp2p/interface-compliance-tests-v1.1.20](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.19...@libp2p/interface-compliance-tests-v1.1.20) (2022-03-24) + + +### Bug Fixes + +* rename peer data to peer info ([#187](https://github.com/libp2p/js-libp2p-interfaces/issues/187)) ([dfea342](https://github.com/libp2p/js-libp2p-interfaces/commit/dfea3429bad57abde040397e4e7a58539829e9c2)) + +## [@libp2p/interface-compliance-tests-v1.1.19](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.18...@libp2p/interface-compliance-tests-v1.1.19) (2022-03-22) + + +### Bug Fixes + +* add method for startable lifecyle ([#186](https://github.com/libp2p/js-libp2p-interfaces/issues/186)) ([2730e29](https://github.com/libp2p/js-libp2p-interfaces/commit/2730e2947bbd231db3f7f82951b51ee534733ab2)) + +## [@libp2p/interface-compliance-tests-v1.1.18](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.17...@libp2p/interface-compliance-tests-v1.1.18) (2022-03-20) + + +### Bug Fixes + +* update pubsub types ([#183](https://github.com/libp2p/js-libp2p-interfaces/issues/183)) ([7ef4baa](https://github.com/libp2p/js-libp2p-interfaces/commit/7ef4baad0fe30f783f3eecd5199ef92af08b7f57)) + +## [@libp2p/interface-compliance-tests-v1.1.17](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.16...@libp2p/interface-compliance-tests-v1.1.17) (2022-03-15) + + +### Bug Fixes + +* use custom event instead of error event ([#181](https://github.com/libp2p/js-libp2p-interfaces/issues/181)) ([71ab242](https://github.com/libp2p/js-libp2p-interfaces/commit/71ab2424dfbf6337111d6d9d994f27c7967c20f1)) + +## [@libp2p/interface-compliance-tests-v1.1.16](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.15...@libp2p/interface-compliance-tests-v1.1.16) (2022-03-15) + + +### Bug Fixes + +* simplify transport interface, update interfaces for use with libp2p ([#180](https://github.com/libp2p/js-libp2p-interfaces/issues/180)) ([ec81622](https://github.com/libp2p/js-libp2p-interfaces/commit/ec81622e5b7c6d256e0f8aed6d3695642473293b)) + +## [@libp2p/interface-compliance-tests-v1.1.15](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.14...@libp2p/interface-compliance-tests-v1.1.15) (2022-02-27) + + +### Bug Fixes + +* rename crypto to connection-encrypter ([#179](https://github.com/libp2p/js-libp2p-interfaces/issues/179)) ([d197f55](https://github.com/libp2p/js-libp2p-interfaces/commit/d197f554d7cdadb3b05ed2d6c69fda2c4362b1eb)) + +## [@libp2p/interface-compliance-tests-v1.1.14](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.13...@libp2p/interface-compliance-tests-v1.1.14) (2022-02-27) + + +### Bug Fixes + +* update package config and add connection gater interface ([#178](https://github.com/libp2p/js-libp2p-interfaces/issues/178)) ([c6079a6](https://github.com/libp2p/js-libp2p-interfaces/commit/c6079a6367f004788062df3e30ad2e26330d947b)) + +## [@libp2p/interface-compliance-tests-v1.1.13](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.12...@libp2p/interface-compliance-tests-v1.1.13) (2022-02-21) + + +### Bug Fixes + +* increase stream test timeout ([#175](https://github.com/libp2p/js-libp2p-interfaces/issues/175)) ([568aefb](https://github.com/libp2p/js-libp2p-interfaces/commit/568aefb5c099ba0161ffecf86bda238b92d396b0)) + +## [@libp2p/interface-compliance-tests-v1.1.12](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.11...@libp2p/interface-compliance-tests-v1.1.12) (2022-02-21) + + +### Bug Fixes + +* update muxer to pass transport tests ([#174](https://github.com/libp2p/js-libp2p-interfaces/issues/174)) ([466ed53](https://github.com/libp2p/js-libp2p-interfaces/commit/466ed53192aa196ac2dbdb83df3c8db9cd5b1e07)) + +## [@libp2p/interface-compliance-tests-v1.1.11](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.10...@libp2p/interface-compliance-tests-v1.1.11) (2022-02-18) + + +### Bug Fixes + +* remove delays from pubsub tests ([#173](https://github.com/libp2p/js-libp2p-interfaces/issues/173)) ([5c8fe09](https://github.com/libp2p/js-libp2p-interfaces/commit/5c8fe09294f0cbd8add1406a61fa7dbc5b4e788b)) + +## [@libp2p/interface-compliance-tests-v1.1.10](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.9...@libp2p/interface-compliance-tests-v1.1.10) (2022-02-18) + + +### Bug Fixes + +* simpler pubsub ([#172](https://github.com/libp2p/js-libp2p-interfaces/issues/172)) ([98715ed](https://github.com/libp2p/js-libp2p-interfaces/commit/98715ed73183b32e4fda3d878a462389548358d9)) + +## [@libp2p/interface-compliance-tests-v1.1.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.8...@libp2p/interface-compliance-tests-v1.1.9) (2022-02-17) + + +### Bug Fixes + +* update deps ([#171](https://github.com/libp2p/js-libp2p-interfaces/issues/171)) ([d0d2564](https://github.com/libp2p/js-libp2p-interfaces/commit/d0d2564a84a0722ab587a3aa6ec01e222442b100)) + +## [@libp2p/interface-compliance-tests-v1.1.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.7...@libp2p/interface-compliance-tests-v1.1.8) (2022-02-17) + + +### Bug Fixes + +* add multistream-select and update pubsub types ([#170](https://github.com/libp2p/js-libp2p-interfaces/issues/170)) ([b9ecb2b](https://github.com/libp2p/js-libp2p-interfaces/commit/b9ecb2bee8f2abc0c41bfcf7bf2025894e37ddc2)) + +## [@libp2p/interface-compliance-tests-v1.1.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.6...@libp2p/interface-compliance-tests-v1.1.7) (2022-02-16) + + +### Bug Fixes + +* test muxer ([#169](https://github.com/libp2p/js-libp2p-interfaces/issues/169)) ([574723d](https://github.com/libp2p/js-libp2p-interfaces/commit/574723d11007e875e7adfa5c32819445f9b8def7)) + +## [@libp2p/interface-compliance-tests-v1.1.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.5...@libp2p/interface-compliance-tests-v1.1.6) (2022-02-12) + + +### Bug Fixes + +* return registered topologies in mock ([#168](https://github.com/libp2p/js-libp2p-interfaces/issues/168)) ([1583019](https://github.com/libp2p/js-libp2p-interfaces/commit/158301982384a694ac3fb8f9df67c71b7b776b47)) + +## [@libp2p/interface-compliance-tests-v1.1.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.4...@libp2p/interface-compliance-tests-v1.1.5) (2022-02-12) + + +### Bug Fixes + +* hide implementations behind factory methods ([#167](https://github.com/libp2p/js-libp2p-interfaces/issues/167)) ([2fba080](https://github.com/libp2p/js-libp2p-interfaces/commit/2fba0800c9896af6dcc49da4fa904bb4a3e3e40d)) + +## [@libp2p/interface-compliance-tests-v1.1.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.3...@libp2p/interface-compliance-tests-v1.1.4) (2022-02-11) + + +### Bug Fixes + +* simpler topologies ([#164](https://github.com/libp2p/js-libp2p-interfaces/issues/164)) ([45fcaa1](https://github.com/libp2p/js-libp2p-interfaces/commit/45fcaa10a6a3215089340ff2eff117d7fd1100e7)) + +## [@libp2p/interface-compliance-tests-v1.1.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.2...@libp2p/interface-compliance-tests-v1.1.3) (2022-02-10) + + +### Bug Fixes + +* make registrar simpler ([#163](https://github.com/libp2p/js-libp2p-interfaces/issues/163)) ([d122f3d](https://github.com/libp2p/js-libp2p-interfaces/commit/d122f3daaccc04039d90814960da92b513265644)) + +## [@libp2p/interface-compliance-tests-v1.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.1...@libp2p/interface-compliance-tests-v1.1.2) (2022-02-10) + + +### Bug Fixes + +* remove args from listener events ([#162](https://github.com/libp2p/js-libp2p-interfaces/issues/162)) ([011ac89](https://github.com/libp2p/js-libp2p-interfaces/commit/011ac891ec7d44625cb4342f068bcd9f241a5b45)) + +## [@libp2p/interface-compliance-tests-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.0...@libp2p/interface-compliance-tests-v1.1.1) (2022-02-10) + + +### Bug Fixes + +* remove node event emitters ([#161](https://github.com/libp2p/js-libp2p-interfaces/issues/161)) ([221fb6a](https://github.com/libp2p/js-libp2p-interfaces/commit/221fb6a024430dc56288d73d8b8ce1aa88427701)) + +## [@libp2p/interface-compliance-tests-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.8...@libp2p/interface-compliance-tests-v1.1.0) (2022-02-09) + + +### Features + +* add peer store/records, and streams are just streams ([#160](https://github.com/libp2p/js-libp2p-interfaces/issues/160)) ([8860a0c](https://github.com/libp2p/js-libp2p-interfaces/commit/8860a0cd46b359a5648402d83870f7ff957222fe)) + +## [@libp2p/interface-compliance-tests-v1.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.7...@libp2p/interface-compliance-tests-v1.0.8) (2022-02-05) + + +### Bug Fixes + +* fix muxer tests ([#157](https://github.com/libp2p/js-libp2p-interfaces/issues/157)) ([7233c44](https://github.com/libp2p/js-libp2p-interfaces/commit/7233c4438479dff56a682f45209ef7a938d63857)) + +## [@libp2p/interface-compliance-tests-v1.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.6...@libp2p/interface-compliance-tests-v1.0.7) (2022-01-31) + + +### Trivial Changes + +* **deps:** bump sinon from 12.0.1 to 13.0.0 ([#154](https://github.com/libp2p/js-libp2p-interfaces/issues/154)) ([3fc8812](https://github.com/libp2p/js-libp2p-interfaces/commit/3fc8812897fa197e7b62f77614abaea4a5563404)) + +## [@libp2p/interface-compliance-tests-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.5...@libp2p/interface-compliance-tests-v1.0.6) (2022-01-29) + + +### Bug Fixes + +* remove extra fields ([#153](https://github.com/libp2p/js-libp2p-interfaces/issues/153)) ([ccd7cf3](https://github.com/libp2p/js-libp2p-interfaces/commit/ccd7cf3f5ac71337baf516d3b0f6fc724ee0d3b4)) + +## [@libp2p/interface-compliance-tests-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.4...@libp2p/interface-compliance-tests-v1.0.5) (2022-01-15) + + +### Bug Fixes + +* remove abort controller dep ([#151](https://github.com/libp2p/js-libp2p-interfaces/issues/151)) ([518bce1](https://github.com/libp2p/js-libp2p-interfaces/commit/518bce1f9bd1f8b2922338e0c65c9934af7da3af)) + +## [@libp2p/interface-compliance-tests-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.3...@libp2p/interface-compliance-tests-v1.0.4) (2022-01-15) + + +### Trivial Changes + +* update project config ([#149](https://github.com/libp2p/js-libp2p-interfaces/issues/149)) ([6eb8556](https://github.com/libp2p/js-libp2p-interfaces/commit/6eb85562c0da167d222808da10a7914daf12970b)) + +## [@libp2p/interface-compliance-tests-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.2...@libp2p/interface-compliance-tests-v1.0.3) (2022-01-14) + + +### Bug Fixes + +* update it-* deps to ts versions ([#148](https://github.com/libp2p/js-libp2p-interfaces/issues/148)) ([7a6fdd7](https://github.com/libp2p/js-libp2p-interfaces/commit/7a6fdd7622ce2870b89dbb849ab421d0dd714b43)) + +## [@libp2p/interface-compliance-tests-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.1...@libp2p/interface-compliance-tests-v1.0.2) (2022-01-08) + + +### Trivial Changes + +* add semantic release config ([#141](https://github.com/libp2p/js-libp2p-interfaces/issues/141)) ([5f0de59](https://github.com/libp2p/js-libp2p-interfaces/commit/5f0de59136b6343d2411abb2d6a4dd2cd0b7efe4)) +* update package versions ([#140](https://github.com/libp2p/js-libp2p-interfaces/issues/140)) ([cd844f6](https://github.com/libp2p/js-libp2p-interfaces/commit/cd844f6e39f4ee50d006e86eac8dadf696900eb5)) + +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.2.0 (2022-01-04) + + +### Features + +* add auto-publish ([7aede5d](https://github.com/libp2p/js-libp2p-interfaces/commit/7aede5df39ea6b5f243348ec9a212b3e33c16a81)) +* update package names ([#133](https://github.com/libp2p/js-libp2p-interfaces/issues/133)) ([337adc9](https://github.com/libp2p/js-libp2p-interfaces/commit/337adc9a9bc0278bdae8cbce9c57d07a83c8b5c2)) + + + + + +## [3.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@3.1.0...libp2p-interfaces-compliance-tests@3.1.1) (2022-01-02) + + +### Bug Fixes + +* move errors ([#132](https://github.com/libp2p/js-libp2p-interfaces/issues/132)) ([21d282a](https://github.com/libp2p/js-libp2p-interfaces/commit/21d282a6d77bd7d1a12daa1cc8b3a3fed8635dad)) + + + + + +# [3.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@3.0.0...libp2p-interfaces-compliance-tests@3.1.0) (2022-01-02) + + +### Bug Fixes + +* update dialer tests ([#116](https://github.com/libp2p/js-libp2p-interfaces/issues/116)) ([c679729](https://github.com/libp2p/js-libp2p-interfaces/commit/c679729113feb963ff27815fcafd7af51f722df7)) + + +### Features + +* simpler peer id ([#117](https://github.com/libp2p/js-libp2p-interfaces/issues/117)) ([fa2c4f5](https://github.com/libp2p/js-libp2p-interfaces/commit/fa2c4f5be74a5cfc11489771881e57b4e53bf174)) + + + + + +# [3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@2.0.0...libp2p-interfaces-compliance-tests@3.0.0) (2021-12-02) + + +### chore + +* update libp2p-crypto and peer-id ([c711e8b](https://github.com/libp2p/js-libp2p-interfaces/commit/c711e8bd4d606f6974b13fad2eeb723f93cebb87)) + + +### BREAKING CHANGES + +* requires node 15+ + + + + + +# [2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.1.2...libp2p-interfaces-compliance-tests@2.0.0) (2021-11-22) + + +### Features + +* split out code, convert to typescript ([#111](https://github.com/libp2p/js-libp2p-interfaces/issues/111)) ([e174bba](https://github.com/libp2p/js-libp2p-interfaces/commit/e174bba889388269b806643c79a6b53c8d6a0f8c)), closes [#110](https://github.com/libp2p/js-libp2p-interfaces/issues/110) [#101](https://github.com/libp2p/js-libp2p-interfaces/issues/101) + + +### BREAKING CHANGES + +* not all fields from concrete classes have been added to the interfaces, some adjustment may be necessary as this gets rolled out + + + + + +## [1.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.1.1...libp2p-interfaces-compliance-tests@1.1.2) (2021-10-18) + +**Note:** Version bump only for package libp2p-interfaces-compliance-tests + + + + + +## [1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.1.0...libp2p-interfaces-compliance-tests@1.1.1) (2021-09-20) + +**Note:** Version bump only for package libp2p-interfaces-compliance-tests + + + + + +# [1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.0.1...libp2p-interfaces-compliance-tests@1.1.0) (2021-08-20) + + +### Features + +* update uint8arrays ([#105](https://github.com/libp2p/js-libp2p-interfaces/issues/105)) ([9297a9c](https://github.com/libp2p/js-libp2p-interfaces/commit/9297a9c379276d03c8da849af6108b38e581b4a6)) + + + + + +## [1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.0.0...libp2p-interfaces-compliance-tests@1.0.1) (2021-07-08) + + +### Bug Fixes + +* make tests more reliable ([#103](https://github.com/libp2p/js-libp2p-interfaces/issues/103)) ([cd4c409](https://github.com/libp2p/js-libp2p-interfaces/commit/cd4c40908efe2e9ffc14aa61aace5176a43fd70a)) +* remove timeouts ([#104](https://github.com/libp2p/js-libp2p-interfaces/issues/104)) ([3699c17](https://github.com/libp2p/js-libp2p-interfaces/commit/3699c17f022da40a87ab24adc3b2081df7a0ddcd)) + + + + + +# 1.0.0 (2021-07-07) + + +### chore + +* monorepo separating interfaces and compliance tests ([#97](https://github.com/libp2p/js-libp2p-interfaces/issues/97)) ([946348f](https://github.com/libp2p/js-libp2p-interfaces/commit/946348f7f8acc1ff7bc9cd0ab4c2602d41106f76)) + + +### BREAKING CHANGES + +* the tests now live in the libp2p-interfaces-compliance-tests module diff --git a/packages/interface-compliance-tests/LICENSE b/packages/interface-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-compliance-tests/LICENSE-APACHE b/packages/interface-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-compliance-tests/LICENSE-MIT b/packages/interface-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-compliance-tests/README.md b/packages/interface-compliance-tests/README.md new file mode 100644 index 0000000000..295cf0c742 --- /dev/null +++ b/packages/interface-compliance-tests/README.md @@ -0,0 +1,41 @@ +# @libp2p/interface-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for JS libp2p interfaces + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-compliance-tests +``` + +## Usage + +Each [interface](https://npmjs.org/packages/@libp2p/interfaces) has its documentation on how to use the compliance tests and should be used as the source of truth. + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-compliance-tests/package.json b/packages/interface-compliance-tests/package.json new file mode 100644 index 0000000000..b14541466f --- /dev/null +++ b/packages/interface-compliance-tests/package.json @@ -0,0 +1,160 @@ +{ + "name": "@libp2p/interface-compliance-tests", + "version": "3.0.7", + "description": "Compliance tests for JS libp2p interfaces", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ], + "src/*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ] + } + }, + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./is-valid-tick": { + "types": "./dist/src/is-valid-tick.d.ts", + "import": "./dist/src/is-valid-tick.js" + }, + "./peers": { + "types": "./dist/src/peers.d.ts", + "import": "./dist/src/peers.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-compliance-tests/src/index.ts b/packages/interface-compliance-tests/src/index.ts new file mode 100644 index 0000000000..7aea8b17d5 --- /dev/null +++ b/packages/interface-compliance-tests/src/index.ts @@ -0,0 +1,5 @@ + +export interface TestSetup> { + setup: (args?: SetupArgs) => Promise + teardown: () => Promise +} diff --git a/packages/interface-compliance-tests/src/is-valid-tick.ts b/packages/interface-compliance-tests/src/is-valid-tick.ts new file mode 100644 index 0000000000..8e6a1c8bcc --- /dev/null +++ b/packages/interface-compliance-tests/src/is-valid-tick.ts @@ -0,0 +1,18 @@ + +/** + * A tick is considered valid if it happened between now + * and `ms` milliseconds ago + */ +export function isValidTick (date?: number, ms: number = 5000): boolean { + if (date == null) { + throw new Error('date must be a number') + } + + const now = Date.now() + + if (date > now - ms && date <= now) { + return true + } + + return false +} diff --git a/packages/interface-compliance-tests/src/peers.ts b/packages/interface-compliance-tests/src/peers.ts new file mode 100644 index 0000000000..42bacedeac --- /dev/null +++ b/packages/interface-compliance-tests/src/peers.ts @@ -0,0 +1,25 @@ +export default [{ + id: 'QmNMMAqSxPetRS1cVMmutW5BCN1qQQyEr4u98kUvZjcfEw', + privKey: 'CAASpQkwggShAgEAAoIBAQDPek2aeHMa0blL42RTKd6xgtkk4Zkldvq4LHxzcag5uXepiQzWANEUvoD3KcUTmMRmx14PvsxdLCNst7S2JSa0R2n5wSRs14zGy6892lx4H4tLBD1KSpQlJ6vabYM1CJhIQRG90BtzDPrJ/X1iJ2HA0PPDz0Mflam2QUMDDrU0IuV2m7gSCJ5r4EmMs3U0xnH/1gShkVx4ir0WUdoWf5KQUJOmLn1clTRHYPv4KL9A/E38+imNAXfkH3c2T7DrCcYRkZSpK+WecjMsH1dCX15hhhggNqfp3iulO1tGPxHjm7PDGTPUjpCWKpD5e50sLqsUwexac1ja6ktMfszIR+FPAgMBAAECggEAB2H2uPRoRCAKU+T3gO4QeoiJaYKNjIO7UCplE0aMEeHDnEjAKC1HQ1G0DRdzZ8sb0fxuIGlNpFMZv5iZ2ZFg2zFfV//DaAwTek9tIOpQOAYHUtgHxkj5FIlg2BjlflGb+ZY3J2XsVB+2HNHkUEXOeKn2wpTxcoJE07NmywkO8Zfr1OL5oPxOPlRN1gI4ffYH2LbfaQVtRhwONR2+fs5ISfubk5iKso6BX4moMYkxubYwZbpucvKKi/rIjUA3SK86wdCUnno1KbDfdXSgCiUlvxt/IbRFXFURQoTV6BOi3sP5crBLw8OiVubMr9/8WE6KzJ0R7hPd5+eeWvYiYnWj4QKBgQD6jRlAFo/MgPO5NZ/HRAk6LUG+fdEWexA+GGV7CwJI61W/Dpbn9ZswPDhRJKo3rquyDFVZPdd7+RlXYg1wpmp1k54z++L1srsgj72vlg4I8wkZ4YLBg0+zVgHlQ0kxnp16DvQdOgiRFvMUUMEgetsoIx1CQWTd67hTExGsW+WAZQKBgQDT/WaHWvwyq9oaZ8G7F/tfeuXvNTk3HIJdfbWGgRXB7lJ7Gf6FsX4x7PeERfL5a67JLV6JdiLLVuYC2CBhipqLqC2DB962aKMvxobQpSljBBZvZyqP1IGPoKskrSo+2mqpYkeCLbDMuJ1nujgMP7gqVjabs2zj6ACKmmpYH/oNowJ/T0ZVtvFsjkg+1VsiMupUARRQuPUWMwa9HOibM1NIZcoQV2NGXB5Z++kR6JqxQO0DZlKArrviclderUdY+UuuY4VRiSEprpPeoW7ZlbTku/Ap8QZpWNEzZorQDro7bnfBW91fX9/81ets/gCPGrfEn+58U3pdb9oleCOQc/ifpQKBgBTYGbi9bYbd9vgZs6bd2M2um+VFanbMytS+g5bSIn2LHXkVOT2UEkB+eGf9KML1n54QY/dIMmukA8HL1oNAyalpw+/aWj+9Ui5kauUhGEywHjSeBEVYM9UXizxz+m9rsoktLLLUI0o97NxCJzitG0Kub3gn0FEogsUeIc7AdinZAoGBANnM1vcteSQDs7x94TDEnvvqwSkA2UWyLidD2jXgE0PG4V6tTkK//QPBmC9eq6TIqXkzYlsErSw4XeKO91knFofmdBzzVh/ddgx/NufJV4tXF+a2iTpqYBUJiz9wpIKgf43/Ob+P1EA99GAhSdxz1ess9O2aTqf3ANzn6v6g62Pv', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPek2aeHMa0blL42RTKd6xgtkk4Zkldvq4LHxzcag5uXepiQzWANEUvoD3KcUTmMRmx14PvsxdLCNst7S2JSa0R2n5wSRs14zGy6892lx4H4tLBD1KSpQlJ6vabYM1CJhIQRG90BtzDPrJ/X1iJ2HA0PPDz0Mflam2QUMDDrU0IuV2m7gSCJ5r4EmMs3U0xnH/1gShkVx4ir0WUdoWf5KQUJOmLn1clTRHYPv4KL9A/E38+imNAXfkH3c2T7DrCcYRkZSpK+WecjMsH1dCX15hhhggNqfp3iulO1tGPxHjm7PDGTPUjpCWKpD5e50sLqsUwexac1ja6ktMfszIR+FPAgMBAAE=' +}, { + id: 'QmW8rAgaaA6sRydK1k6vonShQME47aDxaFidbtMevWs73t', + privKey: 'CAASpwkwggSjAgEAAoIBAQCTU3gVDv3SRXLOsFln9GEf1nJ/uCEDhOG10eC0H9l9IPpVxjuPT1ep+ykFUdvefq3D3q+W3hbmiHm81o8dYv26RxZIEioToUWp7Ec5M2B/niYoE93za9/ZDwJdl7eh2hNKwAdxTmdbXUPjkIU4vLyHKRFbJIn9X8w9djldz8hoUvC1BK4L1XrT6F2l0ruJXErH2ZwI1youfSzo87TdXIoFKdrQLuW6hOtDCGKTiS+ab/DkMODc6zl8N47Oczv7vjzoWOJMUJs1Pg0ZsD1zmISY38P0y/QyEhatZn0B8BmSWxlLQuukatzOepQI6k+HtfyAAjn4UEqnMaXTP1uwLldVAgMBAAECggEAHq2f8MqpYjLiAFZKl9IUs3uFZkEiZsgx9BmbMAb91Aec+WWJG4OLHrNVTG1KWp+IcaQablEa9bBvoToQnS7y5OpOon1d066egg7Ymfmv24NEMM5KRpktCNcOSA0CySpPIB6yrg6EiUr3ixiaFUGABKkxmwgVz/Q15IqM0ZMmCUsC174PMAz1COFZxD0ZX0zgHblOJQW3dc0X3XSzhht8vU02SMoVObQHQfeXEHv3K/RiVj/Ax0bTc5JVkT8dm8xksTtsFCNOzRBqFS6MYqX6U/u0Onz3Jm5Jt7fLWb5n97gZR4SleyGrqxYNb46d9X7mP0ie7E6bzFW0DsWBIeAqVQKBgQDW0We2L1n44yOvJaMs3evpj0nps13jWidt2I3RlZXjWzWHiYQfvhWUWqps/xZBnAYgnN/38xbKzHZeRNhrqOo+VB0WK1IYl0lZVE4l6TNKCsLsUfQzsb1pePkd1eRZA+TSqsi+I/IOQlQU7HA0bMrah/5FYyUBP0jYvCOvYTlZuwKBgQCvkcVRydVlzjUgv7lY5lYvT8IHV5iYO4Qkk2q6Wjv9VUKAJZauurMdiy05PboWfs5kbETdwFybXMBcknIvZO4ihxmwL8mcoNwDVZHI4bXapIKMTCyHgUKvJ9SeTcKGC7ZuQJ8mslRmYox/HloTOXEJgQgPRxXcwa3amzvdZI+6LwKBgQCLsnQqgxKUi0m6bdR2qf7vzTH4258z6X34rjpT0F5AEyF1edVFOz0XU/q+lQhpNEi7zqjLuvbYfSyA026WXKuwSsz7jMJ/oWqev/duKgAjp2npesY/E9gkjfobD+zGgoS9BzkyhXe1FCdP0A6L2S/1+zg88WOwMvJxl6/xLl24XwKBgCm60xSajX8yIQyUpWBM9yUtpueJ2Xotgz4ST+bVNbcEAddll8gWFiaqgug9FLLuFu5lkYTHiPtgc1RNdphvO+62/9MRuLDixwh/2TPO+iNqwKDKJjda8Nei9vVddCPaOtU/xNQ0xLzFJbG9LBmvqH9izOCcu8SJwGHaTcNUeJj/AoGADCJ26cY30c13F/8awAAmFYpZWCuTP5ppTsRmjd63ixlrqgkeLGpJ7kYb5fXkcTycRGYgP0e1kssBGcmE7DuG955fx3ZJESX3GQZ+XfMHvYGONwF1EiK1f0p6+GReC2VlQ7PIkoD9o0hojM6SnWvv9EXNjCPALEbfPFFvcniKVsE=', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCTU3gVDv3SRXLOsFln9GEf1nJ/uCEDhOG10eC0H9l9IPpVxjuPT1ep+ykFUdvefq3D3q+W3hbmiHm81o8dYv26RxZIEioToUWp7Ec5M2B/niYoE93za9/ZDwJdl7eh2hNKwAdxTmdbXUPjkIU4vLyHKRFbJIn9X8w9djldz8hoUvC1BK4L1XrT6F2l0ruJXErH2ZwI1youfSzo87TdXIoFKdrQLuW6hOtDCGKTiS+ab/DkMODc6zl8N47Oczv7vjzoWOJMUJs1Pg0ZsD1zmISY38P0y/QyEhatZn0B8BmSWxlLQuukatzOepQI6k+HtfyAAjn4UEqnMaXTP1uwLldVAgMBAAE=' +}, { + id: 'QmZqCdSzgpsmB3Qweb9s4fojAoqELWzqku21UVrqtVSKi4', + privKey: 'CAASpgkwggSiAgEAAoIBAQCdbSEsTmw7lp5HagRcx57DaLiSUEkh4iBcKc7Y+jHICEIA8NIVi9FlfGEZj9G21FpiTR4Cy+BLVEuf8Nm90bym4iV+cSumeS21fvD8xGTEbeKGljs6OYHy3M45JhWF85gqHQJOqZufI2NRDuRgMZEO2+qGEXmSlv9mMXba/+9ecze8nSpB7bG2Z2pnKDeYwhF9Cz+ElMyn7TBWDjJERGVgFbTpdM3rBnbhB/TGpvs732QqZmIBlxnDb/Jn0l1gNZCgkEDcJ/0NDMBJTQ8vbvcdmaw3eaMPLkn1ix4wdu9QWCA0IBtuY1R7vSUtf4irnLJG7DnAw2GfM5QrF3xF1GLXAgMBAAECggEAQ1N0qHoxl5pmvqv8iaFlqLSUmx5y6GbI6CGJMQpvV9kQQU68yjItr3VuIXx8d/CBZyEMAK4oko7OeOyMcr3MLKLy3gyQWnXgsopDjhZ/8fH8uwps8g2+IZuFJrO+6LaxEPGvFu06fOiphPUVfn40R2KN/iBjGeox+AaXijmCqaV2vEdNJJPpMfz6VKZBDLTrbiqvo/3GN1U99PUqfPWpOWR29oAhh/Au6blSqvqTUPXB2+D/X6e1JXv31mxMPK68atDHSUjZWKB9lE4FMK1bkSKJRbyXmNIlbZ9V8X4/0r8/6T7JnW7ZT8ugRkquohmwgG7KkDXB1YsOCKXYUqzVYQKBgQDtnopFXWYl7XUyePJ/2MA5i7eoko9jmF44L31irqmHc5unNf6JlNBjlxTNx3WyfzhUzrn3c18psnGkqtow0tkBj5hmqn8/WaPbc5UA/5R1FNaNf8W5khn7MDm6KtYRPjN9djqTDiVHyC6ljONYd+5S+MqyKVWZ3t/xvG60sw85qwKBgQCpmpDtL+2JBwkfeUr3LyDcQxvbfzcv8lXj2otopWxWiLiZF1HzcqgAa2CIwu9kCGEt9Zr+9E4uINbe1To0b01/FhvR6xKO/ukceGA/mBB3vsKDcRmvpBUp+3SmnhY0nOk+ArQl4DhJ34k8pDM3EDPrixPf8SfVdU/8IM32lsdHhQKBgHLgpvCKCwxjFLnmBzcPzz8C8TOqR3BbBZIcQ34l+wflOGdKj1hsfaLoM8KYn6pAHzfBCd88A9Hg11hI0VuxVACRL5jS7NnvuGwsIOluppNEE8Ys86aXn7/0vLPoab3EWJhbRE48FIHzobmft3nZ4XpzlWs02JGfUp1IAC2UM9QpAoGAeWy3pZhSr2/iEC5+hUmwdQF2yEbj8+fDpkWo2VrVnX506uXPPkQwE1zM2Bz31t5I9OaJ+U5fSpcoPpDaAwBMs1fYwwlRWB8YNdHY1q6/23svN3uZsC4BGPV2JnO34iMUudilsRg+NGVdk5TbNejbwx7nM8Urh59djFzQGGMKeSECgYA0QMCARPpdMY50Mf2xQaCP7HfMJhESSPaBq9V3xY6ToEOEnXgAR5pNjnU85wnspHp+82r5XrKfEQlFxGpj2YA4DRRmn239sjDa29qP42UNAFg1+C3OvXTht1d5oOabaGhU0udwKmkEKUbb0bG5xPQJ5qeSJ5T1gLzLk3SIP0GlSw==', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdbSEsTmw7lp5HagRcx57DaLiSUEkh4iBcKc7Y+jHICEIA8NIVi9FlfGEZj9G21FpiTR4Cy+BLVEuf8Nm90bym4iV+cSumeS21fvD8xGTEbeKGljs6OYHy3M45JhWF85gqHQJOqZufI2NRDuRgMZEO2+qGEXmSlv9mMXba/+9ecze8nSpB7bG2Z2pnKDeYwhF9Cz+ElMyn7TBWDjJERGVgFbTpdM3rBnbhB/TGpvs732QqZmIBlxnDb/Jn0l1gNZCgkEDcJ/0NDMBJTQ8vbvcdmaw3eaMPLkn1ix4wdu9QWCA0IBtuY1R7vSUtf4irnLJG7DnAw2GfM5QrF3xF1GLXAgMBAAE=' +}, { + id: 'QmR5VwgsL7jyfZHAGyp66tguVrQhCRQuRc3NokocsCZ3fA', + privKey: 'CAASpwkwggSjAgEAAoIBAQCGXYU+uc2nn1zuJhfdFOl34upztnrD1gpHu58ousgHdGlGgYgbqLBAvIAauXdEL0+e30HofjA634SQxE+9nV+0FQBam1DDzHQlXsuwHV+2SKvSDkk4bVllMFpu2SJtts6VH+OXC/2ANJOm+eTALykQPYXgLIBxrhp/eD+Jz5r6wW2nq3k6OmYyK/4pgGzFjo5UyX+fa/171AJ68UPboFpDy6BZCcUjS0ondxPvD7cv5jMNqqMKIB/7rpi8n+Q3oeccRqVL56wH+FE3/QLjwYHwY6ILNRyvNXRqHjwBEXB2R5moXN0AFUWTw9rt3KhFiEjR1U81BTw5/xS7W2Iu0FgZAgMBAAECggEAS64HK8JZfE09eYGJNWPe8ECmD1C7quw21BpwVe+GVPSTizvQHswPohbKDMNj0srXDMPxCnNw1OgqcaOwyjsGuZaOoXoTroTM8nOHRIX27+PUqzaStS6aCG2IsiCozKUHjGTuupftS7XRaF4eIsUtWtFcQ1ytZ9pJYHypRQTi5NMSrTze5ThjnWxtHilK7gnBXik+aR0mYEVfSn13czQEC4rMOs+b9RAc/iibDNoLopfIdvmCCvfxzmySnR7Cu1iSUAONkir7PB+2Mt/qRFCH6P+jMamtCgQ8AmifXgVmDUlun+4MnKg3KrPd6ZjOEKhVe9mCHtGozk65RDREShfDdQKBgQDi+x2MuRa9peEMOHnOyXTS+v+MFcfmG0InsO08rFNBKZChLB+c9UHBdIvexpfBHigSyERfuDye4z6lxi8ZnierWMYJP30nxmrnxwTGTk1MQquhfs1A0kpmDnPsjlOS/drEIEIssNx2WbfJ7YtMxLWBtp+BJzGpQmr0LKC+NHRSrwKBgQCXiy2kJESIUkIs2ihV55hhT6/bZo1B1O5DPA2nkjOBXqXF6fvijzMDX82JjLd07lQZlI0n1Q/Hw0p4iYi9YVd2bLkLXF5UIb2qOeHj76enVFOrPHUSkC9Y2g/0Xs+60Ths2xRd8RrrfQU3kl5iVpBywkCIrb2M5+wRnNTk1W3TtwKBgQCvplyrteAfSurpJhs9JzE8w/hWU9SqAZYkWQp91W1oE95Um2yrbjBAoQxMjaqKS+f/APPIjy56Vqj4aHGyhW11b/Fw3qzfxvCcBKtxOs8eoMlo5FO6QgJJEA4tlcafDcvp0nzjUMqK28safLU7503+33B35fjMXxWdd5u9FaKfCQKBgC4W6j6tuRosymuRvgrCcRnHfpify/5loEFallyMnpWOD6Tt0OnK25z/GifnYDRz96gAAh5HMpFy18dpLOlMHamqz2yhHx8/U8vd5tHIJZlCkF/X91M5/uxrBccwvsT2tM6Got8fYSyVzWxlW8dUxIHiinYHQUsFjkqdBDLEpq5pAoGASoTw5RBEWFM0GuAZdXsyNyxU+4S+grkTS7WdW/Ymkukh+bJZbnvF9a6MkSehqXnknthmufonds2AFNS//63gixENsoOhzT5+2cdfc6tJECvJ9xXVXkf85AoQ6T/RrXF0W4m9yQyCngNJUrKUOIH3oDIfdZITlYzOC3u1ojj7VuQ=', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCGXYU+uc2nn1zuJhfdFOl34upztnrD1gpHu58ousgHdGlGgYgbqLBAvIAauXdEL0+e30HofjA634SQxE+9nV+0FQBam1DDzHQlXsuwHV+2SKvSDkk4bVllMFpu2SJtts6VH+OXC/2ANJOm+eTALykQPYXgLIBxrhp/eD+Jz5r6wW2nq3k6OmYyK/4pgGzFjo5UyX+fa/171AJ68UPboFpDy6BZCcUjS0ondxPvD7cv5jMNqqMKIB/7rpi8n+Q3oeccRqVL56wH+FE3/QLjwYHwY6ILNRyvNXRqHjwBEXB2R5moXN0AFUWTw9rt3KhFiEjR1U81BTw5/xS7W2Iu0FgZAgMBAAE=' +}, { + id: 'QmScLDqRg7H6ipCYxm9fVk152UWavQFKscTdoT4YNHxgqp', + privKey: 'CAASpwkwggSjAgEAAoIBAQCWEHaTZ6LBLFP5OPrUqjDM/cF4b2zrfh1Zm3kd02ZtgQB3iYtZqRPJT5ctT3A7WdVF/7dCxPGOCkJlLekTx4Y4gD8JtjA+EfN9fR/2RBKbti2N3CD4vkGp9ss4hbBFcXIhl8zuD/ELHutbV6b8b4QXJGnxfp/B+1kNPnyd7SJznS0QyvI8OLI1nAkVKdYLDRW8kPKeHyx1xhdNDuTQVTFyAjRGQ4e3UYFB7bYIHW3E6kCtCoJDlj+JPC02Yt1LHzIzZVLvPvNFnYY2mag6OiGFuh/oMBIqvnPc1zRZ3eLUqeGZjQVaoR0kdgZUKz7Q2TBeNldxK/s6XO0DnkQTlelNAgMBAAECggEAdmt1dyswR2p4tdIeNpY7Pnj9JNIhTNDPznefI0dArCdBvBMhkVaYk6MoNIxcj6l7YOrDroAF8sXr0TZimMY6B/pERKCt/z1hPWTxRQBBAvnHhwvwRPq2jK6BfhAZoyM8IoBNKowP9mum5QUNdGV4Al8s73KyFX0IsCfgZSvNpRdlt+DzPh+hu/CyoZaMpRchJc1UmK8Fyk3KfO+m0DZNfHP5P08lXNfM6MZLgTJVVgERHyG+vBOzTd2RElMe19nVCzHwb3dPPRZSQ7Fnz3rA+GeLqsM2Zi4HNhfbD1OcD9C4wDj5tYL6hWTkdz4IlfVcjCeUHxgIOhdDV2K+OwbuAQKBgQD0FjUZ09UW2FQ/fitbvIB5f1SkXWPxTF9l6mAeuXhoGv2EtQUO4vq/PK6N08RjrZdWQy6UsqHgffi7lVQ8o3hvCKdbtf4sP+cM92OrY0WZV89os79ndj4tyvmnP8WojwRjt/2XEfgdoWcgWxW9DiYINTOQVimZX+X/3on4s8hEgQKBgQCdY3kOMbyQeLTRkqHXjVTY4ddO+v4S4wOUa1l4rTqAbq1W3JYWwoDQgFuIu3limIHmjnSJpCD4EioXFsM7p6csenoc20sHxsaHnJ6Mn5Te41UYmY9EW0otkQ0C3KbXM0hwQkjyplnEmZawGKmjEHW8DJ3vRYTv9TUCgYKxDHgOzQKBgB4A/NYH7BG61eBYKgxEx6YnuMfbkwV+Vdu5S8d7FQn3B2LgvZZu4FPRqcNVXLbEB+5ao8czjiKCWaj1Wj15+rvrXGcxn+Tglg5J+r5+nXeUC7LbJZQaPNp0MOwWMr3dlrSLUWjYlJ9Pz9VyXOG4c4Rexc/gR4zK9QLW4C7qKpwBAoGAZzyUb0cYlPtYQA+asTU3bnvVKy1f8yuNcZFowst+EDiI4u0WVh+HNzy6zdmLKa03p+/RaWeLaK0hhrubnEnAUmCUMNF3ScaM+u804LDcicc8TkKLwx7ObU0z56isl4RAA8K27tNHFrpYKXJD834cfBkaj5ReOrfw6Y/iFhhDuBECgYEA8gbC76uz7LSHhW30DSRTcqOzTyoe2oYKQaxuxYNp7vSSOkcdRen+mrdflDvud2q/zN2QdL4pgqdldHlR35M/lJ0f0B6zp74jlzbO9700wzsOqreezGc5eWiroDL100U9uIZ50BKb8CKtixIHpinUSPIUcVDkSAZ2y7mbfCxQwqQ=', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWEHaTZ6LBLFP5OPrUqjDM/cF4b2zrfh1Zm3kd02ZtgQB3iYtZqRPJT5ctT3A7WdVF/7dCxPGOCkJlLekTx4Y4gD8JtjA+EfN9fR/2RBKbti2N3CD4vkGp9ss4hbBFcXIhl8zuD/ELHutbV6b8b4QXJGnxfp/B+1kNPnyd7SJznS0QyvI8OLI1nAkVKdYLDRW8kPKeHyx1xhdNDuTQVTFyAjRGQ4e3UYFB7bYIHW3E6kCtCoJDlj+JPC02Yt1LHzIzZVLvPvNFnYY2mag6OiGFuh/oMBIqvnPc1zRZ3eLUqeGZjQVaoR0kdgZUKz7Q2TBeNldxK/s6XO0DnkQTlelNAgMBAAE=' +}, { + id: 'QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN', + privKey: 'CAASpwkwggSjAgEAAoIBAQC1/GFud/7xutux7qRfMj1sIdMRh99/chR6HqVj6LQqrgk4jil0mdN/LCk/tqPqmDtObHdmEhCoybzuhLbCKgUqryKDwO6yBJHSKWY9QqrKZtLJ37SgKwGjE3+NUD4r1dJHhtQrICFdOdSCBzs/v8gi+J+KZLHo7+Nms4z09ysy7qZh94Pd7cW4gmSMergqUeANLD9C0ERw1NXolswOW7Bi7UGr7yuBxejICLO3nkxe0OtpQBrYrqdCD9vs3t/HQZbPWVoiRj4VO7fxkAPKLl30HzcIfxj/ayg8NHcH59d08D+N2v5Sdh28gsiYKIPE9CXvuw//HUY2WVRY5fDC5JglAgMBAAECggEBAKb5aN/1w3pBqz/HqRMbQpYLNuD33M3PexBNPAy+P0iFpDo63bh5Rz+A4lvuFNmzUX70MFz7qENlzi6+n/zolxMB29YtWBUH8k904rTEjXXl//NviQgITZk106tx+4k2x5gPEm57LYGfBOdFAUzNhzDnE2LkXwRNzkS161f7zKwOEsaGWRscj6UvhO4MIFxjb32CVwt5eK4yOVqtyMs9u30K4Og+AZYTlhtm+bHg6ndCCBO6CQurCQ3jD6YOkT+L3MotKqt1kORpvzIB0ujZRf49Um8wlcjC5G9aexBeGriXaVdPF62zm7GA7RMsbQM/6aRbA1fEQXvJhHUNF9UFeaECgYEA8wCjKqQA7UQnHjRwTsktdwG6szfxd7z+5MTqHHTWhWzgcQLgdh5/dO/zanEoOThadMk5C1Bqjq96gH2xim8dg5XQofSVtV3Ui0dDa+XRB3E3fyY4D3RF5hHv85O0GcvQc6DIb+Ja1oOhvHowFB1C+CT3yEgwzX/EK9xpe+KtYAkCgYEAv7hCnj/DcZFU3fAfS+unBLuVoVJT/drxv66P686s7J8UM6tW+39yDBZ1IcwY9vHFepBvxY2fFfEeLI02QFM+lZXVhNGzFkP90agNHK01psGgrmIufl9zAo8WOKgkLgbYbSHzkkDeqyjEPU+B0QSsZOCE+qLCHSdsnTmo/TjQhj0CgYAz1+j3yfGgrS+jVBC53lXi0+2fGspbf2jqKdDArXSvFqFzuudki/EpY6AND4NDYfB6hguzjD6PnoSGMUrVfAtR7X6LbwEZpqEX7eZGeMt1yQPMDr1bHrVi9mS5FMQR1NfuM1lP9Xzn00GIUpE7WVrWUhzDEBPJY/7YVLf0hFH08QKBgDWBRQZJIVBmkNrHktRrVddaSq4U/d/Q5LrsCrpymYwH8WliHgpeTQPWmKXwAd+ZJdXIzYjCt202N4eTeVqGYOb6Q/anV2WVYBbM4avpIxoA28kPGY6nML+8EyWIt2ApBOmgGgvtEreNzwaVU9NzjHEyv6n7FlVwlT1jxCe3XWq5AoGASYPKQoPeDlW+NmRG7z9EJXJRPVtmLL40fmGgtju9QIjLnjuK8XaczjAWT+ySI93Whu+Eujf2Uj7Q+NfUjvAEzJgwzuOd3jlQvoALq11kuaxlNQTn7rx0A1QhBgUJE8AkvShPC9FEnA4j/CLJU0re9H/8VvyN6qE0Mho0+YbjpP8=', + pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1/GFud/7xutux7qRfMj1sIdMRh99/chR6HqVj6LQqrgk4jil0mdN/LCk/tqPqmDtObHdmEhCoybzuhLbCKgUqryKDwO6yBJHSKWY9QqrKZtLJ37SgKwGjE3+NUD4r1dJHhtQrICFdOdSCBzs/v8gi+J+KZLHo7+Nms4z09ysy7qZh94Pd7cW4gmSMergqUeANLD9C0ERw1NXolswOW7Bi7UGr7yuBxejICLO3nkxe0OtpQBrYrqdCD9vs3t/HQZbPWVoiRj4VO7fxkAPKLl30HzcIfxj/ayg8NHcH59d08D+N2v5Sdh28gsiYKIPE9CXvuw//HUY2WVRY5fDC5JglAgMBAAE=' +}] diff --git a/packages/interface-compliance-tests/tsconfig.json b/packages/interface-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..5fe8ea40d7 --- /dev/null +++ b/packages/interface-compliance-tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ] +} diff --git a/packages/interface-connection-compliance-tests/CHANGELOG.md b/packages/interface-connection-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..8a64b251a8 --- /dev/null +++ b/packages/interface-connection-compliance-tests/CHANGELOG.md @@ -0,0 +1,93 @@ +## [@libp2p/interface-connection-compliance-tests-v2.0.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.8...@libp2p/interface-connection-compliance-tests-v2.0.9) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.7...@libp2p/interface-connection-compliance-tests-v2.0.8) (2023-04-18) + + +### Dependencies + +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.6...@libp2p/interface-connection-compliance-tests-v2.0.7) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.5...@libp2p/interface-connection-compliance-tests-v2.0.6) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.4...@libp2p/interface-connection-compliance-tests-v2.0.5) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.3...@libp2p/interface-connection-compliance-tests-v2.0.4) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + + +### Dependencies + +* bump sinon from 14.0.2 to 15.0.0 ([#316](https://github.com/libp2p/js-libp2p-interfaces/issues/316)) ([d37721c](https://github.com/libp2p/js-libp2p-interfaces/commit/d37721c9143cd3eeafb5f8249b07d9f2fbce0f54)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.2...@libp2p/interface-connection-compliance-tests-v2.0.3) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.1...@libp2p/interface-connection-compliance-tests-v2.0.2) (2022-08-07) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v2.0.0...@libp2p/interface-connection-compliance-tests-v2.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-connection-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-compliance-tests-v1.0.0...@libp2p/interface-connection-compliance-tests-v2.0.0) (2022-06-16) + + +### ⚠ BREAKING CHANGES + +* The Connection and Stream APIs have been updated + +### Features + +* store stream data on the stream, track the stream direction ([#245](https://github.com/libp2p/js-libp2p-interfaces/issues/245)) ([6d74d2f](https://github.com/libp2p/js-libp2p-interfaces/commit/6d74d2f9f344fb4d6741ba0d35263ebe351a4c65)) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) diff --git a/packages/interface-connection-compliance-tests/LICENSE b/packages/interface-connection-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-connection-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-connection-compliance-tests/LICENSE-APACHE b/packages/interface-connection-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-connection-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-connection-compliance-tests/LICENSE-MIT b/packages/interface-connection-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-connection-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-connection-compliance-tests/README.md b/packages/interface-connection-compliance-tests/README.md new file mode 100644 index 0000000000..eed20b2800 --- /dev/null +++ b/packages/interface-connection-compliance-tests/README.md @@ -0,0 +1,61 @@ +# @libp2p/interface-connection-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for implementations of the libp2p Connection interface + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-connection-compliance-tests +``` + +## Usage + +This is a test suite and interface you can use to implement a connection. The connection interface contains all the metadata associated with it, as well as an array of the streams opened through this connection. In the same way as the connection, a stream contains properties with its metadata, plus an iterable duplex object that offers a mechanism for writing and reading data, with back pressure. This module and test suite were heavily inspired by abstract-blob-store and interface-stream-muxer. + +The primary goal of this module is to enable developers to pick, swap or upgrade their connection without losing the same API expectations and mechanisms such as back pressure and the ability to half close a connection. + +Publishing a test suite as a module lets multiple modules ensure compatibility since they use the same test suite. + +```js +import tests from '@libp2p/interface-connection-compliance-tests' + +describe('your connection', () => { + tests({ + // Options should be passed to your connection + async setup (options) { + return YourConnection + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-connection-compliance-tests/package.json b/packages/interface-connection-compliance-tests/package.json new file mode 100644 index 0000000000..d322034546 --- /dev/null +++ b/packages/interface-connection-compliance-tests/package.json @@ -0,0 +1,140 @@ +{ + "name": "@libp2p/interface-connection-compliance-tests", + "version": "2.0.9", + "description": "Compliance tests for implementations of the libp2p Connection interface", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-connection-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-connection": "^5.0.0", + "aegir": "^39.0.5", + "sinon": "^15.0.0", + "ts-sinon": "^2.0.2" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-connection-compliance-tests/src/index.ts b/packages/interface-connection-compliance-tests/src/index.ts new file mode 100644 index 0000000000..032c0ea8bb --- /dev/null +++ b/packages/interface-connection-compliance-tests/src/index.ts @@ -0,0 +1,184 @@ +import { expect } from 'aegir/chai' +import sinon from 'sinon' +import { stubInterface } from 'ts-sinon' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Connection, Stream } from '@libp2p/interface-connection' + +export default (test: TestSetup): void => { + describe('connection', () => { + describe('open connection', () => { + let connection: Connection + + beforeEach(async () => { + connection = await test.setup() + }) + + afterEach(async () => { + await connection.close() + await test.teardown() + }) + + it('should have properties set', () => { + expect(connection.id).to.exist() + expect(connection.remotePeer).to.exist() + expect(connection.remoteAddr).to.exist() + expect(connection.stat.status).to.equal('OPEN') + expect(connection.stat.timeline.open).to.exist() + expect(connection.stat.timeline.close).to.not.exist() + expect(connection.stat.direction).to.exist() + expect(connection.streams).to.eql([]) + expect(connection.tags).to.eql([]) + }) + + it('should get the metadata of an open connection', () => { + const stat = connection.stat + + expect(stat.status).to.equal('OPEN') + expect(stat.direction).to.exist() + expect(stat.timeline.open).to.exist() + expect(stat.timeline.close).to.not.exist() + }) + + it('should return an empty array of streams', () => { + const streams = connection.streams + + expect(streams).to.eql([]) + }) + + it('should be able to create a new stream', async () => { + expect(connection.streams).to.be.empty() + + const protocolToUse = '/echo/0.0.1' + const stream = await connection.newStream([protocolToUse]) + + expect(stream).to.have.nested.property('stat.protocol', protocolToUse) + + const connStreams = connection.streams + + expect(stream).to.exist() + expect(connStreams).to.exist() + expect(connStreams).to.have.lengthOf(1) + expect(connStreams[0]).to.equal(stream) + }) + }) + + describe('close connection', () => { + let connection: Connection + let timelineProxy + const proxyHandler = { + set () { + // @ts-expect-error - TS fails to infer here + return Reflect.set(...arguments) + } + } + + beforeEach(async () => { + timelineProxy = new Proxy({ + open: Date.now() - 10, + upgraded: Date.now() + }, proxyHandler) + + connection = await test.setup() + connection.stat.timeline = timelineProxy + }) + + afterEach(async () => { + await test.teardown() + }) + + it('should be able to close the connection after being created', async () => { + expect(connection.stat.timeline.close).to.not.exist() + await connection.close() + + expect(connection.stat.timeline.close).to.exist() + expect(connection.stat.status).to.equal('CLOSED') + }) + + it('should be able to close the connection after opening a stream', async () => { + // Open stream + const protocol = '/echo/0.0.1' + await connection.newStream([protocol]) + + // Close connection + expect(connection.stat.timeline.close).to.not.exist() + await connection.close() + + expect(connection.stat.timeline.close).to.exist() + expect(connection.stat.status).to.equal('CLOSED') + }) + + it('should properly track streams', async () => { + // Open stream + const protocol = '/echo/0.0.1' + const stream = await connection.newStream([protocol]) + expect(stream).to.have.nested.property('stat.protocol', protocol) + + // Close stream + stream.close() + + expect(connection.streams.filter(s => s.id === stream.id)).to.be.empty() + }) + + it('should track outbound streams', async () => { + // Open stream + const protocol = '/echo/0.0.1' + const stream = await connection.newStream(protocol) + expect(stream).to.have.nested.property('stat.direction', 'outbound') + }) + + it.skip('should track inbound streams', async () => { + // Add an remotely opened stream + const stream = stubInterface() + connection.addStream(stream) + expect(stream).to.have.property('direction', 'inbound') + }) + + it('should support a proxy on the timeline', async () => { + sinon.spy(proxyHandler, 'set') + expect(connection.stat.timeline.close).to.not.exist() + + await connection.close() + // @ts-expect-error - fails to infer callCount + expect(proxyHandler.set.callCount).to.equal(1) + // @ts-expect-error - fails to infer getCall + const [obj, key, value] = proxyHandler.set.getCall(0).args + expect(obj).to.eql(connection.stat.timeline) + expect(key).to.equal('close') + expect(value).to.be.a('number').that.equals(connection.stat.timeline.close) + }) + + it('should fail to create a new stream if the connection is closing', async () => { + expect(connection.stat.timeline.close).to.not.exist() + const p = connection.close() + + try { + const protocol = '/echo/0.0.1' + await connection.newStream([protocol]) + } catch (err: any) { + expect(err).to.exist() + return + } finally { + await p + } + + throw new Error('should fail to create a new stream if the connection is closing') + }) + + it('should fail to create a new stream if the connection is closed', async () => { + expect(connection.stat.timeline.close).to.not.exist() + await connection.close() + + try { + const protocol = '/echo/0.0.1' + await connection.newStream([protocol]) + } catch (err: any) { + expect(err).to.exist() + expect(err.code).to.equal('ERR_CONNECTION_CLOSED') + return + } + + throw new Error('should fail to create a new stream if the connection is closing') + }) + }) + }) +} diff --git a/packages/interface-connection-compliance-tests/tsconfig.json b/packages/interface-connection-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..40cf163c08 --- /dev/null +++ b/packages/interface-connection-compliance-tests/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-connection" + } + ] +} diff --git a/packages/interface-connection-encrypter-compliance-tests/CHANGELOG.md b/packages/interface-connection-encrypter-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..d9442ac70f --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/CHANGELOG.md @@ -0,0 +1,173 @@ +## [@libp2p/interface-connection-encrypter-compliance-tests-v5.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v5.0.0...@libp2p/interface-connection-encrypter-compliance-tests-v5.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v5.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v4.0.5...@libp2p/interface-connection-encrypter-compliance-tests-v5.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) +* update sibling dependencies ([bed9f4c](https://github.com/libp2p/js-libp2p-interfaces/commit/bed9f4c7b7044e974a70678762a51e79e018cf9b)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v4.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v4.0.4...@libp2p/interface-connection-encrypter-compliance-tests-v4.0.5) (2023-04-13) + + +### Dependencies + +* bump it-all from 2.0.1 to 3.0.1 ([#360](https://github.com/libp2p/js-libp2p-interfaces/issues/360)) ([1b439eb](https://github.com/libp2p/js-libp2p-interfaces/commit/1b439eb7503ed7e31e77f17ce0a685ea78d94442)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v4.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v4.0.3...@libp2p/interface-connection-encrypter-compliance-tests-v4.0.4) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v4.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v4.0.2...@libp2p/interface-connection-encrypter-compliance-tests-v4.0.3) (2023-04-04) + + +### Dependencies + +* bump it-pipe from 2.0.5 to 3.0.1 ([#363](https://github.com/libp2p/js-libp2p-interfaces/issues/363)) ([625817b](https://github.com/libp2p/js-libp2p-interfaces/commit/625817b0bbbee276983c40a0604c8810a25abe8f)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v4.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v4.0.1...@libp2p/interface-connection-encrypter-compliance-tests-v4.0.2) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v4.0.0...@libp2p/interface-connection-encrypter-compliance-tests-v4.0.1) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v3.0.5...@libp2p/interface-connection-encrypter-compliance-tests-v4.0.0) (2023-01-06) + + +### ⚠ BREAKING CHANGES + +* update peer-id dep to pull in new multiformats (#331) + +### Bug Fixes + +* update peer-id dep to pull in new multiformats ([#331](https://github.com/libp2p/js-libp2p-interfaces/issues/331)) ([fb8b7ba](https://github.com/libp2p/js-libp2p-interfaces/commit/fb8b7ba654a30a08da0652e2833e36dd3bb85e90)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v3.0.4...@libp2p/interface-connection-encrypter-compliance-tests-v3.0.5) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v3.0.3...@libp2p/interface-connection-encrypter-compliance-tests-v3.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v3.0.2...@libp2p/interface-connection-encrypter-compliance-tests-v3.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v3.0.1...@libp2p/interface-connection-encrypter-compliance-tests-v3.0.2) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v3.0.0...@libp2p/interface-connection-encrypter-compliance-tests-v3.0.1) (2022-10-17) + + +### Dependencies + +* bump it-all from 1.0.6 to 2.0.0 ([#306](https://github.com/libp2p/js-libp2p-interfaces/issues/306)) ([7c7b388](https://github.com/libp2p/js-libp2p-interfaces/commit/7c7b3882e33a064b8e5588d6befd823360347464)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v2.0.3...@libp2p/interface-connection-encrypter-compliance-tests-v3.0.0) (2022-10-12) + + +### ⚠ BREAKING CHANGES + +* modules no longer implement `Initializable` instead switching to constructor injection + +### Bug Fixes + +* remove @libp2p/components ([#301](https://github.com/libp2p/js-libp2p-interfaces/issues/301)) ([1d37dc6](https://github.com/libp2p/js-libp2p-interfaces/commit/1d37dc6d3197838a71895d5769ad8bba6eb38fd3)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v2.0.2...@libp2p/interface-connection-encrypter-compliance-tests-v2.0.3) (2022-10-04) + + +### Dependencies + +* update sibling dependencies ([419f947](https://github.com/libp2p/js-libp2p-interfaces/commit/419f9479e8bba5d0555fe20a6fb9f0cf12a82cf9)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v2.0.1...@libp2p/interface-connection-encrypter-compliance-tests-v2.0.2) (2022-09-21) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v2.0.0...@libp2p/interface-connection-encrypter-compliance-tests-v2.0.1) (2022-08-10) + + +### Bug Fixes + +* revert connection encryption change to accept Uint8ArrayLists ([#280](https://github.com/libp2p/js-libp2p-interfaces/issues/280)) ([03d763c](https://github.com/libp2p/js-libp2p-interfaces/commit/03d763c1a6b168bba001783a1fb59af3f7d4e205)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v1.0.2...@libp2p/interface-connection-encrypter-compliance-tests-v2.0.0) (2022-08-07) + + +### ⚠ BREAKING CHANGES + +* change connection encryption interface to uint8arraylist (#278) + +### Features + +* change connection encryption interface to uint8arraylist ([#278](https://github.com/libp2p/js-libp2p-interfaces/issues/278)) ([1fa580c](https://github.com/libp2p/js-libp2p-interfaces/commit/1fa580c5a45325dc9384738e9a78a238eabb81c3)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) +* update sibling dependencies ([93a89b1](https://github.com/libp2p/js-libp2p-interfaces/commit/93a89b1ca6d35fb5f26963ae7bb10026f3f5d45d)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v1.0.1...@libp2p/interface-connection-encrypter-compliance-tests-v1.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-connection-encrypter-compliance-tests-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-compliance-tests-v1.0.0...@libp2p/interface-connection-encrypter-compliance-tests-v1.0.1) (2022-06-16) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) diff --git a/packages/interface-connection-encrypter-compliance-tests/LICENSE b/packages/interface-connection-encrypter-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-connection-encrypter-compliance-tests/LICENSE-APACHE b/packages/interface-connection-encrypter-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-connection-encrypter-compliance-tests/LICENSE-MIT b/packages/interface-connection-encrypter-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-connection-encrypter-compliance-tests/README.md b/packages/interface-connection-encrypter-compliance-tests/README.md new file mode 100644 index 0000000000..85eba2b556 --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/README.md @@ -0,0 +1,54 @@ +# @libp2p/interface-connection-encrypter-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for implementations of the libp2p Connection Encrypter interface + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-connection-encrypter-compliance-tests +``` + +## Usage + +```js +import tests from '@libp2p/interface-connection-encrypter-compliance-tests' +import yourCrypto from './your-encrypter' + +tests({ + setup () { + // Set up your crypto if needed, then return it + return yourCrypto + }, + teardown () { + // Clean up your crypto if needed + } +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-connection-encrypter-compliance-tests/package.json b/packages/interface-connection-encrypter-compliance-tests/package.json new file mode 100644 index 0000000000..9f19c750c5 --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/package.json @@ -0,0 +1,147 @@ +{ + "name": "@libp2p/interface-connection-encrypter-compliance-tests", + "version": "5.0.1", + "description": "Compliance tests for implementations of the libp2p Connection Encrypter interface", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-connection-encrypter-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-connection-encrypter": "^4.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/peer-id-factory": "^2.0.0", + "@multiformats/multiaddr": "^12.0.0", + "aegir": "^39.0.5", + "it-all": "^3.0.1", + "it-pair": "^2.0.2", + "it-pipe": "^3.0.1", + "it-stream-types": "^2.0.1", + "uint8arrays": "^4.0.2" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-connection-encrypter-compliance-tests/src/index.ts b/packages/interface-connection-encrypter-compliance-tests/src/index.ts new file mode 100644 index 0000000000..c622f67add --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/src/index.ts @@ -0,0 +1,97 @@ +import peers from '@libp2p/interface-compliance-tests/peers' +import { UnexpectedPeerError } from '@libp2p/interface-connection-encrypter/errors' +import * as PeerIdFactory from '@libp2p/peer-id-factory' +import { expect } from 'aegir/chai' +import all from 'it-all' +import { pipe } from 'it-pipe' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { createMaConnPair } from './utils/index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { ConnectionEncrypter } from '@libp2p/interface-connection-encrypter' +import type { PeerId } from '@libp2p/interface-peer-id' + +export default (common: TestSetup): void => { + describe('interface-connection-encrypter compliance tests', () => { + let crypto: ConnectionEncrypter + let localPeer: PeerId + let remotePeer: PeerId + let mitmPeer: PeerId + + before(async () => { + [ + crypto, + localPeer, + remotePeer, + mitmPeer + ] = await Promise.all([ + common.setup(), + PeerIdFactory.createFromJSON(peers[0]), + PeerIdFactory.createFromJSON(peers[1]), + PeerIdFactory.createFromJSON(peers[2]) + ]) + }) + + after(async () => { + await common.teardown() + }) + + it('has a protocol string', () => { + expect(crypto.protocol).to.exist() + expect(crypto.protocol).to.be.a('string') + }) + + it('it wraps the provided duplex connection', async () => { + const [localConn, remoteConn] = createMaConnPair() + + const [ + inboundResult, + outboundResult + ] = await Promise.all([ + crypto.secureInbound(remotePeer, localConn), + crypto.secureOutbound(localPeer, remoteConn, remotePeer) + ]) + + // Echo server + void pipe(inboundResult.conn, inboundResult.conn) + + // Send some data and collect the result + const input = uint8ArrayFromString('data to encrypt') + const result = await pipe( + [input], + outboundResult.conn, + async (source) => all(source) + ) + + expect(result).to.eql([input]) + }) + + it('should return the remote peer id', async () => { + const [localConn, remoteConn] = createMaConnPair() + + const [ + inboundResult, + outboundResult + ] = await Promise.all([ + crypto.secureInbound(remotePeer, localConn), + crypto.secureOutbound(localPeer, remoteConn, remotePeer) + ]) + + // Inbound should return the initiator (local) peer + expect(inboundResult.remotePeer.toBytes()).to.equalBytes(localPeer.toBytes()) + // Outbound should return the receiver (remote) peer + expect(outboundResult.remotePeer.toBytes()).to.equalBytes(remotePeer.toBytes()) + }) + + it('inbound connections should verify peer integrity if known', async () => { + const [localConn, remoteConn] = createMaConnPair() + + await Promise.all([ + crypto.secureInbound(remotePeer, localConn, mitmPeer), + crypto.secureOutbound(localPeer, remoteConn, remotePeer) + ]).then(() => expect.fail(), (err) => { + expect(err).to.exist() + expect(err).to.have.property('code', UnexpectedPeerError.code) + }) + }) + }) +} diff --git a/packages/interface-connection-encrypter-compliance-tests/src/utils/index.ts b/packages/interface-connection-encrypter-compliance-tests/src/utils/index.ts new file mode 100644 index 0000000000..4c50901daf --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/src/utils/index.ts @@ -0,0 +1,23 @@ +import { multiaddr } from '@multiformats/multiaddr' +import { duplexPair } from 'it-pair/duplex' +import type { MultiaddrConnection } from '@libp2p/interface-connection' +import type { Duplex, Source } from 'it-stream-types' + +export function createMaConnPair (): [MultiaddrConnection, MultiaddrConnection] { + const [local, remote] = duplexPair() + + function duplexToMaConn (duplex: Duplex, Source, Promise>): MultiaddrConnection { + const output: MultiaddrConnection = { + ...duplex, + close: async () => {}, + remoteAddr: multiaddr('/ip4/127.0.0.1/tcp/4001'), + timeline: { + open: Date.now() + } + } + + return output + } + + return [duplexToMaConn(local), duplexToMaConn(remote)] +} diff --git a/packages/interface-connection-encrypter-compliance-tests/tsconfig.json b/packages/interface-connection-encrypter-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..77fd5244fb --- /dev/null +++ b/packages/interface-connection-encrypter-compliance-tests/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-connection" + }, + { + "path": "../interface-connection-encrypter" + }, + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-connection-encrypter/CHANGELOG.md b/packages/interface-connection-encrypter/CHANGELOG.md new file mode 100644 index 0000000000..f6826ffa1a --- /dev/null +++ b/packages/interface-connection-encrypter/CHANGELOG.md @@ -0,0 +1,137 @@ +## [@libp2p/interface-connection-encrypter-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v4.0.0...@libp2p/interface-connection-encrypter-v4.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-connection-encrypter-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v3.0.6...@libp2p/interface-connection-encrypter-v4.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) + +## [@libp2p/interface-connection-encrypter-v3.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v3.0.5...@libp2p/interface-connection-encrypter-v3.0.6) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-connection-encrypter-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v3.0.4...@libp2p/interface-connection-encrypter-v3.0.5) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-connection-encrypter-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v3.0.3...@libp2p/interface-connection-encrypter-v3.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-connection-encrypter-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v3.0.2...@libp2p/interface-connection-encrypter-v3.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-connection-encrypter-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v3.0.1...@libp2p/interface-connection-encrypter-v3.0.2) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-connection-encrypter-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v3.0.0...@libp2p/interface-connection-encrypter-v3.0.1) (2022-10-04) + + +### Bug Fixes + +* add default extension type ([#296](https://github.com/libp2p/js-libp2p-interfaces/issues/296)) ([ab658bc](https://github.com/libp2p/js-libp2p-interfaces/commit/ab658bc1b11e411e685388acb9da8f65d62ef919)) + +## [@libp2p/interface-connection-encrypter-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v2.0.2...@libp2p/interface-connection-encrypter-v3.0.0) (2022-10-04) + + +### ⚠ BREAKING CHANGES + +* Add remoteExtensions to connection-encrypter (#293) + +### Features + +* Add remoteExtensions to connection-encrypter ([#293](https://github.com/libp2p/js-libp2p-interfaces/issues/293)) ([501c684](https://github.com/libp2p/js-libp2p-interfaces/commit/501c684d792cd910de7cb9bfbda349db257ee2ca)) + +## [@libp2p/interface-connection-encrypter-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v2.0.1...@libp2p/interface-connection-encrypter-v2.0.2) (2022-09-30) + + +### Bug Fixes + +* make outbound peer id optional ([#294](https://github.com/libp2p/js-libp2p-interfaces/issues/294)) ([6724ffe](https://github.com/libp2p/js-libp2p-interfaces/commit/6724ffef0d170dba2d4c9973b46334fc421f8ea8)) + +## [@libp2p/interface-connection-encrypter-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v2.0.0...@libp2p/interface-connection-encrypter-v2.0.1) (2022-08-10) + + +### Bug Fixes + +* revert connection encryption change to accept Uint8ArrayLists ([#280](https://github.com/libp2p/js-libp2p-interfaces/issues/280)) ([03d763c](https://github.com/libp2p/js-libp2p-interfaces/commit/03d763c1a6b168bba001783a1fb59af3f7d4e205)) + +## [@libp2p/interface-connection-encrypter-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v1.0.3...@libp2p/interface-connection-encrypter-v2.0.0) (2022-08-07) + + +### ⚠ BREAKING CHANGES + +* change connection encryption interface to uint8arraylist (#278) + +### Features + +* change connection encryption interface to uint8arraylist ([#278](https://github.com/libp2p/js-libp2p-interfaces/issues/278)) ([1fa580c](https://github.com/libp2p/js-libp2p-interfaces/commit/1fa580c5a45325dc9384738e9a78a238eabb81c3)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-connection-encrypter-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v1.0.2...@libp2p/interface-connection-encrypter-v1.0.3) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-connection-encrypter-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v1.0.1...@libp2p/interface-connection-encrypter-v1.0.2) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) + +## [@libp2p/interface-connection-encrypter-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-encrypter-v1.0.0...@libp2p/interface-connection-encrypter-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-connection-encrypter-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-connection-encrypter/LICENSE b/packages/interface-connection-encrypter/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-connection-encrypter/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-connection-encrypter/LICENSE-APACHE b/packages/interface-connection-encrypter/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-connection-encrypter/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-connection-encrypter/LICENSE-MIT b/packages/interface-connection-encrypter/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-connection-encrypter/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-connection-encrypter/README.md b/packages/interface-connection-encrypter/README.md new file mode 100644 index 0000000000..685137bc20 --- /dev/null +++ b/packages/interface-connection-encrypter/README.md @@ -0,0 +1,114 @@ +# @libp2p/interface-connection-encrypter + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Connection Encrypter interface for libp2p + +## Table of contents + +- [Install](#install) +- [API](#api) + - [Secure Inbound](#secure-inbound) + - [Secure Outbound](#secure-outbound) +- [Crypto Errors](#crypto-errors) + - [Error Types](#error-types) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-connection-encrypter +``` + +**Modules that implement the interface** + +- [@chainSafe/js-libp2p-noise](https://github.com/ChainSafe/js-libp2p-noise) +- [js-libp2p-secio](https://github.com/NodeFactoryIo/js-libp2p-secio) + +## API + +- `Crypto` + - `protocol`: The protocol id of the crypto module. + - `secureInbound`: Secures inbound connections. + - `secureOutbound`: Secures outbound connections. + +### Secure Inbound + +- `const { conn, remotePeer } = await crypto.secureInbound(localPeer, duplex, [remotePeer])` + +Secures an inbound [streaming iterable duplex][iterable-duplex] connection. It returns an encrypted [streaming iterable duplex][iterable-duplex], as well as the [PeerId][peer-id] of the remote peer. + +**Parameters** + +- `localPeer` is the [PeerId][peer-id] of the receiving peer. +- `duplex` is the [streaming iterable duplex][iterable-duplex] that will be encryption. +- `remotePeer` is the optional [PeerId][peer-id] of the initiating peer, if known. This may only exist during transport upgrades. + +**Return Value** + +- `` + - `conn`: An encrypted [streaming iterable duplex][iterable-duplex]. + - `remotePeer`: The [PeerId][peer-id] of the remote peer. + +### Secure Outbound + +- `const { conn, remotePeer } = await crypto.secureOutbound(localPeer, duplex, remotePeer)` + +Secures an outbound [streaming iterable duplex][iterable-duplex] connection. It returns an encrypted [streaming iterable duplex][iterable-duplex], as well as the [PeerId][peer-id] of the remote peer. + +**Parameters** + +- `localPeer` is the [PeerId][peer-id] of the receiving peer. +- `duplex` is the [streaming iterable duplex][iterable-duplex] that will be encrypted. +- `remotePeer` is the [PeerId][peer-id] of the remote peer. If provided, implementations **should** use this to validate the integrity of the remote peer. + +**Return Value** + +- `` + - `conn`: An encrypted [streaming iterable duplex][iterable-duplex]. + - `remotePeer`: The [PeerId][peer-id] of the remote peer. This **should** match the `remotePeer` parameter, and implementations should enforce this. + +## Crypto Errors + +Common crypto errors come with the interface, and can be imported directly. All Errors take an optional message. + +```js +const { + InvalidCryptoExchangeError, + InvalidCryptoTransmissionError, + UnexpectedPeerError +} = require('libp2p-interfaces/src/crypto/errors') + +const error = new UnexpectedPeerError('a custom error message') +console.log(error.code === UnexpectedPeerError.code) // true +``` + +### Error Types + +- `InvalidCryptoExchangeError` - Should be thrown when a peer provides data that is insufficient to finish the crypto exchange. +- `InvalidCryptoTransmissionError` - Should be thrown when an error occurs during encryption/decryption. +- `UnexpectedPeerError` - Should be thrown when the expected peer id does not match the peer id determined via the crypto exchange. + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. + +[peer-id]: https://github.com/libp2p/js-peer-id + +[iterable-duplex]: https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9#duplex-it diff --git a/packages/interface-connection-encrypter/package.json b/packages/interface-connection-encrypter/package.json new file mode 100644 index 0000000000..24611a551d --- /dev/null +++ b/packages/interface-connection-encrypter/package.json @@ -0,0 +1,160 @@ +{ + "name": "@libp2p/interface-connection-encrypter", + "version": "4.0.1", + "description": "Connection Encrypter interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-connection-encrypter#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ], + "src/*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ] + } + }, + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./errors": { + "types": "./dist/src/errors.d.ts", + "import": "./dist/src/errors.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-id": "^2.0.0", + "it-stream-types": "^2.0.1" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-connection-encrypter/src/errors.ts b/packages/interface-connection-encrypter/src/errors.ts new file mode 100644 index 0000000000..e23304aae3 --- /dev/null +++ b/packages/interface-connection-encrypter/src/errors.ts @@ -0,0 +1,33 @@ + +export class UnexpectedPeerError extends Error { + public code: string + + constructor (message = 'Unexpected Peer') { + super(message) + this.code = UnexpectedPeerError.code + } + + static readonly code = 'ERR_UNEXPECTED_PEER' +} + +export class InvalidCryptoExchangeError extends Error { + public code: string + + constructor (message = 'Invalid crypto exchange') { + super(message) + this.code = InvalidCryptoExchangeError.code + } + + static readonly code = 'ERR_INVALID_CRYPTO_EXCHANGE' +} + +export class InvalidCryptoTransmissionError extends Error { + public code: string + + constructor (message = 'Invalid crypto transmission') { + super(message) + this.code = InvalidCryptoTransmissionError.code + } + + static readonly code = 'ERR_INVALID_CRYPTO_TRANSMISSION' +} diff --git a/packages/interface-connection-encrypter/src/index.ts b/packages/interface-connection-encrypter/src/index.ts new file mode 100644 index 0000000000..d8bcddd2e8 --- /dev/null +++ b/packages/interface-connection-encrypter/src/index.ts @@ -0,0 +1,30 @@ +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Duplex, Source } from 'it-stream-types' + +/** + * A libp2p connection encrypter module must be compliant to this interface + * to ensure all exchanged data between two peers is encrypted. + */ +export interface ConnectionEncrypter { + protocol: string + + /** + * Encrypt outgoing data to the remote party. If the remote PeerId is known, + * pass it for extra verification, otherwise it will be determined during + * the handshake. + */ + secureOutbound: (localPeer: PeerId, connection: Duplex, Source, Promise>, remotePeer?: PeerId) => Promise> + + /** + * Decrypt incoming data. If the remote PeerId is known, + * pass it for extra verification, otherwise it will be determined during + * the handshake + */ + secureInbound: (localPeer: PeerId, connection: Duplex, Source, Promise>, remotePeer?: PeerId) => Promise> +} + +export interface SecuredConnection { + conn: Duplex, Source, Promise> + remoteExtensions?: Extension + remotePeer: PeerId +} diff --git a/packages/interface-connection-encrypter/tsconfig.json b/packages/interface-connection-encrypter/tsconfig.json new file mode 100644 index 0000000000..d8db0b667f --- /dev/null +++ b/packages/interface-connection-encrypter/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-connection-gater/CHANGELOG.md b/packages/interface-connection-gater/CHANGELOG.md new file mode 100644 index 0000000000..c50efe4d71 --- /dev/null +++ b/packages/interface-connection-gater/CHANGELOG.md @@ -0,0 +1,64 @@ +## [@libp2p/interface-connection-gater-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-gater-v3.0.0...@libp2p/interface-connection-gater-v3.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-connection-gater-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-gater-v2.0.1...@libp2p/interface-connection-gater-v3.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-connection-gater-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-gater-v2.0.0...@libp2p/interface-connection-gater-v2.0.1) (2023-04-14) + + +### Bug Fixes + +* make deny dial multiaddr optional ([#370](https://github.com/libp2p/js-libp2p-interfaces/issues/370)) ([6bf7a7e](https://github.com/libp2p/js-libp2p-interfaces/commit/6bf7a7e9fe2a77a43c5ddf114c26c4978c579d46)) + +## [@libp2p/interface-connection-gater-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-gater-v1.0.3...@libp2p/interface-connection-gater-v2.0.0) (2023-04-14) + + +### ⚠ BREAKING CHANGES + +* the peer id argument has been removed from the `denyDialMultiaddr` method of the connection gater + +### Bug Fixes + +* remove peer id argument from deny dial multiaddr ([#366](https://github.com/libp2p/js-libp2p-interfaces/issues/366)) ([aa3e000](https://github.com/libp2p/js-libp2p-interfaces/commit/aa3e0008a94d943df961da7756bf4cf6862bd4c1)) + +## [@libp2p/interface-connection-gater-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-gater-v1.0.2...@libp2p/interface-connection-gater-v1.0.3) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-connection-gater-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-gater-v1.0.1...@libp2p/interface-connection-gater-v1.0.2) (2023-03-17) + + +### Bug Fixes + +* update project settings ([2aa4f95](https://github.com/libp2p/js-libp2p-interfaces/commit/2aa4f9583fb8ff9b53c51ebb6b81f72d69a1748d)) + +## [@libp2p/interface-connection-gater-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-gater-v1.0.0...@libp2p/interface-connection-gater-v1.0.1) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## @libp2p/interface-connection-gater-v1.0.0 (2023-03-09) + + +### Features + +* split connection gater out into module ([#347](https://github.com/libp2p/js-libp2p-interfaces/issues/347)) ([1824744](https://github.com/libp2p/js-libp2p-interfaces/commit/18247442aa64c809d9e101ccbd0067ce48bdb80f)) diff --git a/packages/interface-connection-gater/LICENSE b/packages/interface-connection-gater/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-connection-gater/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-connection-gater/LICENSE-APACHE b/packages/interface-connection-gater/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-connection-gater/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-connection-gater/LICENSE-MIT b/packages/interface-connection-gater/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-connection-gater/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-connection-gater/README.md b/packages/interface-connection-gater/README.md new file mode 100644 index 0000000000..a5f03d34ae --- /dev/null +++ b/packages/interface-connection-gater/README.md @@ -0,0 +1,36 @@ +# @libp2p/interface-connection-gater + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Connection gater interface for libp2p + +## Table of contents + +- [Install](#install) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-connection-gater +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-connection-gater/package.json b/packages/interface-connection-gater/package.json new file mode 100644 index 0000000000..3d3f6b706b --- /dev/null +++ b/packages/interface-connection-gater/package.json @@ -0,0 +1,141 @@ +{ + "name": "@libp2p/interface-connection-gater", + "version": "3.0.1", + "description": "Connection gater interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-connection-gater#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@multiformats/multiaddr": "^12.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-connection-gater/src/index.ts b/packages/interface-connection-gater/src/index.ts new file mode 100644 index 0000000000..923449ca5d --- /dev/null +++ b/packages/interface-connection-gater/src/index.ts @@ -0,0 +1,128 @@ +import type { MultiaddrConnection } from '@libp2p/interface-connection' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Multiaddr } from '@multiformats/multiaddr' + +export interface ConnectionGater { + /** + * denyDialPeer tests whether we're permitted to Dial the + * specified peer. + * + * This is called by the dialer.connectToPeer implementation before + * dialling a peer. + * + * Return true to prevent dialing the passed peer. + */ + denyDialPeer?: (peerId: PeerId) => Promise + + /** + * denyDialMultiaddr tests whether we're permitted to dial the specified + * multiaddr. + * + * This is called by the connection manager - if the peer id of the remote + * node is known it will be present in the multiaddr. + * + * Return true to prevent dialing the passed peer on the passed multiaddr. + */ + denyDialMultiaddr?: (multiaddr: Multiaddr) => Promise + + /** + * denyInboundConnection tests whether an incipient inbound connection is allowed. + * + * This is called by the upgrader, or by the transport directly (e.g. QUIC, + * Bluetooth), straight after it has accepted a connection from its socket. + * + * Return true to deny the incoming passed connection. + */ + denyInboundConnection?: (maConn: MultiaddrConnection) => Promise + + /** + * denyOutboundConnection tests whether an incipient outbound connection is allowed. + * + * This is called by the upgrader, or by the transport directly (e.g. QUIC, + * Bluetooth), straight after it has created a connection with its socket. + * + * Return true to deny the incoming passed connection. + */ + denyOutboundConnection?: (peerId: PeerId, maConn: MultiaddrConnection) => Promise + + /** + * denyInboundEncryptedConnection tests whether a given connection, now encrypted, + * is allowed. + * + * This is called by the upgrader, after it has performed the security + * handshake, and before it negotiates the muxer, or by the directly by the + * transport, at the exact same checkpoint. + * + * Return true to deny the passed secured connection. + */ + denyInboundEncryptedConnection?: (peerId: PeerId, maConn: MultiaddrConnection) => Promise + + /** + * denyOutboundEncryptedConnection tests whether a given connection, now encrypted, + * is allowed. + * + * This is called by the upgrader, after it has performed the security + * handshake, and before it negotiates the muxer, or by the directly by the + * transport, at the exact same checkpoint. + * + * Return true to deny the passed secured connection. + */ + denyOutboundEncryptedConnection?: (peerId: PeerId, maConn: MultiaddrConnection) => Promise + + /** + * denyInboundUpgradedConnection tests whether a fully capable connection is allowed. + * + * This is called after encryption has been negotiated and the connection has been + * multiplexed, if a multiplexer is configured. + * + * Return true to deny the passed upgraded connection. + */ + denyInboundUpgradedConnection?: (peerId: PeerId, maConn: MultiaddrConnection) => Promise + + /** + * denyOutboundUpgradedConnection tests whether a fully capable connection is allowed. + * + * This is called after encryption has been negotiated and the connection has been + * multiplexed, if a multiplexer is configured. + * + * Return true to deny the passed upgraded connection. + */ + denyOutboundUpgradedConnection?: (peerId: PeerId, maConn: MultiaddrConnection) => Promise + + /** + * denyInboundRelayReservation tests whether a remote peer is allowed make a + * relay reservation on this node. + * + * Return true to deny the relay reservation. + */ + denyInboundRelayReservation?: (source: PeerId) => Promise + + /** + * denyOutboundRelayedConnection tests whether a remote peer is allowed to open a relayed + * connection to the destination node. + * + * This is invoked on the relay server when a source client with a reservation instructs + * the server to relay a connection to a destination peer. + * + * Return true to deny the relayed connection. + */ + denyOutboundRelayedConnection?: (source: PeerId, destination: PeerId) => Promise + + /** + * denyInboundRelayedConnection tests whether a remote peer is allowed to open a relayed + * connection to this node. + * + * This is invoked on the relay client when a remote relay has received an instruction to + * relay a connection to the client. + * + * Return true to deny the relayed connection. + */ + denyInboundRelayedConnection?: (relay: PeerId, remotePeer: PeerId) => Promise + + /** + * Used by the address book to filter passed addresses. + * + * Return true to allow storing the passed multiaddr for the passed peer. + */ + filterMultiaddrForPeer?: (peer: PeerId, multiaddr: Multiaddr) => Promise +} diff --git a/packages/interface-connection-gater/tsconfig.json b/packages/interface-connection-gater/tsconfig.json new file mode 100644 index 0000000000..16ab3d8b56 --- /dev/null +++ b/packages/interface-connection-gater/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-connection-manager/CHANGELOG.md b/packages/interface-connection-manager/CHANGELOG.md new file mode 100644 index 0000000000..75dd3e8235 --- /dev/null +++ b/packages/interface-connection-manager/CHANGELOG.md @@ -0,0 +1,179 @@ +## [@libp2p/interface-connection-manager-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v3.0.0...@libp2p/interface-connection-manager-v3.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-connection-manager-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v2.1.1...@libp2p/interface-connection-manager-v3.0.0) (2023-04-21) + + +### ⚠ BREAKING CHANGES + +* add libp2p events (#373) + +### Features + +* add libp2p events ([#373](https://github.com/libp2p/js-libp2p-interfaces/issues/373)) ([071c718](https://github.com/libp2p/js-libp2p-interfaces/commit/071c718808902858818ca86167b51b242b67a5a5)) + +## [@libp2p/interface-connection-manager-v2.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v2.1.0...@libp2p/interface-connection-manager-v2.1.1) (2023-04-18) + + +### Dependencies + +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-connection-manager-v2.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v2.0.0...@libp2p/interface-connection-manager-v2.1.0) (2023-04-14) + + +### Features + +* expose get connection map method of connection manager ([#372](https://github.com/libp2p/js-libp2p-interfaces/issues/372)) ([fc7245b](https://github.com/libp2p/js-libp2p-interfaces/commit/fc7245b63764562f5ec66a5a0ba334caea80ed66)) +* expose get dial queue method of connection manager ([#371](https://github.com/libp2p/js-libp2p-interfaces/issues/371)) ([0c407aa](https://github.com/libp2p/js-libp2p-interfaces/commit/0c407aa0772c171bf6650e31fb20a3433df40b6b)) + +## [@libp2p/interface-connection-manager-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.5.0...@libp2p/interface-connection-manager-v2.0.0) (2023-04-14) + + +### ⚠ BREAKING CHANGES + +* the Dialer interface has been removed + +### Bug Fixes + +* remove dialer interface from interface connection manager ([#364](https://github.com/libp2p/js-libp2p-interfaces/issues/364)) ([5fb8a34](https://github.com/libp2p/js-libp2p-interfaces/commit/5fb8a342150efbc8c0ac8b1ae76ec53dc9f60ee9)) + +## [@libp2p/interface-connection-manager-v1.5.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.4.1...@libp2p/interface-connection-manager-v1.5.0) (2023-04-11) + + +### Features + +* add peer:prune event to connection manager ([#367](https://github.com/libp2p/js-libp2p-interfaces/issues/367)) ([45680c6](https://github.com/libp2p/js-libp2p-interfaces/commit/45680c614f082e1d02c5258559f3ee3b711e6a87)) + +## [@libp2p/interface-connection-manager-v1.4.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.4.0...@libp2p/interface-connection-manager-v1.4.1) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-connection-manager-v1.4.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.8...@libp2p/interface-connection-manager-v1.4.0) (2023-04-05) + + +### Features + +* support batch dialling ([#351](https://github.com/libp2p/js-libp2p-interfaces/issues/351)) ([e46b72b](https://github.com/libp2p/js-libp2p-interfaces/commit/e46b72b1731ff935a1f0d755cbaf6f3159060ed3)) + +## [@libp2p/interface-connection-manager-v1.3.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.7...@libp2p/interface-connection-manager-v1.3.8) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-connection-manager-v1.3.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.6...@libp2p/interface-connection-manager-v1.3.7) (2023-01-18) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-connection-manager-v1.3.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.5...@libp2p/interface-connection-manager-v1.3.6) (2023-01-14) + + +### Bug Fixes + +* accept multiaddr param when opening connections ([#336](https://github.com/libp2p/js-libp2p-interfaces/issues/336)) ([fef9c26](https://github.com/libp2p/js-libp2p-interfaces/commit/fef9c26847cf63cb95f5fcb51ee40cbc679cc6bf)) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + +## [@libp2p/interface-connection-manager-v1.3.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.4...@libp2p/interface-connection-manager-v1.3.5) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-connection-manager-v1.3.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.3...@libp2p/interface-connection-manager-v1.3.4) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-connection-manager-v1.3.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.2...@libp2p/interface-connection-manager-v1.3.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-connection-manager-v1.3.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.1...@libp2p/interface-connection-manager-v1.3.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-connection-manager-v1.3.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.3.0...@libp2p/interface-connection-manager-v1.3.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-connection-manager-v1.3.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.2.0...@libp2p/interface-connection-manager-v1.3.0) (2022-10-11) + + +### Features + +* add afterUpgradeInbound method ([#300](https://github.com/libp2p/js-libp2p-interfaces/issues/300)) ([fbdf5f5](https://github.com/libp2p/js-libp2p-interfaces/commit/fbdf5f54277735a26df0a28099eeae9d57159978)) + +## [@libp2p/interface-connection-manager-v1.2.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.1.1...@libp2p/interface-connection-manager-v1.2.0) (2022-10-04) + + +### Features + +* add acceptIncomingConnection to ConnectionManager ([#295](https://github.com/libp2p/js-libp2p-interfaces/issues/295)) ([5d460e8](https://github.com/libp2p/js-libp2p-interfaces/commit/5d460e8815a8b49915da7ffabccc4a8b96a61acc)) + +## [@libp2p/interface-connection-manager-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.1.0...@libp2p/interface-connection-manager-v1.1.1) (2022-09-21) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-connection-manager-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.0.3...@libp2p/interface-connection-manager-v1.1.0) (2022-09-09) + + +### Features + +* add dialer interface ([#285](https://github.com/libp2p/js-libp2p-interfaces/issues/285)) ([1e62df4](https://github.com/libp2p/js-libp2p-interfaces/commit/1e62df4f15b45abe62fe8400dbd88866a2bc13cd)) + +## [@libp2p/interface-connection-manager-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.0.2...@libp2p/interface-connection-manager-v1.0.3) (2022-08-07) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-connection-manager-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.0.1...@libp2p/interface-connection-manager-v1.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-connection-manager-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-manager-v1.0.0...@libp2p/interface-connection-manager-v1.0.1) (2022-06-16) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) diff --git a/packages/interface-connection-manager/LICENSE b/packages/interface-connection-manager/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-connection-manager/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-connection-manager/LICENSE-APACHE b/packages/interface-connection-manager/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-connection-manager/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-connection-manager/LICENSE-MIT b/packages/interface-connection-manager/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-connection-manager/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-connection-manager/README.md b/packages/interface-connection-manager/README.md new file mode 100644 index 0000000000..ac0985fe6f --- /dev/null +++ b/packages/interface-connection-manager/README.md @@ -0,0 +1,43 @@ +# @libp2p/interface-connection-manager + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Connection Manager interface for libp2p + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-connection-manager +``` + +## Usage + +```js +import type { ConnectionManager } from '@libp2p/interface-connection-manager' +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-connection-manager/package.json b/packages/interface-connection-manager/package.json new file mode 100644 index 0000000000..28a8101839 --- /dev/null +++ b/packages/interface-connection-manager/package.json @@ -0,0 +1,143 @@ +{ + "name": "@libp2p/interface-connection-manager", + "version": "3.0.1", + "description": "Connection Manager interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-connection-manager#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interfaces": "^3.0.0", + "@libp2p/peer-collections": "^3.0.1", + "@multiformats/multiaddr": "^12.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-connection-manager/src/index.ts b/packages/interface-connection-manager/src/index.ts new file mode 100644 index 0000000000..ca9bebc2d2 --- /dev/null +++ b/packages/interface-connection-manager/src/index.ts @@ -0,0 +1,79 @@ +import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { AbortOptions } from '@libp2p/interfaces' +import type { PeerMap } from '@libp2p/peer-collections' +import type { Multiaddr } from '@multiformats/multiaddr' + +export type PendingDialStatus = 'queued' | 'active' | 'error' | 'success' + +export interface PendingDial { + id: string + status: PendingDialStatus + peerId?: PeerId + multiaddrs: Multiaddr[] +} + +export interface ConnectionManager { + /** + * Return connections, optionally filtering by a PeerId + * + * @example + * + * ```js + * const connections = libp2p.connectionManager.get(peerId) + * // [] + * ``` + */ + getConnections: (peerId?: PeerId) => Connection[] + + /** + * Return a map of all connections with their associated PeerIds + * + * @example + * + * ```js + * const connectionsMap = libp2p.connectionManager.getConnectionsMap() + * ``` + */ + getConnectionsMap: () => PeerMap + + /** + * Open a connection to a remote peer + * + * @example + * + * ```js + * const connection = await libp2p.connectionManager.openConnection(peerId) + * ``` + */ + openConnection: (peer: PeerId | Multiaddr | Multiaddr[], options?: AbortOptions) => Promise + + /** + * Close our connections to a peer + */ + closeConnections: (peer: PeerId) => Promise + + /** + * Invoked after an incoming connection is opened but before PeerIds are + * exchanged, this lets the ConnectionManager check we have sufficient + * resources to accept the connection in which case it will return true, + * otherwise it will return false. + */ + acceptIncomingConnection: (maConn: MultiaddrConnection) => Promise + + /** + * Invoked after upgrading a multiaddr connection has finished + */ + afterUpgradeInbound: () => void + + /** + * Return the list of in-progress or queued dials + * + * @example + * + * ```js + * const dials = libp2p.connectionManager.getDialQueue() + * ``` + */ + getDialQueue: () => PendingDial[] +} diff --git a/packages/interface-connection-manager/tsconfig.json b/packages/interface-connection-manager/tsconfig.json new file mode 100644 index 0000000000..cbde3d05cb --- /dev/null +++ b/packages/interface-connection-manager/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interface-peer-id" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-connection/CHANGELOG.md b/packages/interface-connection/CHANGELOG.md new file mode 100644 index 0000000000..4cbc441900 --- /dev/null +++ b/packages/interface-connection/CHANGELOG.md @@ -0,0 +1,188 @@ +## [@libp2p/interface-connection-v5.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v5.1.0...@libp2p/interface-connection-v5.1.1) (2023-06-14) + + +### Bug Fixes + +* add maxOutboundStreams option to connection.newStream ([#415](https://github.com/libp2p/js-libp2p-interfaces/issues/415)) ([45ae18f](https://github.com/libp2p/js-libp2p-interfaces/commit/45ae18fe30436dedf418e0fa328f1af9a18a9a98)) + +## [@libp2p/interface-connection-v5.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v5.0.2...@libp2p/interface-connection-v5.1.0) (2023-05-16) + + +### Features + +* add closeRead and closeWrite to stream timeline properties ([#401](https://github.com/libp2p/js-libp2p-interfaces/issues/401)) ([b1de032](https://github.com/libp2p/js-libp2p-interfaces/commit/b1de0327cc6128b52ff1ceabe333481fb8a24bcb)) + +## [@libp2p/interface-connection-v5.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v5.0.1...@libp2p/interface-connection-v5.0.2) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-connection-v5.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v5.0.0...@libp2p/interface-connection-v5.0.1) (2023-04-18) + + +### Bug Fixes + +* specify stream sink return type ([#378](https://github.com/libp2p/js-libp2p-interfaces/issues/378)) ([e0641fc](https://github.com/libp2p/js-libp2p-interfaces/commit/e0641fcc2f2a6562e7f7d8e064ebd98c5cc6dccb)) + +## [@libp2p/interface-connection-v5.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v4.0.0...@libp2p/interface-connection-v5.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) + +## [@libp2p/interface-connection-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.1.1...@libp2p/interface-connection-v4.0.0) (2023-04-11) + + +### ⚠ BREAKING CHANGES + +* remove connection gater from interface-connection (#365) + +### Bug Fixes + +* remove connection gater from interface-connection ([#365](https://github.com/libp2p/js-libp2p-interfaces/issues/365)) ([1cc13d3](https://github.com/libp2p/js-libp2p-interfaces/commit/1cc13d3f0cbb9a82cdfca77af2a4deb5e20e8f6a)) + +## [@libp2p/interface-connection-v3.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.1.0...@libp2p/interface-connection-v3.1.1) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-connection-v3.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.8...@libp2p/interface-connection-v3.1.0) (2023-03-09) + + +### Features + +* split connection gater out into module ([#347](https://github.com/libp2p/js-libp2p-interfaces/issues/347)) ([1824744](https://github.com/libp2p/js-libp2p-interfaces/commit/18247442aa64c809d9e101ccbd0067ce48bdb80f)) + +## [@libp2p/interface-connection-v3.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.7...@libp2p/interface-connection-v3.0.8) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-connection-v3.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.6...@libp2p/interface-connection-v3.0.7) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-connection-v3.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.5...@libp2p/interface-connection-v3.0.6) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-connection-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.4...@libp2p/interface-connection-v3.0.5) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-connection-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.3...@libp2p/interface-connection-v3.0.4) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-connection-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.2...@libp2p/interface-connection-v3.0.3) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-connection-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.1...@libp2p/interface-connection-v3.0.2) (2022-09-21) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-connection-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v3.0.0...@libp2p/interface-connection-v3.0.1) (2022-08-10) + + +### Bug Fixes + +* revert connection encryption change to accept Uint8ArrayLists ([#280](https://github.com/libp2p/js-libp2p-interfaces/issues/280)) ([03d763c](https://github.com/libp2p/js-libp2p-interfaces/commit/03d763c1a6b168bba001783a1fb59af3f7d4e205)) + +## [@libp2p/interface-connection-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v2.1.1...@libp2p/interface-connection-v3.0.0) (2022-08-07) + + +### ⚠ BREAKING CHANGES + +* change stream muxer interface (#279) +* change connection encryption interface to uint8arraylist (#278) + +### Features + +* change connection encryption interface to uint8arraylist ([#278](https://github.com/libp2p/js-libp2p-interfaces/issues/278)) ([1fa580c](https://github.com/libp2p/js-libp2p-interfaces/commit/1fa580c5a45325dc9384738e9a78a238eabb81c3)) +* change stream muxer interface ([#279](https://github.com/libp2p/js-libp2p-interfaces/issues/279)) ([1ebe269](https://github.com/libp2p/js-libp2p-interfaces/commit/1ebe26988b6a286f36a4fc5177f502cfb60368a1)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-connection-v2.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v2.1.0...@libp2p/interface-connection-v2.1.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-connection-v2.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v2.0.0...@libp2p/interface-connection-v2.1.0) (2022-06-21) + + +### Features + +* add direction to StreamMuxerInit ([#253](https://github.com/libp2p/js-libp2p-interfaces/issues/253)) ([6d34d75](https://github.com/libp2p/js-libp2p-interfaces/commit/6d34d755ff4e798d52945f1f099052bdd6a83f2b)) + +## [@libp2p/interface-connection-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v1.0.1...@libp2p/interface-connection-v2.0.0) (2022-06-16) + + +### ⚠ BREAKING CHANGES + +* The Connection and Stream APIs have been updated + +### Features + +* store stream data on the stream, track the stream direction ([#245](https://github.com/libp2p/js-libp2p-interfaces/issues/245)) ([6d74d2f](https://github.com/libp2p/js-libp2p-interfaces/commit/6d74d2f9f344fb4d6741ba0d35263ebe351a4c65)) + +## [@libp2p/interface-connection-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-connection-v1.0.0...@libp2p/interface-connection-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* **release:** 1.0.0 [skip ci] ([0005492](https://github.com/libp2p/js-libp2p-interfaces/commit/0005492cc5958d261017f6db5fe1073b83b46265)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) [#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234) [#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233) + +## @libp2p/interface-connection-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) +* release [skip ci] ([357286d](https://github.com/libp2p/js-libp2p-interfaces/commit/357286df899899cf7a94348aeb8dd7387f7acad5)) +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) diff --git a/packages/interface-connection/LICENSE b/packages/interface-connection/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-connection/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-connection/LICENSE-APACHE b/packages/interface-connection/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-connection/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-connection/LICENSE-MIT b/packages/interface-connection/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-connection/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-connection/README.md b/packages/interface-connection/README.md new file mode 100644 index 0000000000..b2e2acc46f --- /dev/null +++ b/packages/interface-connection/README.md @@ -0,0 +1,315 @@ +# @libp2p/interface-connection + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Connection interface for libp2p + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [Connection](#connection) +- [Test suite](#test-suite) +- [API](#api) + - [Connection](#connection-1) + - [Creating a connection instance](#creating-a-connection-instance) + - [Create a new stream](#create-a-new-stream) + - [Add stream metadata](#add-stream-metadata) + - [Remove a from the registry](#remove-a-from-the-registry) + - [Close connection](#close-connection) + - [Connection identifier](#connection-identifier) + - [Connection streams registry](#connection-streams-registry) + - [Remote peer](#remote-peer) + - [Local peer](#local-peer) + - [Get the connection Streams](#get-the-connection-streams) + - [Remote address](#remote-address) + - [Local address](#local-address) + - [Stat](#stat) + - [Tags](#tags) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-connection +``` + +## Usage + +```js +import type { Connection } from '@libp2p/interface-connection' +``` + +This is a test suite and interface you can use to implement a connection. The connection interface contains all the metadata associated with it, as well as an array of the streams opened through this connection. In the same way as the connection, a stream contains properties with its metadata, plus an iterable duplex object that offers a mechanism for writing and reading data, with back pressure. This module and test suite were heavily inspired by abstract-blob-store and interface-stream-muxer. + +The primary goal of this module is to enable developers to pick, swap or upgrade their connection without losing the same API expectations and mechanisms such as back pressure and the ability to half close a connection. + +Publishing a test suite as a module lets multiple modules ensure compatibility since they use the same test suite. + +## Connection + +Before creating a connection from a transport compatible with `libp2p` it is important to understand some concepts: + +- **socket**: the underlying raw duplex connection between two nodes. It is created by the transports during a dial/listen. +- **[multiaddr connection](https://github.com/libp2p/interface-transport#multiaddrconnection)**: an abstraction over the socket to allow it to work with multiaddr addresses. It is a duplex connection that transports create to wrap the socket before passing to an upgrader that turns it into a standard connection (see below). +- **connection**: a connection between two *peers* that has built in multiplexing and info about the connected peer. It is created from a [multiaddr connection](https://github.com/libp2p/interface-transport#multiaddrconnection) by an upgrader. The upgrader uses multistream-select to add secio and multiplexing and returns this object. +- **stream**: a muxed duplex channel of the `connection`. Each connection may have many streams. + +A connection stands for the libp2p communication duplex layer between two nodes. It is **not** the underlying raw transport duplex layer (socket), such as a TCP socket, but an abstracted layer that sits on top of the raw socket. + +This helps ensuring that the transport is responsible for socket management, while also allowing the application layer to handle the connection management. + +## Test suite + +```js +const tests = require('@libp2p/interface-connection-compliance-tests') +describe('your connection', () => { + tests({ + // Options should be passed to your connection + async setup (options) { + return YourConnection + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## API + +### Connection + +A valid connection (one that follows this abstraction), must implement the following API: + +- type: `Connection` + +```js +new Connection({ + localAddr, + remoteAddr, + localPeer, + remotePeer, + newStream, + close, + getStreams, + stat: { + direction, + timeline: { + open, + upgraded + }, + multiplexer, + encryption + } +}) +``` + +- ` conn.localAddr` +- ` conn.remoteAddr` +- ` conn.localPeer` +- ` conn.remotePeer` +- ` conn.stat` +- ` conn.registry` +- `Array conn.streams` +- `Promise conn.newStream(Array)` +- ` conn.removeStream(id)` +- ` conn.addStream(stream, protocol, metadata)` +- `Promise<> conn.close()` + +It can be obtained as follows: + +```js +const { Connection } = require('interface-connection') + +const conn = new Connection({ + localAddr: maConn.localAddr, + remoteAddr: maConn.remoteAddr, + localPeer: this._peerId, + remotePeer, + newStream, + close: err => maConn.close(err), + getStreams, + stats: { + direction: 'outbound', + timeline: { + open: maConn.timeline.open, + upgraded: Date.now() + }, + multiplexer, + encryption + } +}) +``` + +#### Creating a connection instance + +- `JavaScript` - `const conn = new Connection({localAddr, remoteAddr, localPeer, remotePeer, newStream, close, getStreams, direction, multiplexer, encryption})` + +Creates a new Connection instance. + +`localAddr` is the optional [multiaddr](https://github.com/multiformats/multiaddr) address used by the local peer to reach the remote. +`remoteAddr` is the optional [multiaddr](https://github.com/multiformats/multiaddr) address used to communicate with the remote peer. +`localPeer` is the [PeerId](https://github.com/libp2p/js-peer-id) of the local peer. +`remotePeer` is the [PeerId](https://github.com/libp2p/js-peer-id) of the remote peer. +`newStream` is the `function` responsible for getting a new muxed+multistream-selected stream. +`close` is the `function` responsible for closing the raw connection. +`getStreams` is the `function` responsible for getting the streams muxed within the connection. +`stats` is an `object` with the metadata of the connection. It contains: + +- `direction` is a `string` indicating whether the connection is `inbound` or `outbound`. +- `timeline` is an `object` with the relevant events timestamps of the connection (`open`, `upgraded` and `closed`; the `closed` will be added when the connection is closed). +- `multiplexer` is a `string` with the connection multiplexing codec (optional). +- `encryption` is a `string` with the connection encryption method identifier (optional). +- `status` is a `string` indicating the overall status of the connection. It is one of \[`'open'`, `'closing'`, `'closed'`] + +#### Create a new stream + +- `JavaScript` - `conn.newStream(protocols)` + +Create a new stream within the connection. + +`protocols` is an array of the intended protocol to use (by order of preference). Example: `[/echo/1.0.0]` + +It returns a `Promise` with an object with the following properties: + +```js +{ + stream, + protocol +} +``` + +The stream property contains the muxed stream, while the protocol contains the protocol codec used by the stream. + +#### Add stream metadata + +- `JavaScript` - `conn.addStream(stream, { protocol, ...metadata })` + +Add a new stream to the connection registry. + +`stream` is a muxed stream. +`protocol` is the string codec for the protocol used by the stream. Example: `/echo/1.0.0` +`metadata` is an object containing any additional, optional, stream metadata that you wish to track (such as its `tags`). + +#### Remove a from the registry + +- `JavaScript` - `conn.removeStream(id)` + +Removes the stream with the given id from the connection registry. + +`id` is the unique id of the stream for this connection. + +#### Close connection + +- `JavaScript` - `conn.close()` + +This method closes the connection to the remote peer, as well as all the streams muxed within the connection. + +It returns a `Promise`. + +#### Connection identifier + +- `JavaScript` - `conn.id` + +This property contains the identifier of the connection. + +#### Connection streams registry + +- `JavaScript` - `conn.registry` + +This property contains a map with the muxed streams indexed by their id. This registry contains the protocol used by the stream, as well as its metadata. + +#### Remote peer + +- `JavaScript` - `conn.remotePeer` + +This property contains the remote `peer-id` of this connection. + +#### Local peer + +- `JavaScript` - `conn.localPeer` + +This property contains the local `peer-id` of this connection. + +#### Get the connection Streams + +- `JavaScript` - `conn.streams` + +This getter returns all the muxed streams within the connection. + +It returns an `Array`. + +#### Remote address + +- `JavaScript` - `conn.remoteAddr` + +This getter returns the `remote` [multiaddr](https://github.com/multiformats/multiaddr) address. + +#### Local address + +- `JavaScript` - `conn.localAddr` + +This getter returns the `local` [multiaddr](https://github.com/multiformats/multiaddr) address. + +#### Stat + +- `JavaScript` - `conn.stat` + +This getter returns an `Object` with the metadata of the connection, as follows: + +- `status`: + +This property contains the status of the connection. It can be either `open`, `closing` or `closed`. Once the connection is created it is in an `open` status. When a `conn.close()` happens, the status will change to `closing` and finally, after all the connection streams are properly closed, the status will be `closed`. These values can also be directly referenced by importing the `status` file: + +```js +const { + OPEN, CLOSING, CLOSED +} = require('libp2p-interfaces/src/connection/status') + +if (connection.stat.status === OPEN) { + // ... +} +``` + +- `timeline`: + +This property contains an object with the `open`, `upgraded` and `close` timestamps of the connection. Note that, the `close` timestamp is `undefined` until the connection is closed. + +- `direction`: + +This property contains the direction of the peer in the connection. It can be `inbound` or `outbound`. + +- `multiplexer`: + +This property contains the `multiplexing` codec being used in the connection. + +- `encryption`: + +This property contains the encryption method being used in the connection. It is `undefined` if the connection is not encrypted. + +#### Tags + +- `JavaScript` - `conn.tags` + +This property contains an array of tags associated with the connection. New tags can be pushed to this array during the connection's lifetime. + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-connection/img/badge.png b/packages/interface-connection/img/badge.png new file mode 100644 index 0000000000..a79ca44967 Binary files /dev/null and b/packages/interface-connection/img/badge.png differ diff --git a/packages/interface-connection/img/badge.sketch b/packages/interface-connection/img/badge.sketch new file mode 100644 index 0000000000..a4c4a438a2 Binary files /dev/null and b/packages/interface-connection/img/badge.sketch differ diff --git a/packages/interface-connection/img/badge.svg b/packages/interface-connection/img/badge.svg new file mode 100644 index 0000000000..a240ced76c --- /dev/null +++ b/packages/interface-connection/img/badge.svg @@ -0,0 +1,19 @@ + + + + badge + Created with Sketch. + + + + + + Connectio + n + + + Compatibl + e + + + \ No newline at end of file diff --git a/packages/interface-connection/package.json b/packages/interface-connection/package.json new file mode 100644 index 0000000000..96934ced1f --- /dev/null +++ b/packages/interface-connection/package.json @@ -0,0 +1,163 @@ +{ + "name": "@libp2p/interface-connection", + "version": "5.1.1", + "description": "Connection interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-connection#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ], + "src/*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ] + } + }, + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./status": { + "types": "./dist/src/status.d.ts", + "import": "./dist/src/status.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interfaces": "^3.0.0", + "@multiformats/multiaddr": "^12.0.0", + "it-stream-types": "^2.0.1", + "uint8arraylist": "^2.4.3" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-connection/src/index.ts b/packages/interface-connection/src/index.ts new file mode 100644 index 0000000000..ea5d9296d0 --- /dev/null +++ b/packages/interface-connection/src/index.ts @@ -0,0 +1,221 @@ +import type * as Status from './status.js' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { AbortOptions } from '@libp2p/interfaces' +import type { Multiaddr } from '@multiformats/multiaddr' +import type { Duplex, Source } from 'it-stream-types' +import type { Uint8ArrayList } from 'uint8arraylist' + +export interface ConnectionTimeline { + open: number + upgraded?: number + close?: number +} + +/** + * Outbound conections are opened by the local node, inbound streams are opened by the remote + */ +export type Direction = 'inbound' | 'outbound' + +export interface ConnectionStat { + /** + * Outbound conections are opened by the local node, inbound streams are opened by the remote + */ + direction: Direction + + /** + * Lifecycle times for the connection + */ + timeline: ConnectionTimeline + + /** + * Once a multiplexer has been negotiated for this stream, it will be set on the stat object + */ + multiplexer?: string + + /** + * Once a connection encrypter has been negotiated for this stream, it will be set on the stat object + */ + encryption?: string + + /** + * The current status of the connection + */ + status: keyof typeof Status +} + +export interface StreamTimeline { + /** + * A timestamp of when the stream was opened + */ + open: number + + /** + * A timestamp of when the stream was closed for both reading and writing + */ + close?: number + + /** + * A timestamp of when the stream was closed for reading + */ + closeRead?: number + + /** + * A timestamp of when the stream was closed for writing + */ + closeWrite?: number + + /** + * A timestamp of when the stream was reset + */ + reset?: number +} + +export interface StreamStat { + /** + * Outbound streams are opened by the local node, inbound streams are opened by the remote + */ + direction: Direction + + /** + * Lifecycle times for the stream + */ + timeline: StreamTimeline + + /** + * Once a protocol has been negotiated for this stream, it will be set on the stat object + */ + protocol?: string +} + +/** + * A Stream is a data channel between two peers that + * can be written to and read from at both ends. + * + * It may be encrypted and multiplexed depending on the + * configuration of the nodes. + */ +export interface Stream extends Duplex, Source, Promise> { + /** + * Closes the stream for **reading** *and* **writing**. + * + * Any buffered data in the source can still be consumed and the stream will end normally. + * + * This will cause a `CLOSE` message to be sent to the remote, *unless* the sink has already ended. + * + * The sink and the source will return normally. + */ + close: () => void + + /** + * Closes the stream for **reading**. If iterating over the source of this stream in a `for await of` loop, it will return (exit the loop) after any buffered data has been consumed. + * + * This function is called automatically by the muxer when it receives a `CLOSE` message from the remote. + * + * The source will return normally, the sink will continue to consume. + */ + closeRead: () => void + + /** + * Closes the stream for **writing**. If iterating over the source of this stream in a `for await of` loop, it will return (exit the loop) after any buffered data has been consumed. + * + * The source will return normally, the sink will continue to consume. + */ + closeWrite: () => void + + /** + * Closes the stream for **reading** *and* **writing**. This should be called when a *local error* has occurred. + * + * Note, if called without an error any buffered data in the source can still be consumed and the stream will end normally. + * + * This will cause a `RESET` message to be sent to the remote, *unless* the sink has already ended. + * + * The sink will return and the source will throw if an error is passed or return normally if not. + */ + abort: (err: Error) => void + + /** + * Closes the stream *immediately* for **reading** *and* **writing**. This should be called when a *remote error* has occurred. + * + * This function is called automatically by the muxer when it receives a `RESET` message from the remote. + * + * The sink will return and the source will throw. + */ + reset: () => void + + /** + * Unique identifier for a stream. Identifiers are not unique across muxers. + */ + id: string + + /** + * Stats about this stream + */ + stat: StreamStat + + /** + * User defined stream metadata + */ + metadata: Record +} + +export interface NewStreamOptions extends AbortOptions { + /** + * If specified, and no handler has been registered with the registrar for the + * successfully negotiated protocol, use this as the max outbound stream limit + * for the protocol + */ + maxOutboundStreams?: number +} + +/** + * A Connection is a high-level representation of a connection + * to a remote peer that may have been secured by encryption and + * multiplexed, depending on the configuration of the nodes + * between which the connection is made. + */ +export interface Connection { + id: string + stat: ConnectionStat + remoteAddr: Multiaddr + remotePeer: PeerId + tags: string[] + streams: Stream[] + + newStream: (multicodecs: string | string[], options?: NewStreamOptions) => Promise + addStream: (stream: Stream) => void + removeStream: (id: string) => void + close: () => Promise +} + +export const symbol = Symbol.for('@libp2p/connection') + +export function isConnection (other: any): other is Connection { + return other != null && Boolean(other[symbol]) +} + +export interface ConnectionProtector { + + /** + * Takes a given Connection and creates a private encryption stream + * between its two peers from the PSK the Protector instance was + * created with. + */ + protect: (connection: MultiaddrConnection) => Promise +} + +export interface MultiaddrConnectionTimeline { + open: number + upgraded?: number + close?: number +} + +/** + * A MultiaddrConnection is returned by transports after dialing + * a peer. It is a low-level primitive and is the raw connection + * without encryption or stream multiplexing. + */ +export interface MultiaddrConnection extends Duplex, Source, Promise> { + close: (err?: Error) => Promise + remoteAddr: Multiaddr + timeline: MultiaddrConnectionTimeline +} diff --git a/packages/interface-connection/src/status.ts b/packages/interface-connection/src/status.ts new file mode 100644 index 0000000000..a640d97e03 --- /dev/null +++ b/packages/interface-connection/src/status.ts @@ -0,0 +1,4 @@ + +export const OPEN = 'OPEN' +export const CLOSING = 'CLOSING' +export const CLOSED = 'CLOSED' diff --git a/packages/interface-connection/tsconfig.json b/packages/interface-connection/tsconfig.json new file mode 100644 index 0000000000..22a45bf0b5 --- /dev/null +++ b/packages/interface-connection/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-id" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-content-routing/CHANGELOG.md b/packages/interface-content-routing/CHANGELOG.md new file mode 100644 index 0000000000..a2a789a7c3 --- /dev/null +++ b/packages/interface-content-routing/CHANGELOG.md @@ -0,0 +1,111 @@ +## [@libp2p/interface-content-routing-v2.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v2.1.0...@libp2p/interface-content-routing-v2.1.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-content-routing-v2.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v2.0.2...@libp2p/interface-content-routing-v2.1.0) (2023-04-27) + + +### Features + +* add routing symbols ([#388](https://github.com/libp2p/js-libp2p-interfaces/issues/388)) ([9ee7691](https://github.com/libp2p/js-libp2p-interfaces/commit/9ee76915d2b8298d99557e105c4f71d585e97e7d)) + +## [@libp2p/interface-content-routing-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v2.0.1...@libp2p/interface-content-routing-v2.0.2) (2023-03-08) + + +### Documentation + +* update content/peer routing interface comments ([#346](https://github.com/libp2p/js-libp2p-interfaces/issues/346)) ([8080944](https://github.com/libp2p/js-libp2p-interfaces/commit/8080944d3c3a81834c6b432843441996cd9e34e5)) + +## [@libp2p/interface-content-routing-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v2.0.0...@libp2p/interface-content-routing-v2.0.1) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-content-routing-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.7...@libp2p/interface-content-routing-v2.0.0) (2023-01-06) + + +### ⚠ BREAKING CHANGES + +* bump multiformats from 10.0.3 to 11.0.0 (#329) + +### Dependencies + +* bump multiformats from 10.0.3 to 11.0.0 ([#329](https://github.com/libp2p/js-libp2p-interfaces/issues/329)) ([ba3a98b](https://github.com/libp2p/js-libp2p-interfaces/commit/ba3a98be61e3cf0996fefbd3004e974bb41ad2f0)) + +## [@libp2p/interface-content-routing-v1.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.6...@libp2p/interface-content-routing-v1.0.7) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-content-routing-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.5...@libp2p/interface-content-routing-v1.0.6) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-content-routing-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.4...@libp2p/interface-content-routing-v1.0.5) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-content-routing-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.3...@libp2p/interface-content-routing-v1.0.4) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-content-routing-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.2...@libp2p/interface-content-routing-v1.0.3) (2022-10-12) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* bump multiformats from 9.9.0 to 10.0.0 ([#302](https://github.com/libp2p/js-libp2p-interfaces/issues/302)) ([fe11d69](https://github.com/libp2p/js-libp2p-interfaces/commit/fe11d69b6aca3dd6ef6053bec27b534ec9908aa1)) + +## [@libp2p/interface-content-routing-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.1...@libp2p/interface-content-routing-v1.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-content-routing-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-content-routing-v1.0.0...@libp2p/interface-content-routing-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* **release:** 1.0.0 [skip ci] ([1211753](https://github.com/libp2p/js-libp2p-interfaces/commit/121175364dc47cd683bee7bc40b645f193f33528)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) [#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234) [#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233) + +## @libp2p/interface-content-routing-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) +* release [skip ci] ([357286d](https://github.com/libp2p/js-libp2p-interfaces/commit/357286df899899cf7a94348aeb8dd7387f7acad5)) +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) diff --git a/packages/interface-content-routing/LICENSE b/packages/interface-content-routing/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-content-routing/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-content-routing/LICENSE-APACHE b/packages/interface-content-routing/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-content-routing/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-content-routing/LICENSE-MIT b/packages/interface-content-routing/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-content-routing/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-content-routing/README.md b/packages/interface-content-routing/README.md new file mode 100644 index 0000000000..489d9b5a64 --- /dev/null +++ b/packages/interface-content-routing/README.md @@ -0,0 +1,100 @@ +# @libp2p/interface-content-routing + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Content routing interface for libp2p + +## Table of contents + +- - [Install](#install) +- [Modules that implement the interface](#modules-that-implement-the-interface) +- [Badge](#badge) +- [How to use the battery of tests](#how-to-use-the-battery-of-tests) + - [Node.js](#nodejs) +- [API](#api) + - - [findProviders](#findproviders) + - [provide](#provide) + - [API Docs](#api-docs) + - [License](#license) + - [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-content-routing +``` + +The primary goal of this module is to enable developers to pick and swap their Content Routing module as they see fit for their libp2p installation, without having to go through shims or compatibility issues. This module and test suite were heavily inspired by abstract-blob-store and interface-stream-muxer. + +Publishing a test suite as a module lets multiple modules all ensure compatibility since they use the same test suite. + +# Modules that implement the interface + +- [JavaScript libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) +- [JavaScript libp2p-delegated-content-routing](https://github.com/libp2p/js-libp2p-delegated-content-routing) + +# Badge + +Include this badge in your readme if you make a module that is compatible with the interface-content-routing API. You can validate this by running the tests. + +![](img/badge.png) + +# How to use the battery of tests + +## Node.js + +TBD + +# API + +A valid (read: that follows this abstraction) Content Routing module must implement the following API. + +### findProviders + +- `findProviders(cid)` + +Find peers in the network that can provide a specific value, given a key. + +**Parameters** + +- [CID](https://github.com/multiformats/js-cid) + +**Returns** + +It returns an `AsyncIterable` containing the identification and addresses of the peers providing the given key, as follows: + +`AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>` + +### provide + +- `provide(cid)` + +Announce to the network that we are providing the given value. + +**Parameters** + +- [CID](https://github.com/multiformats/js-cid) + +**Returns** + +It returns a promise that is resolved on the success of the operation. + +`Promise` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-content-routing/img/badge.png b/packages/interface-content-routing/img/badge.png new file mode 100644 index 0000000000..07f73279b5 Binary files /dev/null and b/packages/interface-content-routing/img/badge.png differ diff --git a/packages/interface-content-routing/img/badge.sketch b/packages/interface-content-routing/img/badge.sketch new file mode 100644 index 0000000000..985a835db6 Binary files /dev/null and b/packages/interface-content-routing/img/badge.sketch differ diff --git a/packages/interface-content-routing/img/badge.svg b/packages/interface-content-routing/img/badge.svg new file mode 100644 index 0000000000..43b16d1579 --- /dev/null +++ b/packages/interface-content-routing/img/badge.svg @@ -0,0 +1,25 @@ + + + + badge + Created with Sketch. + + + + + + + + + + Content Routin + g + + + Compatibl + e + + + + + \ No newline at end of file diff --git a/packages/interface-content-routing/package.json b/packages/interface-content-routing/package.json new file mode 100644 index 0000000000..56f6a2983a --- /dev/null +++ b/packages/interface-content-routing/package.json @@ -0,0 +1,141 @@ +{ + "name": "@libp2p/interface-content-routing", + "version": "2.1.1", + "description": "Content routing interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-content-routing#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-info": "^1.0.0", + "@libp2p/interfaces": "^3.0.0", + "multiformats": "^11.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-content-routing/src/index.ts b/packages/interface-content-routing/src/index.ts new file mode 100644 index 0000000000..c22bd19edb --- /dev/null +++ b/packages/interface-content-routing/src/index.ts @@ -0,0 +1,83 @@ +import type { PeerInfo } from '@libp2p/interface-peer-info' +import type { AbortOptions } from '@libp2p/interfaces' +import type { CID } from 'multiformats/cid' + +/** + * Any object that implements this Symbol as a property should return a + * ContentRouting instance as the property value, similar to how + * `Symbol.Iterable` can be used to return an `Iterable` from an `Iterator`. + * + * @example + * + * ```js + * import { contentRouting, ContentRouting } from '@libp2p/content-routing' + * + * class MyContentRouter implements ContentRouting { + * get [contentRouting] () { + * return this + * } + * + * // ...other methods + * } + * ``` + */ +export const contentRouting = Symbol.for('@libp2p/content-routing') + +export interface ContentRouting { + /** + * The implementation of this method should ensure that network peers know the + * caller can provide content that corresponds to the passed CID. + * + * @example + * + * ```js + * // ... + * await contentRouting.provide(cid) + * ``` + */ + provide: (cid: CID, options?: AbortOptions) => Promise + + /** + * Find the providers of the passed CID. + * + * @example + * + * ```js + * // Iterate over the providers found for the given cid + * for await (const provider of contentRouting.findProviders(cid)) { + * console.log(provider.id, provider.multiaddrs) + * } + * ``` + */ + findProviders: (cid: CID, options?: AbortOptions) => AsyncIterable + + /** + * Puts a value corresponding to the passed key in a way that can later be + * retrieved by another network peer using the get method. + * + * @example + * + * ```js + * // ... + * const key = '/key' + * const value = uint8ArrayFromString('oh hello there') + * + * await contentRouting.put(key, value) + * ``` + */ + put: (key: Uint8Array, value: Uint8Array, options?: AbortOptions) => Promise + + /** + * Retrieves a value from the network corresponding to the passed key. + * + * @example + * + * ```js + * // ... + * + * const key = '/key' + * const value = await contentRouting.get(key) + * ``` + */ + get: (key: Uint8Array, options?: AbortOptions) => Promise +} diff --git a/packages/interface-content-routing/tsconfig.json b/packages/interface-content-routing/tsconfig.json new file mode 100644 index 0000000000..84bbd0ffe3 --- /dev/null +++ b/packages/interface-content-routing/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-info" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-dht/CHANGELOG.md b/packages/interface-dht/CHANGELOG.md new file mode 100644 index 0000000000..71d1f444e1 --- /dev/null +++ b/packages/interface-dht/CHANGELOG.md @@ -0,0 +1,77 @@ +## [@libp2p/interface-dht-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v2.0.2...@libp2p/interface-dht-v2.0.3) (2023-05-04) + + +### Dependencies + +* update sibling dependencies ([45cf513](https://github.com/libp2p/js-libp2p-interfaces/commit/45cf513090d2a069bb6752ad2e231df65c76df36)) + +## [@libp2p/interface-dht-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v2.0.1...@libp2p/interface-dht-v2.0.2) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-dht-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v2.0.0...@libp2p/interface-dht-v2.0.1) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-dht-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v1.0.5...@libp2p/interface-dht-v2.0.0) (2023-01-06) + + +### ⚠ BREAKING CHANGES + +* bump multiformats from 10.0.3 to 11.0.0 (#329) + +### Dependencies + +* bump multiformats from 10.0.3 to 11.0.0 ([#329](https://github.com/libp2p/js-libp2p-interfaces/issues/329)) ([ba3a98b](https://github.com/libp2p/js-libp2p-interfaces/commit/ba3a98be61e3cf0996fefbd3004e974bb41ad2f0)) +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-dht-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v1.0.4...@libp2p/interface-dht-v1.0.5) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-dht-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v1.0.3...@libp2p/interface-dht-v1.0.4) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-dht-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v1.0.2...@libp2p/interface-dht-v1.0.3) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-dht-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v1.0.1...@libp2p/interface-dht-v1.0.2) (2022-10-12) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* bump multiformats from 9.9.0 to 10.0.0 ([#302](https://github.com/libp2p/js-libp2p-interfaces/issues/302)) ([fe11d69](https://github.com/libp2p/js-libp2p-interfaces/commit/fe11d69b6aca3dd6ef6053bec27b534ec9908aa1)) + +## [@libp2p/interface-dht-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-dht-v1.0.0...@libp2p/interface-dht-v1.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) diff --git a/packages/interface-dht/LICENSE b/packages/interface-dht/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-dht/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-dht/LICENSE-APACHE b/packages/interface-dht/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-dht/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-dht/LICENSE-MIT b/packages/interface-dht/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-dht/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-dht/README.md b/packages/interface-dht/README.md new file mode 100644 index 0000000000..917812c917 --- /dev/null +++ b/packages/interface-dht/README.md @@ -0,0 +1,36 @@ +# @libp2p/interface-dht + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> DHT interface for libp2p + +## Table of contents + +- [Install](#install) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-dht +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-dht/package.json b/packages/interface-dht/package.json new file mode 100644 index 0000000000..36deae40a0 --- /dev/null +++ b/packages/interface-dht/package.json @@ -0,0 +1,143 @@ +{ + "name": "@libp2p/interface-dht", + "version": "2.0.3", + "description": "DHT interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-dht#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-discovery": "^2.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interface-peer-info": "^1.0.0", + "@libp2p/interfaces": "^3.0.0", + "multiformats": "^11.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-dht/src/index.ts b/packages/interface-dht/src/index.ts new file mode 100644 index 0000000000..25f46a7d79 --- /dev/null +++ b/packages/interface-dht/src/index.ts @@ -0,0 +1,211 @@ +import type { PeerDiscovery } from '@libp2p/interface-peer-discovery' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { PeerInfo } from '@libp2p/interface-peer-info' +import type { AbortOptions } from '@libp2p/interfaces' +import type { CID } from 'multiformats/cid' + +/** + * The types of events emitted during DHT queries + */ +export enum EventTypes { + SENDING_QUERY = 0, + PEER_RESPONSE, + FINAL_PEER, + QUERY_ERROR, + PROVIDER, + VALUE, + ADDING_PEER, + DIALING_PEER +} + +/** + * The types of messages sent to peers during DHT queries + */ +export enum MessageType { + PUT_VALUE = 0, + GET_VALUE, + ADD_PROVIDER, + GET_PROVIDERS, + FIND_NODE, + PING +} + +export type MessageName = keyof typeof MessageType + +export interface DHTRecord { + key: Uint8Array + value: Uint8Array + timeReceived?: Date +} + +export interface QueryOptions extends AbortOptions { + queryFuncTimeout?: number +} + +/** + * Emitted when sending queries to remote peers + */ +export interface SendingQueryEvent { + to: PeerId + type: EventTypes.SENDING_QUERY + name: 'SENDING_QUERY' + messageName: keyof typeof MessageType + messageType: MessageType +} + +/** + * Emitted when query responses are received form remote peers. Depending on the query + * these events may be followed by a `FinalPeerEvent`, a `ValueEvent` or a `ProviderEvent`. + */ +export interface PeerResponseEvent { + from: PeerId + type: EventTypes.PEER_RESPONSE + name: 'PEER_RESPONSE' + messageName: keyof typeof MessageType + messageType: MessageType + closer: PeerInfo[] + providers: PeerInfo[] + record?: DHTRecord +} + +/** + * Emitted at the end of a `findPeer` query + */ +export interface FinalPeerEvent { + from: PeerId + peer: PeerInfo + type: EventTypes.FINAL_PEER + name: 'FINAL_PEER' +} + +/** + * Something went wrong with the query + */ +export interface QueryErrorEvent { + from: PeerId + type: EventTypes.QUERY_ERROR + name: 'QUERY_ERROR' + error: Error +} + +/** + * Emitted when providers are found + */ +export interface ProviderEvent { + from: PeerId + type: EventTypes.PROVIDER + name: 'PROVIDER' + providers: PeerInfo[] +} + +/** + * Emitted when values are found + */ +export interface ValueEvent { + from: PeerId + type: EventTypes.VALUE + name: 'VALUE' + value: Uint8Array +} + +/** + * Emitted when peers are added to a query + */ +export interface AddingPeerEvent { + type: EventTypes.ADDING_PEER + name: 'ADDING_PEER' + peer: PeerId +} + +/** + * Emitted when peers are dialled as part of a query + */ +export interface DialingPeerEvent { + peer: PeerId + type: EventTypes.DIALING_PEER + name: 'DIALING_PEER' +} + +export type QueryEvent = SendingQueryEvent | PeerResponseEvent | FinalPeerEvent | QueryErrorEvent | ProviderEvent | ValueEvent | AddingPeerEvent | DialingPeerEvent + +export interface RoutingTable { + size: number +} + +export interface DHT extends PeerDiscovery { + /** + * Get a value from the DHT, the final ValueEvent will be the best value + */ + get: (key: Uint8Array, options?: QueryOptions) => AsyncIterable + + /** + * Find providers of a given CID + */ + findProviders: (key: CID, options?: QueryOptions) => AsyncIterable + + /** + * Find a peer on the DHT + */ + findPeer: (id: PeerId, options?: QueryOptions) => AsyncIterable + + /** + * Find the closest peers to the passed key + */ + getClosestPeers: (key: Uint8Array, options?: QueryOptions) => AsyncIterable + + /** + * Store provider records for the passed CID on the DHT pointing to us + */ + provide: (key: CID, options?: QueryOptions) => AsyncIterable + + /** + * Store the passed value under the passed key on the DHT + */ + put: (key: Uint8Array, value: Uint8Array, options?: QueryOptions) => AsyncIterable + + /** + * Returns the mode this node is in + */ + getMode: () => Promise<'client' | 'server'> + + /** + * If 'server' this node will respond to DHT queries, if 'client' this node will not + */ + setMode: (mode: 'client' | 'server') => Promise + + /** + * Force a routing table refresh + */ + refreshRoutingTable: () => Promise +} + +export interface SingleDHT extends DHT { + routingTable: RoutingTable +} + +export interface DualDHT extends DHT { + wan: SingleDHT + lan: SingleDHT +} + +/** + * A selector function takes a DHT key and a list of records and returns the + * index of the best record in the list + */ +export interface SelectFn { (key: Uint8Array, records: Uint8Array[]): number } + +/** + * A validator function takes a DHT key and the value of the record for that key + * and throws if the record is invalid + */ +export interface ValidateFn { (key: Uint8Array, value: Uint8Array): Promise } + +/** + * Selectors are a map of key prefixes to selector functions + */ +export type Selectors = Record + +/** + * Validators are a map of key prefixes to validator functions + */ +export type Validators = Record diff --git a/packages/interface-dht/tsconfig.json b/packages/interface-dht/tsconfig.json new file mode 100644 index 0000000000..29f2945683 --- /dev/null +++ b/packages/interface-dht/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-discovery" + }, + { + "path": "../interface-peer-id" + }, + { + "path": "../interface-peer-info" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-keychain/CHANGELOG.md b/packages/interface-keychain/CHANGELOG.md new file mode 100644 index 0000000000..f94cdbd62f --- /dev/null +++ b/packages/interface-keychain/CHANGELOG.md @@ -0,0 +1,122 @@ +## [@libp2p/interface-keychain-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v2.0.4...@libp2p/interface-keychain-v2.0.5) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-keychain-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v2.0.3...@libp2p/interface-keychain-v2.0.4) (2023-01-27) + + +### Bug Fixes + +* add missing method to keychain interface to rotate password ([#340](https://github.com/libp2p/js-libp2p-interfaces/issues/340)) ([db60895](https://github.com/libp2p/js-libp2p-interfaces/commit/db60895f9b86f627b1cb5c1bcabff69398e34b93)) + +## [@libp2p/interface-keychain-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v2.0.2...@libp2p/interface-keychain-v2.0.3) (2023-01-18) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-keychain-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v2.0.1...@libp2p/interface-keychain-v2.0.2) (2023-01-18) + + +### Bug Fixes + +* add exportPeer method to keychain interface ([#337](https://github.com/libp2p/js-libp2p-interfaces/issues/337)) ([a970939](https://github.com/libp2p/js-libp2p-interfaces/commit/a970939ee685c1fd8ba2121e04f8a7cff5b953ca)) + +## [@libp2p/interface-keychain-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v2.0.0...@libp2p/interface-keychain-v2.0.1) (2023-01-07) + + +### Bug Fixes + +* add importPeer method to keychain interface ([#333](https://github.com/libp2p/js-libp2p-interfaces/issues/333)) ([51de73c](https://github.com/libp2p/js-libp2p-interfaces/commit/51de73c85f72151d1b9e5f3248d757512d40659b)) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + +## [@libp2p/interface-keychain-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.8...@libp2p/interface-keychain-v2.0.0) (2023-01-06) + + +### ⚠ BREAKING CHANGES + +* bump multiformats from 10.0.3 to 11.0.0 (#329) + +### Dependencies + +* bump multiformats from 10.0.3 to 11.0.0 ([#329](https://github.com/libp2p/js-libp2p-interfaces/issues/329)) ([ba3a98b](https://github.com/libp2p/js-libp2p-interfaces/commit/ba3a98be61e3cf0996fefbd3004e974bb41ad2f0)) + +## [@libp2p/interface-keychain-v1.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.7...@libp2p/interface-keychain-v1.0.8) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-keychain-v1.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.6...@libp2p/interface-keychain-v1.0.7) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-keychain-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.5...@libp2p/interface-keychain-v1.0.6) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-keychain-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.4...@libp2p/interface-keychain-v1.0.5) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-keychain-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.3...@libp2p/interface-keychain-v1.0.4) (2022-10-12) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* bump multiformats from 9.9.0 to 10.0.0 ([#302](https://github.com/libp2p/js-libp2p-interfaces/issues/302)) ([fe11d69](https://github.com/libp2p/js-libp2p-interfaces/commit/fe11d69b6aca3dd6ef6053bec27b534ec9908aa1)) + +## [@libp2p/interface-keychain-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.2...@libp2p/interface-keychain-v1.0.3) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-keychain-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.1...@libp2p/interface-keychain-v1.0.2) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) + +## [@libp2p/interface-keychain-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keychain-v1.0.0...@libp2p/interface-keychain-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-keychain-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-keychain/LICENSE b/packages/interface-keychain/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-keychain/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-keychain/LICENSE-APACHE b/packages/interface-keychain/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-keychain/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-keychain/LICENSE-MIT b/packages/interface-keychain/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-keychain/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-keychain/README.md b/packages/interface-keychain/README.md new file mode 100644 index 0000000000..5906ebc6bf --- /dev/null +++ b/packages/interface-keychain/README.md @@ -0,0 +1,100 @@ +# @libp2p/interface-keychain + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Keychain interface for libp2p + +## Table of contents + +- - [Install](#install) +- [Modules that implement the interface](#modules-that-implement-the-interface) +- [Badge](#badge) +- [How to use the battery of tests](#how-to-use-the-battery-of-tests) + - [Node.js](#nodejs) +- [API](#api) + - - [findProviders](#findproviders) + - [provide](#provide) + - [API Docs](#api-docs) + - [License](#license) + - [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-keychain +``` + +The primary goal of this module is to enable developers to pick and swap their Content Routing module as they see fit for their libp2p installation, without having to go through shims or compatibility issues. This module and test suite were heavily inspired by abstract-blob-store and interface-stream-muxer. + +Publishing a test suite as a module lets multiple modules all ensure compatibility since they use the same test suite. + +# Modules that implement the interface + +- [JavaScript libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) +- [JavaScript libp2p-delegated-content-routing](https://github.com/libp2p/js-libp2p-delegated-content-routing) + +# Badge + +Include this badge in your readme if you make a module that is compatible with the interface-content-routing API. You can validate this by running the tests. + +![](img/badge.png) + +# How to use the battery of tests + +## Node.js + +TBD + +# API + +A valid (read: that follows this abstraction) Content Routing module must implement the following API. + +### findProviders + +- `findProviders(cid)` + +Find peers in the network that can provide a specific value, given a key. + +**Parameters** + +- [CID](https://github.com/multiformats/js-cid) + +**Returns** + +It returns an `AsyncIterable` containing the identification and addresses of the peers providing the given key, as follows: + +`AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>` + +### provide + +- `provide(cid)` + +Announce to the network that we are providing the given value. + +**Parameters** + +- [CID](https://github.com/multiformats/js-cid) + +**Returns** + +It returns a promise that is resolved on the success of the operation. + +`Promise` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-keychain/package.json b/packages/interface-keychain/package.json new file mode 100644 index 0000000000..12d971d1c6 --- /dev/null +++ b/packages/interface-keychain/package.json @@ -0,0 +1,140 @@ +{ + "name": "@libp2p/interface-keychain", + "version": "2.0.5", + "description": "Keychain interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-keychain#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-id": "^2.0.0", + "multiformats": "^11.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-keychain/src/index.ts b/packages/interface-keychain/src/index.ts new file mode 100644 index 0000000000..1c71ea5b0b --- /dev/null +++ b/packages/interface-keychain/src/index.ts @@ -0,0 +1,168 @@ +/** + * @packageDocumentation + * + * The libp2p keychain provides an API to store keys in a datastore in + * an encrypted format. + * + * @example + * + * ```typescript + * import { createLibp2p } from 'libp2p' + * import { FsDatastore } from 'datastore-fs' + * + * const node = await createLibp2p({ + * datastore: new FsDatastore('/path/to/dir') + * }) + * + * const info = await node.keychain.createKey('my-new-key', 'Ed25519') + * + * console.info(info) // { id: '...', name: 'my-new-key' } + * ``` + */ + +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Multibase } from 'multiformats/bases/interface' + +export interface KeyInfo { + /** + * The universally unique key id + */ + id: string + + /** + * The local key name + */ + name: string +} + +export type KeyType = 'RSA' | 'Ed25519' | 'secp256k1' + +export interface KeyChain { + /** + * Export an existing key as a PEM encrypted PKCS #8 string. + * + * @example + * + * ```js + * await libp2p.keychain.createKey('keyTest', 'RSA', 4096) + * const pemKey = await libp2p.keychain.exportKey('keyTest', 'password123') + * ``` + */ + exportKey: (name: string, password: string) => Promise> + + /** + * Import a new key from a PEM encoded PKCS #8 string. + * + * @example + * + * ```js + * await libp2p.keychain.createKey('keyTest', 'RSA', 4096) + * const pemKey = await libp2p.keychain.exportKey('keyTest', 'password123') + * const keyInfo = await libp2p.keychain.importKey('keyTestImport', pemKey, 'password123') + * ``` + */ + importKey: (name: string, pem: string, password: string) => Promise + + /** + * Import a new key from a PeerId with a private key component + * + * @example + * + * ```js + * const keyInfo = await libp2p.keychain.importPeer('keyTestImport', peerIdFromString('12D3Foo...')) + * ``` + */ + importPeer: (name: string, peerId: PeerId) => Promise + + /** + * Export an existing key as a PeerId + * + * @example + * + * ```js + * const peerId = await libp2p.keychain.exportPeerId('key-name') + * ``` + */ + exportPeerId: (name: string) => Promise + + /** + * Create a key in the keychain. + * + * @example + * + * ```js + * const keyInfo = await libp2p.keychain.createKey('keyTest', 'RSA', 4096) + * ``` + */ + createKey: (name: string, type: KeyType, size?: number) => Promise + + /** + * List all the keys. + * + * @example + * + * ```js + * const keyInfos = await libp2p.keychain.listKeys() + * ``` + */ + listKeys: () => Promise + + /** + * Removes a key from the keychain. + * + * @example + * + * ```js + * await libp2p.keychain.createKey('keyTest', 'RSA', 4096) + * const keyInfo = await libp2p.keychain.removeKey('keyTest') + * ``` + */ + removeKey: (name: string) => Promise + + /** + * Rename a key in the keychain. + * + * @example + * + * ```js + * await libp2p.keychain.createKey('keyTest', 'RSA', 4096) + * const keyInfo = await libp2p.keychain.renameKey('keyTest', 'keyNewNtest') + * ``` + */ + renameKey: (oldName: string, newName: string) => Promise + + /** + * Find a key by it's id. + * + * @example + * + * ```js + * const keyInfo = await libp2p.keychain.createKey('keyTest', 'RSA', 4096) + * const keyInfo2 = await libp2p.keychain.findKeyById(keyInfo.id) + * ``` + */ + findKeyById: (id: string) => Promise + + /** + * Find a key by it's name. + * + * @example + * + * ```js + * const keyInfo = await libp2p.keychain.createKey('keyTest', 'RSA', 4096) + * const keyInfo2 = await libp2p.keychain.findKeyByName('keyTest') + * ``` + */ + findKeyByName: (name: string) => Promise + + /** + * Rotate keychain password and re-encrypt all associated keys + * + * @example + * + * ```js + * await libp2p.keychain.rotateKeychainPass('oldPassword', 'newPassword') + * ``` + */ + rotateKeychainPass: (oldPass: string, newPass: string) => Promise +} diff --git a/packages/interface-keychain/tsconfig.json b/packages/interface-keychain/tsconfig.json new file mode 100644 index 0000000000..d8db0b667f --- /dev/null +++ b/packages/interface-keychain/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-keys/CHANGELOG.md b/packages/interface-keys/CHANGELOG.md new file mode 100644 index 0000000000..f2f84f5302 --- /dev/null +++ b/packages/interface-keys/CHANGELOG.md @@ -0,0 +1,76 @@ +## [@libp2p/interface-keys-v1.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.7...@libp2p/interface-keys-v1.0.8) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-keys-v1.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.6...@libp2p/interface-keys-v1.0.7) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-keys-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.5...@libp2p/interface-keys-v1.0.6) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-keys-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.4...@libp2p/interface-keys-v1.0.5) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-keys-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.3...@libp2p/interface-keys-v1.0.4) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-keys-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.2...@libp2p/interface-keys-v1.0.3) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-keys-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.1...@libp2p/interface-keys-v1.0.2) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) + +## [@libp2p/interface-keys-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-keys-v1.0.0...@libp2p/interface-keys-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-keys-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-keys/LICENSE b/packages/interface-keys/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-keys/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-keys/LICENSE-APACHE b/packages/interface-keys/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-keys/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-keys/LICENSE-MIT b/packages/interface-keys/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-keys/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-keys/README.md b/packages/interface-keys/README.md new file mode 100644 index 0000000000..227c3c2702 --- /dev/null +++ b/packages/interface-keys/README.md @@ -0,0 +1,56 @@ +# @libp2p/interface-keys + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Keys interface for libp2p + +## Table of contents + +- [Install](#install) +- [Using the Test Suite](#using-the-test-suite) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-keys +``` + +## Using the Test Suite + +You can also check out the [internal test suite](../../test/crypto/compliance.spec.js) to see the setup in action. + +```js +const tests = require('libp2p-interfaces-compliance-tests/keys') +const yourKeys = require('./your-keys') + +tests({ + setup () { + // Set up your keys if needed, then return it + return yourKeys + }, + teardown () { + // Clean up your keys if needed + } +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-keys/package.json b/packages/interface-keys/package.json new file mode 100644 index 0000000000..2767047daf --- /dev/null +++ b/packages/interface-keys/package.json @@ -0,0 +1,136 @@ +{ + "name": "@libp2p/interface-keys", + "version": "1.0.8", + "description": "Keys interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-keys#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-keys/src/index.ts b/packages/interface-keys/src/index.ts new file mode 100644 index 0000000000..a201e0487b --- /dev/null +++ b/packages/interface-keys/src/index.ts @@ -0,0 +1,38 @@ + +export interface PublicKey { + readonly bytes: Uint8Array + verify: (data: Uint8Array, sig: Uint8Array) => Promise + marshal: () => Uint8Array + equals: (key: PublicKey) => boolean + hash: () => Promise +} + +/** + * Generic private key interface + */ +export interface PrivateKey { + readonly public: PublicKey + readonly bytes: Uint8Array + sign: (data: Uint8Array) => Promise + marshal: () => Uint8Array + equals: (key: PrivateKey) => boolean + hash: () => Promise + /** + * Gets the ID of the key. + * + * The key id is the base58 encoding of the SHA-256 multihash of its public key. + * The public key is a protobuf encoding containing a type and the DER encoding + * of the PKCS SubjectPublicKeyInfo. + */ + id: () => Promise + /** + * Exports the password protected key in the format specified. + */ + export: (password: string, format?: 'pkcs-8' | string) => Promise +} + +export const Ed25519 = 'Ed25519' +export const RSA = 'RSA' +export const secp256k1 = 'secp256k1' + +export type KeyType = typeof Ed25519 | typeof RSA | typeof secp256k1 diff --git a/packages/interface-keys/tsconfig.json b/packages/interface-keys/tsconfig.json new file mode 100644 index 0000000000..5fe8ea40d7 --- /dev/null +++ b/packages/interface-keys/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ] +} diff --git a/packages/interface-libp2p/CHANGELOG.md b/packages/interface-libp2p/CHANGELOG.md new file mode 100644 index 0000000000..1c294f09b8 --- /dev/null +++ b/packages/interface-libp2p/CHANGELOG.md @@ -0,0 +1,235 @@ +## [@libp2p/interface-libp2p-v3.2.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v3.1.0...@libp2p/interface-libp2p-v3.2.0) (2023-05-19) + + +### Features + +* add start/stop events to libp2p interface ([#407](https://github.com/libp2p/js-libp2p-interfaces/issues/407)) ([016c1e8](https://github.com/libp2p/js-libp2p-interfaces/commit/016c1e82b060c93c80546cd8c493ec6e6c97cbec)) + +## [@libp2p/interface-libp2p-v3.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v3.0.1...@libp2p/interface-libp2p-v3.1.0) (2023-05-05) + + +### Features + +* add peer:identify event to libp2p ([#395](https://github.com/libp2p/js-libp2p-interfaces/issues/395)) ([6aee82a](https://github.com/libp2p/js-libp2p-interfaces/commit/6aee82ad81a752f204ec27838ccd6de4908aeb0e)) + +## [@libp2p/interface-libp2p-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v3.0.0...@libp2p/interface-libp2p-v3.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-libp2p-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v2.0.0...@libp2p/interface-libp2p-v3.0.0) (2023-04-27) + + +### ⚠ BREAKING CHANGES + +* pubsub, dht, ping, fetch and identify have been removed - re-enable these by passing them as services + +### Features + +* allow user defined services ([#375](https://github.com/libp2p/js-libp2p-interfaces/issues/375)) ([13cf442](https://github.com/libp2p/js-libp2p-interfaces/commit/13cf442ff29acbe28cf75431dee02bfefd9a4e40)) + + +### Documentation + +* fix typos in docs ([#386](https://github.com/libp2p/js-libp2p-interfaces/issues/386)) ([8ec2cdc](https://github.com/libp2p/js-libp2p-interfaces/commit/8ec2cdcc5deed76e0c673a75c27bf7a2e931eea1)) + +## [@libp2p/interface-libp2p-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.3.2...@libp2p/interface-libp2p-v2.0.0) (2023-04-21) + + +### ⚠ BREAKING CHANGES + +* add libp2p events (#373) + +### Features + +* add libp2p events ([#373](https://github.com/libp2p/js-libp2p-interfaces/issues/373)) ([071c718](https://github.com/libp2p/js-libp2p-interfaces/commit/071c718808902858818ca86167b51b242b67a5a5)) + + +### Dependencies + +* update sibling dependencies ([17ed429](https://github.com/libp2p/js-libp2p-interfaces/commit/17ed429d57e83cb38484ac52a0e0975a7d8af963)) +* update sibling dependencies ([4421374](https://github.com/libp2p/js-libp2p-interfaces/commit/4421374d85ac7d4e9cf0b1a4c5072e881e091b31)) + +## [@libp2p/interface-libp2p-v1.3.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.3.1...@libp2p/interface-libp2p-v1.3.2) (2023-04-21) + + +### Dependencies + +* update sibling dependencies ([bc1588c](https://github.com/libp2p/js-libp2p-interfaces/commit/bc1588c70ffa35c1ba9c954090a7ac8087a22b0c)) + +## [@libp2p/interface-libp2p-v1.3.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.3.0...@libp2p/interface-libp2p-v1.3.1) (2023-04-18) + + +### Dependencies + +* update sibling dependencies ([3d23367](https://github.com/libp2p/js-libp2p-interfaces/commit/3d233676a17299bfa1b59d309543598176826523)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-libp2p-v1.3.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.2.0...@libp2p/interface-libp2p-v1.3.0) (2023-04-17) + + +### Features + +* expose dial queue inspection method ([#374](https://github.com/libp2p/js-libp2p-interfaces/issues/374)) ([973263f](https://github.com/libp2p/js-libp2p-interfaces/commit/973263f582d39a5b727c9fd90abeea7ed72a9aff)) + +## [@libp2p/interface-libp2p-v1.2.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.1.2...@libp2p/interface-libp2p-v1.2.0) (2023-04-11) + + +### Features + +* support batch dialling ([#351](https://github.com/libp2p/js-libp2p-interfaces/issues/351)) ([e46b72b](https://github.com/libp2p/js-libp2p-interfaces/commit/e46b72b1731ff935a1f0d755cbaf6f3159060ed3)) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-libp2p-v1.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.1.1...@libp2p/interface-libp2p-v1.1.2) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-libp2p-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.1.0...@libp2p/interface-libp2p-v1.1.1) (2023-01-18) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-libp2p-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.0.2...@libp2p/interface-libp2p-v1.1.0) (2023-01-07) + + +### Features + +* add register and unregister methods to libp2p type ([#332](https://github.com/libp2p/js-libp2p-interfaces/issues/332)) ([e37c55a](https://github.com/libp2p/js-libp2p-interfaces/commit/e37c55a62b1b4a927996ca9ea2a311651640de7f)) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + +## [@libp2p/interface-libp2p-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.0.1...@libp2p/interface-libp2p-v1.0.2) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([acf0058](https://github.com/libp2p/js-libp2p-interfaces/commit/acf0058696e343f3330e63e45a85a520424d0bd8)) +* update sibling dependencies ([29515c6](https://github.com/libp2p/js-libp2p-interfaces/commit/29515c65f84203cdbdd5f5562acc0e8cbbda6664)) +* update sibling dependencies ([b599221](https://github.com/libp2p/js-libp2p-interfaces/commit/b599221d9044a0c573bac40c57e70a842930b253)) +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-libp2p-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-libp2p-v1.0.0...@libp2p/interface-libp2p-v1.0.1) (2022-12-21) + + +### Bug Fixes + +* add getProtocols method, events, and identify service ([#326](https://github.com/libp2p/js-libp2p-interfaces/issues/326)) ([b036505](https://github.com/libp2p/js-libp2p-interfaces/commit/b036505100d32742065190e47d1803cbd8f61f4a)) + +## @libp2p/interface-libp2p-v1.0.0 (2022-12-19) + + +### Features + +* add libp2p interface ([#325](https://github.com/libp2p/js-libp2p-interfaces/issues/325)) ([79a474d](https://github.com/libp2p/js-libp2p-interfaces/commit/79a474d8eda95ad3ff3bcdb2a15bfcf778f51772)) + +## [@libp2p/interface-metrics-v4.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.3...@libp2p/interface-metrics-v4.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-metrics-v4.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.2...@libp2p/interface-metrics-v4.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-metrics-v4.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.1...@libp2p/interface-metrics-v4.0.2) (2022-11-05) + + +### Bug Fixes + +* metrics only need numbers ([#312](https://github.com/libp2p/js-libp2p-interfaces/issues/312)) ([0076c1f](https://github.com/libp2p/js-libp2p-interfaces/commit/0076c1f354ebc1106b6ac42d48688c0209866084)) + +## [@libp2p/interface-metrics-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.0...@libp2p/interface-metrics-v4.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-metrics-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v3.0.0...@libp2p/interface-metrics-v4.0.0) (2022-11-05) + + +### ⚠ BREAKING CHANGES + +* the global/per-peer moving average tracking has been removed from the interface as it's expensive and requires lots of timers - this functionality can be replicated by implementations if it's desirable. It's better to have simple counters instead and let an external system like Prometheus or Graphana calculate the values over time + +### Features + +* return metrics objects from register instead of updating with an options object ([#310](https://github.com/libp2p/js-libp2p-interfaces/issues/310)) ([3b106ce](https://github.com/libp2p/js-libp2p-interfaces/commit/3b106ce799b5d84a82a66238995e09970ed8116c)) + +## [@libp2p/interface-metrics-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v2.0.0...@libp2p/interface-metrics-v3.0.0) (2022-08-07) + + +### ⚠ BREAKING CHANGES + +* change stream muxer interface (#279) + +### Features + +* change stream muxer interface ([#279](https://github.com/libp2p/js-libp2p-interfaces/issues/279)) ([1ebe269](https://github.com/libp2p/js-libp2p-interfaces/commit/1ebe26988b6a286f36a4fc5177f502cfb60368a1)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-metrics-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.3...@libp2p/interface-metrics-v2.0.0) (2022-07-01) + + +### ⚠ BREAKING CHANGES + +* the return type of `metrics.getComponentMetrics` has been changed to include optional labels/help text and also is now a function that returns a single or group value + +### Features + +* add metrics groups ([#267](https://github.com/libp2p/js-libp2p-interfaces/issues/267)) ([b9d898a](https://github.com/libp2p/js-libp2p-interfaces/commit/b9d898abdb551ebe2e0e961ec325d5e6abcf4fab)), closes [#257](https://github.com/libp2p/js-libp2p-interfaces/issues/257) [#258](https://github.com/libp2p/js-libp2p-interfaces/issues/258) + +## [@libp2p/interface-metrics-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.2...@libp2p/interface-metrics-v1.0.3) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-metrics-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.1...@libp2p/interface-metrics-v1.0.2) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) + +## [@libp2p/interface-metrics-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.0...@libp2p/interface-metrics-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-metrics-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-libp2p/LICENSE b/packages/interface-libp2p/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-libp2p/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-libp2p/LICENSE-APACHE b/packages/interface-libp2p/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-libp2p/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-libp2p/LICENSE-MIT b/packages/interface-libp2p/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-libp2p/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-libp2p/README.md b/packages/interface-libp2p/README.md new file mode 100644 index 0000000000..80044041ec --- /dev/null +++ b/packages/interface-libp2p/README.md @@ -0,0 +1,36 @@ +# @libp2p/interface-libp2p + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> The interface implemented by a libp2p node + +## Table of contents + +- [Install](#install) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-libp2p +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-libp2p/package.json b/packages/interface-libp2p/package.json new file mode 100644 index 0000000000..5178f5a138 --- /dev/null +++ b/packages/interface-libp2p/package.json @@ -0,0 +1,150 @@ +{ + "name": "@libp2p/interface-libp2p", + "version": "3.2.0", + "description": "The interface implemented by a libp2p node", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-libp2p#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-content-routing": "^2.0.0", + "@libp2p/interface-keychain": "^2.0.0", + "@libp2p/interface-metrics": "^4.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interface-peer-info": "^1.0.0", + "@libp2p/interface-peer-routing": "^1.0.0", + "@libp2p/interface-peer-store": "^2.0.0", + "@libp2p/interface-registrar": "^2.0.0", + "@libp2p/interface-transport": "^4.0.0", + "@libp2p/interfaces": "^3.0.0", + "@multiformats/multiaddr": "^12.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-libp2p/src/index.ts b/packages/interface-libp2p/src/index.ts new file mode 100644 index 0000000000..3e0a606cae --- /dev/null +++ b/packages/interface-libp2p/src/index.ts @@ -0,0 +1,599 @@ +/** + * @packageDocumentation + * + * Exports a `Libp2p` type for modules to use as a type argument. + * + * @example + * + * ```typescript + * import type { Libp2p } from '@libp2p/interface-libp2p' + * + * function doSomethingWithLibp2p (node: Libp2p) { + * // ... + * } + * ``` + */ + +import type { Connection, Stream } from '@libp2p/interface-connection' +import type { ContentRouting } from '@libp2p/interface-content-routing' +import type { KeyChain } from '@libp2p/interface-keychain' +import type { Metrics } from '@libp2p/interface-metrics' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { PeerInfo } from '@libp2p/interface-peer-info' +import type { PeerRouting } from '@libp2p/interface-peer-routing' +import type { Address, Peer, PeerStore } from '@libp2p/interface-peer-store' +import type { StreamHandler, StreamHandlerOptions, Topology } from '@libp2p/interface-registrar' +import type { Listener } from '@libp2p/interface-transport' +import type { AbortOptions } from '@libp2p/interfaces' +import type { EventEmitter } from '@libp2p/interfaces/events' +import type { Startable } from '@libp2p/interfaces/startable' +import type { Multiaddr } from '@multiformats/multiaddr' + +/** + * Used by the connection manager to sort addresses into order before dialling + */ +export interface AddressSorter { + (a: Address, b: Address): -1 | 0 | 1 +} + +/** + * Event detail emitted when peer data changes + */ +export interface PeerUpdate { + peer: Peer + previous?: Peer +} + +/** + * Peer data signed by the remote Peer's public key + */ +export interface SignedPeerRecord { + addresses: Multiaddr[] + seq: bigint +} + +/** + * Data returned from a successful identify response + */ +export interface IdentifyResult { + /** + * The remote Peer's PeerId + */ + peerId: PeerId + + /** + * The unsigned addresses they are listening on. Note - any multiaddrs present + * in the signed peer record should be preferred to the value here. + */ + listenAddrs: Multiaddr[] + + /** + * The protocols the remote peer supports + */ + protocols: string[] + + /** + * The remote protocol version + */ + protocolVersion?: string + + /** + * The remote agent version + */ + agentVersion?: string + + /** + * The public key part of the remote PeerId - this is only useful for older + * RSA-based PeerIds, the more modern Ed25519 and secp256k1 types have the + * public key embedded in them + */ + publicKey?: Uint8Array + + /** + * If set this is the address that the remote peer saw the identify request + * originate from + */ + observedAddr?: Multiaddr + + /** + * If sent by the remote peer this is the deserialized signed peer record + */ + signedPeerRecord?: SignedPeerRecord +} + +/** + * Once you have a libp2p instance, you can listen to several events it emits, + * so that you can be notified of relevant network events. + * + * Event names are `noun:verb` so the first part is the name of the object + * being acted on and the second is the action. + */ +export interface Libp2pEvents { + /** + * This event is dispatched when a new network peer is discovered. + * + * @example + * + * ```js + * libp2p.addEventListener('peer:discovery', (event) => { + * const peerInfo = event.detail + * // ... + * }) + * ``` + */ + 'peer:discovery': CustomEvent + + /** + * This event will be triggered any time a new peer connects. + * + * @example + * + * ```js + * libp2p.addEventListener('peer:connect', (event) => { + * const peerId = event.detail + * // ... + * }) + * ``` + */ + 'peer:connect': CustomEvent + + /** + * This event will be triggered any time we are disconnected from another peer, regardless of + * the circumstances of that disconnection. If we happen to have multiple connections to a + * peer, this event will **only** be triggered when the last connection is closed. + * + * @example + * + * ```js + * libp2p.addEventListener('peer:disconnect', (event) => { + * const peerId = event.detail + * // ... + * }) + * ``` + */ + 'peer:disconnect': CustomEvent + + /** + * This event is dispatched after a remote peer has successfully responded to the identify + * protocol. Note that for this to be emitted, both peers must have an identify service + * configured. + * + * @example + * + * ```js + * libp2p.addEventListener('peer:identify', (event) => { + * const identifyResult = event.detail + * // ... + * }) + * ``` + */ + 'peer:identify': CustomEvent + + /** + * This event is dispatched when the peer store data for a peer has been + * updated - e.g. their multiaddrs, protocols etc have changed. + * + * If they were previously known to this node, the old peer data will be + * set in the `previous` field. + * + * This may be in response to the identify protocol running, a manual + * update or some other event. + */ + 'peer:update': CustomEvent + + /** + * This event is dispatched when the current node's peer record changes - + * for example a transport started listening on a new address or a new + * protocol handler was registered. + * + * @example + * + * ```js + * libp2p.addEventListener('self:peer:update', (event) => { + * const { peer } = event.detail + * // ... + * }) + * ``` + */ + 'self:peer:update': CustomEvent + + /** + * This event is dispatched when a transport begins listening on a new address + */ + 'transport:listening': CustomEvent + + /** + * This event is dispatched when a transport stops listening on an address + */ + 'transport:close': CustomEvent + + /** + * This event is dispatched when the connection manager has more than the + * configured allowable max connections and has closed some connections to + * bring the node back under the limit. + */ + 'connection:prune': CustomEvent + + /** + * This event notifies listeners when new incoming or outgoing connections + * are opened. + */ + 'connection:open': CustomEvent + + /** + * This event notifies listeners when incoming or outgoing connections are + * closed. + */ + 'connection:close': CustomEvent + + /** + * This event notifies listeners that the node has started + * + * ```js + * libp2p.addEventListener('start', (event) => { + * console.info(libp2p.isStarted()) // true + * }) + * ``` + */ + 'start': CustomEvent> + + /** + * This event notifies listeners that the node has stopped + * + * ```js + * libp2p.addEventListener('stop', (event) => { + * console.info(libp2p.isStarted()) // false + * }) + * ``` + */ + 'stop': CustomEvent> +} + +/** + * A map of user defined services available on the libp2p node via the + * `services` key + * + * @example + * + * ```js + * const node = await createLibp2p({ + * // ...other options + * services: { + * myService: myService({ + * // ...service options + * }) + * } + * }) + * + * // invoke methods on the service + * node.services.myService.anOperation() + * ``` + */ +export type ServiceMap = Record + +export type PendingDialStatus = 'queued' | 'active' | 'error' | 'success' + +/** + * An item in the dial queue + */ +export interface PendingDial { + /** + * A unique identifier for this dial + */ + id: string + + /** + * The current status of the dial + */ + status: PendingDialStatus + + /** + * If known, this is the peer id that libp2p expects to be dialling + */ + peerId?: PeerId + + /** + * The list of multiaddrs that will be dialled. The returned connection will + * use the first address that succeeds, all other dials part of this pending + * dial will be cancelled. + */ + multiaddrs: Multiaddr[] +} + +/** + * Libp2p nodes implement this interface. + */ +export interface Libp2p extends Startable, EventEmitter> { + /** + * The PeerId is a unique identifier for a node on the network. + * + * It is the hash of an RSA public key or, for Ed25519 or secp256k1 keys, + * the key itself. + * + * @example + * + * ```js + * console.info(libp2p.peerId) + * // PeerId(12D3Foo...) + * ```` + */ + peerId: PeerId + + /** + * The peer store holds information we know about other peers on the network. + * - multiaddrs, supported protocols, etc. + * + * @example + * + * ```js + * const peer = await libp2p.peerStore.get(peerId) + * console.info(peer) + * // { id: PeerId(12D3Foo...), addresses: [] ... } + * ``` + */ + peerStore: PeerStore + + /** + * The peer routing subsystem allows the user to find peers on the network + * or to find peers close to binary keys. + * + * @example + * + * ```js + * const peerInfo = await libp2p.peerRouting.findPeer(peerId) + * console.info(peerInfo) + * // { id: PeerId(12D3Foo...), multiaddrs: [] ... } + * ``` + * + * @example + * + * ```js + * for await (const peerInfo of libp2p.peerRouting.getClosestPeers(key)) { + * console.info(peerInfo) + * // { id: PeerId(12D3Foo...), multiaddrs: [] ... } + * } + * ``` + */ + peerRouting: PeerRouting + + /** + * The content routing subsystem allows the user to find providers for content, + * let the network know they are providers for content, and get/put values to + * the DHT. + * + * @example + * + * ```js + * for await (const peerInfo of libp2p.contentRouting.findProviders(cid)) { + * console.info(peerInfo) + * // { id: PeerId(12D3Foo...), multiaddrs: [] ... } + * } + * ``` + */ + contentRouting: ContentRouting + + /** + * The keychain contains the keys used by the current node, and can create new + * keys, export them, import them, etc. + * + * @example + * + * ```js + * const keyInfo = await libp2p.keychain.createKey('new key') + * console.info(keyInfo) + * // { id: '...', name: 'new key' } + * ``` + */ + keychain: KeyChain + + /** + * The metrics subsystem allows recording values to assess the health/performance + * of the running node. + * + * @example + * + * ```js + * const metric = libp2p.metrics.registerMetric({ + * 'my-metric' + * }) + * + * // later + * metric.update(5) + * ``` + */ + metrics?: Metrics + + /** + * Get a deduplicated list of peer advertising multiaddrs by concatenating + * the listen addresses used by transports with any configured + * announce addresses as well as observed addresses reported by peers. + * + * If Announce addrs are specified, configured listen addresses will be + * ignored though observed addresses will still be included. + * + * @example + * + * ```js + * const listenMa = libp2p.getMultiaddrs() + * // [ ] + * ``` + */ + getMultiaddrs: () => Multiaddr[] + + /** + * Returns a list of supported protocols + * + * @example + * + * ```js + * const protocols = libp2p.getProtocols() + * // [ '/ipfs/ping/1.0.0', '/ipfs/id/1.0.0' ] + * ``` + */ + getProtocols: () => string[] + + /** + * Return a list of all connections this node has open, optionally filtering + * by a PeerId + * + * @example + * + * ```js + * for (const connection of libp2p.getConnections()) { + * console.log(peerId, connection.remoteAddr.toString()) + * // Logs the PeerId string and the observed remote multiaddr of each Connection + * } + * ``` + */ + getConnections: (peerId?: PeerId) => Connection[] + + /** + * Return the list of dials currently in progress or queued to start + * + * @example + * + * ```js + * for (const pendingDial of libp2p.getDialQueue()) { + * console.log(pendingDial) + * } + * ``` + */ + getDialQueue: () => PendingDial[] + + /** + * Return a list of all peers we currently have a connection open to + */ + getPeers: () => PeerId[] + + /** + * Dials to the provided peer. If successful, the known metadata of the + * peer will be added to the nodes `peerStore`. + * + * If a PeerId is passed as the first argument, the peer will need to have known multiaddrs for it in the PeerStore. + * + * @example + * + * ```js + * const conn = await libp2p.dial(remotePeerId) + * + * // create a new stream within the connection + * const { stream, protocol } = await conn.newStream(['/echo/1.1.0', '/echo/1.0.0']) + * + * // protocol negotiated: 'echo/1.0.0' means that the other party only supports the older version + * + * // ... + * await conn.close() + * ``` + */ + dial: (peer: PeerId | Multiaddr | Multiaddr[], options?: AbortOptions) => Promise + + /** + * Dials to the provided peer and tries to handshake with the given protocols in order. + * If successful, the known metadata of the peer will be added to the nodes `peerStore`, + * and the `MuxedStream` will be returned together with the successful negotiated protocol. + * + * @example + * + * ```js + * import { pipe } from 'it-pipe' + * + * const { stream, protocol } = await libp2p.dialProtocol(remotePeerId, protocols) + * + * // Use this new stream like any other duplex stream + * pipe([1, 2, 3], stream, consume) + * ``` + */ + dialProtocol: (peer: PeerId | Multiaddr | Multiaddr[], protocols: string | string[], options?: AbortOptions) => Promise + + /** + * Attempts to gracefully close an open connection to the given peer. If the connection is not closed in the grace period, it will be forcefully closed. + * + * @example + * + * ```js + * await libp2p.hangUp(remotePeerId) + * ``` + */ + hangUp: (peer: PeerId | Multiaddr) => Promise + + /** + * Sets up [multistream-select routing](https://github.com/multiformats/multistream-select) of protocols to their application handlers. Whenever a stream is opened on one of the provided protocols, the handler will be called. `handle` must be called in order to register a handler and support for a given protocol. This also informs other peers of the protocols you support. + * + * `libp2p.handle(protocols, handler, options)` + * + * In the event of a new handler for the same protocol being added, the first one is discarded. + * + * @example + * + * ```js + * const handler = ({ connection, stream, protocol }) => { + * // use stream or connection according to the needs + * } + * + * libp2p.handle('/echo/1.0.0', handler, { + * maxInboundStreams: 5, + * maxOutboundStreams: 5 + * }) + * ``` + */ + handle: (protocol: string | string[], handler: StreamHandler, options?: StreamHandlerOptions) => Promise + + /** + * Removes the handler for each protocol. The protocol + * will no longer be supported on streams. + * + * @example + * + * ```js + * libp2p.unhandle(['/echo/1.0.0']) + * ``` + */ + unhandle: (protocols: string[] | string) => Promise + + /** + * Register a topology to be informed when peers are encountered that + * support the specified protocol + * + * @example + * + * ```js + * import { createTopology } from '@libp2p/topology' + * + * const id = await libp2p.register('/echo/1.0.0', createTopology({ + * onConnect: (peer, connection) => { + * // handle connect + * }, + * onDisconnect: (peer, connection) => { + * // handle disconnect + * } + * })) + * ``` + */ + register: (protocol: string, topology: Topology) => Promise + + /** + * Unregister topology to no longer be informed when peers connect or + * disconnect. + * + * @example + * + * ```js + * const id = await libp2p.register(...) + * + * libp2p.unregister(id) + * ``` + */ + unregister: (id: string) => void + + /** + * Returns the public key for the passed PeerId. If the PeerId is of the 'RSA' type + * this may mean searching the DHT if the key is not present in the KeyStore. + * A set of user defined services + */ + getPublicKey: (peer: PeerId, options?: AbortOptions) => Promise + + /** + * A set of user defined services + */ + services: T +} diff --git a/packages/interface-libp2p/tsconfig.json b/packages/interface-libp2p/tsconfig.json new file mode 100644 index 0000000000..141be663e3 --- /dev/null +++ b/packages/interface-libp2p/tsconfig.json @@ -0,0 +1,44 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interface-content-routing" + }, + { + "path": "../interface-keychain" + }, + { + "path": "../interface-metrics" + }, + { + "path": "../interface-peer-id" + }, + { + "path": "../interface-peer-info" + }, + { + "path": "../interface-peer-routing" + }, + { + "path": "../interface-peer-store" + }, + { + "path": "../interface-registrar" + }, + { + "path": "../interface-transport" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-metrics/CHANGELOG.md b/packages/interface-metrics/CHANGELOG.md new file mode 100644 index 0000000000..387c1c4b68 --- /dev/null +++ b/packages/interface-metrics/CHANGELOG.md @@ -0,0 +1,130 @@ +## [@libp2p/interface-metrics-v4.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.7...@libp2p/interface-metrics-v4.0.8) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-metrics-v4.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.6...@libp2p/interface-metrics-v4.0.7) (2023-04-18) + + +### Dependencies + +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-metrics-v4.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.5...@libp2p/interface-metrics-v4.0.6) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-metrics-v4.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.4...@libp2p/interface-metrics-v4.0.5) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-metrics-v4.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.3...@libp2p/interface-metrics-v4.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-metrics-v4.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.2...@libp2p/interface-metrics-v4.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-metrics-v4.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.1...@libp2p/interface-metrics-v4.0.2) (2022-11-05) + + +### Bug Fixes + +* metrics only need numbers ([#312](https://github.com/libp2p/js-libp2p-interfaces/issues/312)) ([0076c1f](https://github.com/libp2p/js-libp2p-interfaces/commit/0076c1f354ebc1106b6ac42d48688c0209866084)) + +## [@libp2p/interface-metrics-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v4.0.0...@libp2p/interface-metrics-v4.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-metrics-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v3.0.0...@libp2p/interface-metrics-v4.0.0) (2022-11-05) + + +### ⚠ BREAKING CHANGES + +* the global/per-peer moving average tracking has been removed from the interface as it's expensive and requires lots of timers - this functionality can be replicated by implementations if it's desirable. It's better to have simple counters instead and let an external system like Prometheus or Graphana calculate the values over time + +### Features + +* return metrics objects from register instead of updating with an options object ([#310](https://github.com/libp2p/js-libp2p-interfaces/issues/310)) ([3b106ce](https://github.com/libp2p/js-libp2p-interfaces/commit/3b106ce799b5d84a82a66238995e09970ed8116c)) + +## [@libp2p/interface-metrics-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v2.0.0...@libp2p/interface-metrics-v3.0.0) (2022-08-07) + + +### ⚠ BREAKING CHANGES + +* change stream muxer interface (#279) + +### Features + +* change stream muxer interface ([#279](https://github.com/libp2p/js-libp2p-interfaces/issues/279)) ([1ebe269](https://github.com/libp2p/js-libp2p-interfaces/commit/1ebe26988b6a286f36a4fc5177f502cfb60368a1)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-metrics-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.3...@libp2p/interface-metrics-v2.0.0) (2022-07-01) + + +### ⚠ BREAKING CHANGES + +* the return type of `metrics.getComponentMetrics` has been changed to include optional labels/help text and also is now a function that returns a single or group value + +### Features + +* add metrics groups ([#267](https://github.com/libp2p/js-libp2p-interfaces/issues/267)) ([b9d898a](https://github.com/libp2p/js-libp2p-interfaces/commit/b9d898abdb551ebe2e0e961ec325d5e6abcf4fab)), closes [#257](https://github.com/libp2p/js-libp2p-interfaces/issues/257) [#258](https://github.com/libp2p/js-libp2p-interfaces/issues/258) + +## [@libp2p/interface-metrics-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.2...@libp2p/interface-metrics-v1.0.3) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-metrics-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.1...@libp2p/interface-metrics-v1.0.2) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) + +## [@libp2p/interface-metrics-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-metrics-v1.0.0...@libp2p/interface-metrics-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-metrics-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-metrics/LICENSE b/packages/interface-metrics/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-metrics/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-metrics/LICENSE-APACHE b/packages/interface-metrics/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-metrics/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-metrics/LICENSE-MIT b/packages/interface-metrics/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-metrics/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-metrics/README.md b/packages/interface-metrics/README.md new file mode 100644 index 0000000000..39ddd7192e --- /dev/null +++ b/packages/interface-metrics/README.md @@ -0,0 +1,41 @@ +# @libp2p/interface-metrics + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Metrics interface for libp2p + +## Table of contents + +- [Install](#install) +- [Implementations](#implementations) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-metrics +``` + +## Implementations + +- [@libp2p/prometheus-metrics](https://github.com/libp2p/js-libp2p-prometheus-metrics) + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-metrics/package.json b/packages/interface-metrics/package.json new file mode 100644 index 0000000000..a96e776b71 --- /dev/null +++ b/packages/interface-metrics/package.json @@ -0,0 +1,139 @@ +{ + "name": "@libp2p/interface-metrics", + "version": "4.0.8", + "description": "Metrics interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-metrics#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-metrics/src/index.ts b/packages/interface-metrics/src/index.ts new file mode 100644 index 0000000000..eaa89ca775 --- /dev/null +++ b/packages/interface-metrics/src/index.ts @@ -0,0 +1,187 @@ +import type { MultiaddrConnection, Stream, Connection } from '@libp2p/interface-connection' + +/** + * Create tracked metrics with these options. Loosely based on the + * interfaces exposed by the prom-client module + */ +export interface MetricOptions { + /** + * Optional label for the metric + */ + label?: string + + /** + * Optional help for the metric + */ + help?: string +} + +/** + * A function that returns a tracked metric which may be expensive + * to calculate so it is only invoked when metrics are being scraped + */ +export type CalculateMetric = (() => T) | (() => Promise) + +/** + * Create tracked metrics that are expensive to calculate by passing + * a function that is only invoked when metrics are being scraped + */ +export interface CalculatedMetricOptions extends MetricOptions { + /** + * An optional function invoked to calculate the component metric instead of + * using `.update`, `.increment`, and `.decrement` + */ + calculate: CalculateMetric +} + +/** + * Call this function to stop the timer returned from the `.timer` method + * on the metric + */ +export interface StopTimer { (): void } + +/** + * A tracked metric loosely based on the interfaces exposed by the + * prom-client module + */ +export interface Metric { + /** + * Update the stored metric to the passed value + */ + update: (value: number) => void + + /** + * Increment the metric by the passed value or 1 + */ + increment: (value?: number) => void + + /** + * Decrement the metric by the passed value or 1 + */ + decrement: (value?: number) => void + + /** + * Reset this metric to its default value + */ + reset: () => void + + /** + * Start a timed metric, call the returned function to + * stop the timer + */ + timer: () => StopTimer +} + +/** + * A group of related metrics loosely based on the interfaces exposed by the + * prom-client module + */ +export interface MetricGroup { + /** + * Update the stored metric group to the passed value + */ + update: (values: Record) => void + + /** + * Increment the metric group keys by the passed number or + * any non-numeric value to increment by 1 + */ + increment: (values: Record) => void + + /** + * Decrement the metric group keys by the passed number or + * any non-numeric value to decrement by 1 + */ + decrement: (values: Record) => void + + /** + * Reset the passed key in this metric group to its default value + * or all keys if no key is passed + */ + reset: () => void + + /** + * Start a timed metric for the named key in the group, call + * the returned function to stop the timer + */ + timer: (key: string) => StopTimer +} + +/** + * A tracked counter loosely based on the Counter interface exposed + * by the prom-client module - counters are metrics that only go up + */ +export interface Counter { + /** + * Increment the metric by the passed value or 1 + */ + increment: (value?: number) => void + + /** + * Reset this metric to its default value + */ + reset: () => void +} + +/** + * A group of tracked counters loosely based on the Counter interface + * exposed by the prom-client module - counters are metrics that only + * go up + */ +export interface CounterGroup { + /** + * Increment the metric group keys by the passed number or + * any non-numeric value to increment by 1 + */ + increment: (values: Record) => void + + /** + * Reset the passed key in this metric group to its default value + * or all keys if no key is passed + */ + reset: () => void +} + +/** + * The libp2p metrics tracking object. This interface is only concerned + * with the collection of metrics, please see the individual implementations + * for how to extract metrics for viewing. + */ +export interface Metrics { + /** + * Track a newly opened multiaddr connection + */ + trackMultiaddrConnection: (maConn: MultiaddrConnection) => void + + /** + * Track a newly opened protocol stream + */ + trackProtocolStream: (stream: Stream, connection: Connection) => void + + /** + * Register an arbitrary metric. Call this to set help/labels for metrics + * and update/increment/decrement/etc them by calling methods on the returned + * metric object + */ + registerMetric: ((name: string, options?: MetricOptions) => Metric) & ((name: string, options: CalculatedMetricOptions) => void) + + /** + * Register a a group of related metrics. Call this to set help/labels for + * groups of related metrics that will be updated with by calling `.update`, + * `.increment` and/or `.decrement` methods on the returned metric group object + */ + registerMetricGroup: ((name: string, options?: MetricOptions) => MetricGroup) & ((name: string, options: CalculatedMetricOptions>) => void) + + /** + * Register an arbitrary counter. Call this to set help/labels for counters + * and increment them by calling methods on the returned counter object + */ + registerCounter: ((name: string, options?: MetricOptions) => Counter) & ((name: string, options: CalculatedMetricOptions) => void) + + /** + * Register a a group of related counters. Call this to set help/labels for + * groups of related counters that will be updated with by calling the `.increment` + * method on the returned counter group object + */ + registerCounterGroup: ((name: string, options?: MetricOptions) => CounterGroup) & ((name: string, options: CalculatedMetricOptions>) => void) +} diff --git a/packages/interface-metrics/tsconfig.json b/packages/interface-metrics/tsconfig.json new file mode 100644 index 0000000000..01ca33094c --- /dev/null +++ b/packages/interface-metrics/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-connection" + } + ] +} diff --git a/packages/interface-mocks/CHANGELOG.md b/packages/interface-mocks/CHANGELOG.md new file mode 100644 index 0000000000..5a66070f58 --- /dev/null +++ b/packages/interface-mocks/CHANGELOG.md @@ -0,0 +1,1013 @@ +## [@libp2p/interface-mocks-v12.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v12.0.0...@libp2p/interface-mocks-v12.0.1) (2023-05-10) + + +### Bug Fixes + +* emit peer:connect events from mock connection manager ([#399](https://github.com/libp2p/js-libp2p-interfaces/issues/399)) ([836dcf3](https://github.com/libp2p/js-libp2p-interfaces/commit/836dcf3d0fbdd00686f662260940c5600db25c09)) + +## [@libp2p/interface-mocks-v12.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v11.0.3...@libp2p/interface-mocks-v12.0.0) (2023-05-04) + + +### ⚠ BREAKING CHANGES + +* the `symbol` export is now named `peerDiscovery` and the getter with that name should return an instance of `PeerDiscovery` + +### Features + +* rename peer discovery symbol to peerDiscovery ([#394](https://github.com/libp2p/js-libp2p-interfaces/issues/394)) ([5957c77](https://github.com/libp2p/js-libp2p-interfaces/commit/5957c77718df6e6336ca22386d8c03a045fd1d89)) + + +### Dependencies + +* update sibling dependencies ([45cf513](https://github.com/libp2p/js-libp2p-interfaces/commit/45cf513090d2a069bb6752ad2e231df65c76df36)) + +## [@libp2p/interface-mocks-v11.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v11.0.2...@libp2p/interface-mocks-v11.0.3) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-mocks-v11.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v11.0.1...@libp2p/interface-mocks-v11.0.2) (2023-04-27) + + +### Dependencies + +* update sibling dependencies ([6aa5ee8](https://github.com/libp2p/js-libp2p-interfaces/commit/6aa5ee87f9e431cabd4081cf8bc76b8f5180f344)) + +## [@libp2p/interface-mocks-v11.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v11.0.0...@libp2p/interface-mocks-v11.0.1) (2023-04-24) + + +### Bug Fixes + +* make events optional in mock upgrader ([#385](https://github.com/libp2p/js-libp2p-interfaces/issues/385)) ([51f4aae](https://github.com/libp2p/js-libp2p-interfaces/commit/51f4aaea6ab216a1f60b899ecc25b7a325de988d)) + +## [@libp2p/interface-mocks-v11.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v10.0.3...@libp2p/interface-mocks-v11.0.0) (2023-04-21) + + +### ⚠ BREAKING CHANGES + +* add libp2p events (#373) + +### Features + +* add libp2p events ([#373](https://github.com/libp2p/js-libp2p-interfaces/issues/373)) ([071c718](https://github.com/libp2p/js-libp2p-interfaces/commit/071c718808902858818ca86167b51b242b67a5a5)) + + +### Dependencies + +* update sibling dependencies ([a1b72f9](https://github.com/libp2p/js-libp2p-interfaces/commit/a1b72f90414536308befd07df2a003985951ceb7)) +* update sibling dependencies ([17ed429](https://github.com/libp2p/js-libp2p-interfaces/commit/17ed429d57e83cb38484ac52a0e0975a7d8af963)) +* update sibling dependencies ([6c18790](https://github.com/libp2p/js-libp2p-interfaces/commit/6c18790f6178053c69a8cd6bd289fd749d4e9633)) + +## [@libp2p/interface-mocks-v10.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v10.0.2...@libp2p/interface-mocks-v10.0.3) (2023-04-19) + + +### Bug Fixes + +* update mock duplex type ([#380](https://github.com/libp2p/js-libp2p-interfaces/issues/380)) ([5260314](https://github.com/libp2p/js-libp2p-interfaces/commit/52603142bc91aaeb192ebf9b3a7559e8a270b7bf)) + +## [@libp2p/interface-mocks-v10.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v10.0.1...@libp2p/interface-mocks-v10.0.2) (2023-04-18) + + +### Dependencies + +* update abortable iterator to 5.x.x ([#379](https://github.com/libp2p/js-libp2p-interfaces/issues/379)) ([d405e5b](https://github.com/libp2p/js-libp2p-interfaces/commit/d405e5b5db624d97f47588ef55c379debccfd160)) + +## [@libp2p/interface-mocks-v10.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v10.0.0...@libp2p/interface-mocks-v10.0.1) (2023-04-18) + + +### Bug Fixes + +* specify stream sink return type ([#378](https://github.com/libp2p/js-libp2p-interfaces/issues/378)) ([e0641fc](https://github.com/libp2p/js-libp2p-interfaces/commit/e0641fcc2f2a6562e7f7d8e064ebd98c5cc6dccb)) + +## [@libp2p/interface-mocks-v10.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.4.0...@libp2p/interface-mocks-v10.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) +* update sibling dependencies ([4972cc6](https://github.com/libp2p/js-libp2p-interfaces/commit/4972cc6c4c43319730305b58f329d6cf4591517a)) +* update sibling dependencies ([a5b7b33](https://github.com/libp2p/js-libp2p-interfaces/commit/a5b7b33dccee52d03fce788d2876a398d6fd6d99)) +* update sibling dependencies ([99a862b](https://github.com/libp2p/js-libp2p-interfaces/commit/99a862baed66d4e83ba006a70c33561855c9682e)) +* update sibling dependencies ([e95dcc2](https://github.com/libp2p/js-libp2p-interfaces/commit/e95dcc28f0a8b42457a44155eb0dfb3d813b03c8)) +* update sibling dependencies ([3d23367](https://github.com/libp2p/js-libp2p-interfaces/commit/3d233676a17299bfa1b59d309543598176826523)) +* update sibling dependencies ([2b9ddda](https://github.com/libp2p/js-libp2p-interfaces/commit/2b9ddda88d2655d389bf5142f7131f333ab9f780)) +* update sibling dependencies ([bed9f4c](https://github.com/libp2p/js-libp2p-interfaces/commit/bed9f4c7b7044e974a70678762a51e79e018cf9b)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-mocks-v9.4.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.3.4...@libp2p/interface-mocks-v9.4.0) (2023-04-14) + + +### Features + +* expose get connection map method of connection manager ([#372](https://github.com/libp2p/js-libp2p-interfaces/issues/372)) ([fc7245b](https://github.com/libp2p/js-libp2p-interfaces/commit/fc7245b63764562f5ec66a5a0ba334caea80ed66)) +* expose get dial queue method of connection manager ([#371](https://github.com/libp2p/js-libp2p-interfaces/issues/371)) ([0c407aa](https://github.com/libp2p/js-libp2p-interfaces/commit/0c407aa0772c171bf6650e31fb20a3433df40b6b)) + +## [@libp2p/interface-mocks-v9.3.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.3.3...@libp2p/interface-mocks-v9.3.4) (2023-04-14) + + +### Dependencies + +* update sibling dependencies ([34b1627](https://github.com/libp2p/js-libp2p-interfaces/commit/34b1627458b2ada5e94e00cf4bcba41a77232090)) + +## [@libp2p/interface-mocks-v9.3.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.3.2...@libp2p/interface-mocks-v9.3.3) (2023-04-14) + + +### Dependencies + +* update sibling dependencies ([3e743bb](https://github.com/libp2p/js-libp2p-interfaces/commit/3e743bba3d8ebd081907e74f02728a1e8476a147)) + +## [@libp2p/interface-mocks-v9.3.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.3.1...@libp2p/interface-mocks-v9.3.2) (2023-04-13) + + +### Dependencies + +* update any-signal to 4.x.x ([#369](https://github.com/libp2p/js-libp2p-interfaces/issues/369)) ([72be911](https://github.com/libp2p/js-libp2p-interfaces/commit/72be91176509f619e5d621463cb4ecc014fde0b7)) + +## [@libp2p/interface-mocks-v9.3.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.3.0...@libp2p/interface-mocks-v9.3.1) (2023-04-13) + + +### Dependencies + +* bump it-map from 2.0.1 to 3.0.2 ([#361](https://github.com/libp2p/js-libp2p-interfaces/issues/361)) ([c016269](https://github.com/libp2p/js-libp2p-interfaces/commit/c01626912eae85969bf2b1027b68a5242a4ae4d4)) + +## [@libp2p/interface-mocks-v9.3.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.2.4...@libp2p/interface-mocks-v9.3.0) (2023-04-11) + + +### Features + +* support batch dialling ([#351](https://github.com/libp2p/js-libp2p-interfaces/issues/351)) ([e46b72b](https://github.com/libp2p/js-libp2p-interfaces/commit/e46b72b1731ff935a1f0d755cbaf6f3159060ed3)) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-mocks-v9.2.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.2.3...@libp2p/interface-mocks-v9.2.4) (2023-04-04) + + +### Dependencies + +* bump it-pipe from 2.0.5 to 3.0.1 ([#363](https://github.com/libp2p/js-libp2p-interfaces/issues/363)) ([625817b](https://github.com/libp2p/js-libp2p-interfaces/commit/625817b0bbbee276983c40a0604c8810a25abe8f)) + +## [@libp2p/interface-mocks-v9.2.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.2.2...@libp2p/interface-mocks-v9.2.3) (2023-03-17) + + +### Bug Fixes + +* update project settings ([2aa4f95](https://github.com/libp2p/js-libp2p-interfaces/commit/2aa4f9583fb8ff9b53c51ebb6b81f72d69a1748d)) + +## [@libp2p/interface-mocks-v9.2.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.2.1...@libp2p/interface-mocks-v9.2.2) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-mocks-v9.2.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.2.0...@libp2p/interface-mocks-v9.2.1) (2023-03-10) + + +### Bug Fixes + +* filter closed connections properly ([#349](https://github.com/libp2p/js-libp2p-interfaces/issues/349)) ([21021c3](https://github.com/libp2p/js-libp2p-interfaces/commit/21021c366579db5b45b93ea4446118f32aca0428)) + +## [@libp2p/interface-mocks-v9.2.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.1.3...@libp2p/interface-mocks-v9.2.0) (2023-03-09) + + +### Features + +* split connection gater out into module ([#347](https://github.com/libp2p/js-libp2p-interfaces/issues/347)) ([1824744](https://github.com/libp2p/js-libp2p-interfaces/commit/18247442aa64c809d9e101ccbd0067ce48bdb80f)) + + +### Bug Fixes + +* update @libp2p/interface-connection-gater depdendency ([e53cf8b](https://github.com/libp2p/js-libp2p-interfaces/commit/e53cf8b26b83dcca553b934f171d07d817df15ca)) + + +### Dependencies + +* update sibling dependencies ([e72292f](https://github.com/libp2p/js-libp2p-interfaces/commit/e72292fe1e37ac55b041a09058365fb74de0e629)) + +## [@libp2p/interface-mocks-v9.1.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.1.2...@libp2p/interface-mocks-v9.1.3) (2023-03-07) + + +### Bug Fixes + +* dispatch connection event from mock upgrader ([#345](https://github.com/libp2p/js-libp2p-interfaces/issues/345)) ([b691b1f](https://github.com/libp2p/js-libp2p-interfaces/commit/b691b1fa28e23b549c32e89d6b7c98d6a50c7b8f)) + +## [@libp2p/interface-mocks-v9.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.1.1...@libp2p/interface-mocks-v9.1.2) (2023-02-22) + + +### Bug Fixes + +* replace err-code with CodeError ([#334](https://github.com/libp2p/js-libp2p-interfaces/issues/334)) ([a909d41](https://github.com/libp2p/js-libp2p-interfaces/commit/a909d418ce1128c771b682dc78bb48789d4b319a)), closes [js-libp2p#1269](https://github.com/libp2p/js-libp2p/issues/1269) + +## [@libp2p/interface-mocks-v9.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.1.0...@libp2p/interface-mocks-v9.1.1) (2023-01-18) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-mocks-v9.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.0.1...@libp2p/interface-mocks-v9.1.0) (2023-01-17) + + +### Features + +* safe dispatch event ([#319](https://github.com/libp2p/js-libp2p-interfaces/issues/319)) ([8caeee8](https://github.com/libp2p/js-libp2p-interfaces/commit/8caeee8221e78c2412d8aeb9a7db7cc43abfdf1b)), closes [#317](https://github.com/libp2p/js-libp2p-interfaces/issues/317) + +## [@libp2p/interface-mocks-v9.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v9.0.0...@libp2p/interface-mocks-v9.0.1) (2023-01-14) + + +### Bug Fixes + +* accept multiaddr param when opening connections ([#336](https://github.com/libp2p/js-libp2p-interfaces/issues/336)) ([fef9c26](https://github.com/libp2p/js-libp2p-interfaces/commit/fef9c26847cf63cb95f5fcb51ee40cbc679cc6bf)) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + +## [@libp2p/interface-mocks-v9.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v8.0.5...@libp2p/interface-mocks-v9.0.0) (2023-01-06) + + +### ⚠ BREAKING CHANGES + +* update peer-id dep to pull in new multiformats (#331) + +### Bug Fixes + +* update peer-id dep to pull in new multiformats ([#331](https://github.com/libp2p/js-libp2p-interfaces/issues/331)) ([fb8b7ba](https://github.com/libp2p/js-libp2p-interfaces/commit/fb8b7ba654a30a08da0652e2833e36dd3bb85e90)) + + +### Dependencies + +* update sibling dependencies ([667082f](https://github.com/libp2p/js-libp2p-interfaces/commit/667082f7070ec28a2f19c356fe44fd7499958f2e)) + +## [@libp2p/interface-mocks-v8.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v8.0.4...@libp2p/interface-mocks-v8.0.5) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-mocks-v8.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v8.0.3...@libp2p/interface-mocks-v8.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-mocks-v8.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v8.0.2...@libp2p/interface-mocks-v8.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-mocks-v8.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v8.0.1...@libp2p/interface-mocks-v8.0.2) (2022-12-07) + + +### Bug Fixes + +* add missing dependency ([e2168e8](https://github.com/libp2p/js-libp2p-interfaces/commit/e2168e8f863d6a488e4117800b5143dce1122b0b)) + +## [@libp2p/interface-mocks-v8.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v8.0.0...@libp2p/interface-mocks-v8.0.1) (2022-11-05) + + +### Bug Fixes + +* metrics only need numbers ([#312](https://github.com/libp2p/js-libp2p-interfaces/issues/312)) ([0076c1f](https://github.com/libp2p/js-libp2p-interfaces/commit/0076c1f354ebc1106b6ac42d48688c0209866084)) + +## [@libp2p/interface-mocks-v8.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v7.1.0...@libp2p/interface-mocks-v8.0.0) (2022-11-05) + + +### ⚠ BREAKING CHANGES + +* the global/per-peer moving average tracking has been removed from the interface as it's expensive and requires lots of timers - this functionality can be replicated by implementations if it's desirable. It's better to have simple counters instead and let an external system like Prometheus or Graphana calculate the values over time + +### Features + +* return metrics objects from register instead of updating with an options object ([#310](https://github.com/libp2p/js-libp2p-interfaces/issues/310)) ([3b106ce](https://github.com/libp2p/js-libp2p-interfaces/commit/3b106ce799b5d84a82a66238995e09970ed8116c)) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Dependencies + +* update sibling dependencies ([6f41152](https://github.com/libp2p/js-libp2p-interfaces/commit/6f41152cc10e9babd338fe0c0d3c9bfff6eee960)) + +## [@libp2p/interface-mocks-v7.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v7.0.3...@libp2p/interface-mocks-v7.1.0) (2022-11-05) + + +### Features + +* allow passing muxer factory to mock upgrader ([#309](https://github.com/libp2p/js-libp2p-interfaces/issues/309)) ([b2a4d92](https://github.com/libp2p/js-libp2p-interfaces/commit/b2a4d9231580e4cfc7b662e4cdae72f43e1c1011)) + +## [@libp2p/interface-mocks-v7.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v7.0.2...@libp2p/interface-mocks-v7.0.3) (2022-10-18) + + +### Dependencies + +* bump it-ndjson from 0.1.1 to 1.0.0 ([#308](https://github.com/libp2p/js-libp2p-interfaces/issues/308)) ([54db8a4](https://github.com/libp2p/js-libp2p-interfaces/commit/54db8a45c8e533b832c0b7b0f6847c28d7185676)) + +## [@libp2p/interface-mocks-v7.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v7.0.1...@libp2p/interface-mocks-v7.0.2) (2022-10-17) + + +### Dependencies + +* bump it-map from 1.0.6 to 2.0.0 ([#304](https://github.com/libp2p/js-libp2p-interfaces/issues/304)) ([8a1f7f4](https://github.com/libp2p/js-libp2p-interfaces/commit/8a1f7f4241d3acf250ee81a2265a00f58e80e6ed)) + +## [@libp2p/interface-mocks-v7.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v7.0.0...@libp2p/interface-mocks-v7.0.1) (2022-10-12) + + +### Bug Fixes + +* export network components type ([79a5d8f](https://github.com/libp2p/js-libp2p-interfaces/commit/79a5d8fc57ae47274ff9ad9c3969c5898f07eb1d)) +* update mock network components use ([c760e95](https://github.com/libp2p/js-libp2p-interfaces/commit/c760e95f07b6199f08adb20c1e3a4265649fdda0)) + + +### Trivial Changes + +* fix linting ([a8ab192](https://github.com/libp2p/js-libp2p-interfaces/commit/a8ab19295452c388d6556ea7847c490035455c99)) + +## [@libp2p/interface-mocks-v7.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v6.1.0...@libp2p/interface-mocks-v7.0.0) (2022-10-12) + + +### ⚠ BREAKING CHANGES + +* modules no longer implement `Initializable` instead switching to constructor injection + +### Bug Fixes + +* remove @libp2p/components ([#301](https://github.com/libp2p/js-libp2p-interfaces/issues/301)) ([1d37dc6](https://github.com/libp2p/js-libp2p-interfaces/commit/1d37dc6d3197838a71895d5769ad8bba6eb38fd3)) + + +### Dependencies + +* update sibling dependencies ([99330b2](https://github.com/libp2p/js-libp2p-interfaces/commit/99330b20842b2aff7530d1b9d373e8dce1ec3699)) +* update sibling dependencies ([6f26d1b](https://github.com/libp2p/js-libp2p-interfaces/commit/6f26d1b0343f4b41c064fab3ef87f308fc0c652d)) +* update sibling dependencies ([2ad1fa3](https://github.com/libp2p/js-libp2p-interfaces/commit/2ad1fa37c46b4c472570d79a592e798f20ed0cc8)) + +## [@libp2p/interface-mocks-v6.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v6.0.1...@libp2p/interface-mocks-v6.1.0) (2022-10-11) + + +### Features + +* add afterUpgradeInbound method ([#300](https://github.com/libp2p/js-libp2p-interfaces/issues/300)) ([fbdf5f5](https://github.com/libp2p/js-libp2p-interfaces/commit/fbdf5f54277735a26df0a28099eeae9d57159978)) + +## [@libp2p/interface-mocks-v6.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v6.0.0...@libp2p/interface-mocks-v6.0.1) (2022-10-07) + + +### Dependencies + +* bump @libp2p/components from 2.1.1 to 3.0.0 ([#299](https://github.com/libp2p/js-libp2p-interfaces/issues/299)) ([b3f493c](https://github.com/libp2p/js-libp2p-interfaces/commit/b3f493c5e260f697f66de54b56379d036ca3db59)) + +## [@libp2p/interface-mocks-v6.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v5.1.0...@libp2p/interface-mocks-v6.0.0) (2022-10-06) + + +### ⚠ BREAKING CHANGES + +* the return type of StreamMuxer.newStream can now return a promise + +Co-authored-by: Marco Munizaga + +### Features + +* add upgrader options ([#290](https://github.com/libp2p/js-libp2p-interfaces/issues/290)) ([c502b66](https://github.com/libp2p/js-libp2p-interfaces/commit/c502b66d87020eb8e2768c49be17392c55503f69)) + + +### Dependencies + +* update sibling dependencies ([0fae3ee](https://github.com/libp2p/js-libp2p-interfaces/commit/0fae3ee43fab43293fb290654a927b5c5c5759fc)) +* update sibling dependencies ([8a89a05](https://github.com/libp2p/js-libp2p-interfaces/commit/8a89a054e95827dd8cccc033669e17ae58059fbc)) +* update sibling dependencies ([66b4993](https://github.com/libp2p/js-libp2p-interfaces/commit/66b49938a09eeb12bf8ec8d78938d5cffd6ec134)) + +## [@libp2p/interface-mocks-v5.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v5.0.0...@libp2p/interface-mocks-v5.1.0) (2022-10-04) + + +### Features + +* add acceptIncomingConnection to ConnectionManager ([#295](https://github.com/libp2p/js-libp2p-interfaces/issues/295)) ([5d460e8](https://github.com/libp2p/js-libp2p-interfaces/commit/5d460e8815a8b49915da7ffabccc4a8b96a61acc)) + +## [@libp2p/interface-mocks-v5.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v4.0.3...@libp2p/interface-mocks-v5.0.0) (2022-10-04) + + +### ⚠ BREAKING CHANGES + +* Add remoteExtensions to connection-encrypter (#293) + +### Features + +* Add remoteExtensions to connection-encrypter ([#293](https://github.com/libp2p/js-libp2p-interfaces/issues/293)) ([501c684](https://github.com/libp2p/js-libp2p-interfaces/commit/501c684d792cd910de7cb9bfbda349db257ee2ca)) + + +### Dependencies + +* update sibling dependencies ([419f947](https://github.com/libp2p/js-libp2p-interfaces/commit/419f9479e8bba5d0555fe20a6fb9f0cf12a82cf9)) + +## [@libp2p/interface-mocks-v4.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v4.0.2...@libp2p/interface-mocks-v4.0.3) (2022-09-21) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-mocks-v4.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v4.0.1...@libp2p/interface-mocks-v4.0.2) (2022-08-11) + + +### Bug Fixes + +* update marshal type ([#282](https://github.com/libp2p/js-libp2p-interfaces/issues/282)) ([2c04ff9](https://github.com/libp2p/js-libp2p-interfaces/commit/2c04ff98097ba33dc64878b788c6b9318d2ea98b)) + +## [@libp2p/interface-mocks-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v4.0.0...@libp2p/interface-mocks-v4.0.1) (2022-08-10) + + +### Bug Fixes + +* revert connection encryption change to accept Uint8ArrayLists ([#280](https://github.com/libp2p/js-libp2p-interfaces/issues/280)) ([03d763c](https://github.com/libp2p/js-libp2p-interfaces/commit/03d763c1a6b168bba001783a1fb59af3f7d4e205)) + +## [@libp2p/interface-mocks-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v3.0.3...@libp2p/interface-mocks-v4.0.0) (2022-08-07) + + +### ⚠ BREAKING CHANGES + +* change stream muxer interface (#279) +* change connection encryption interface to uint8arraylist (#278) + +### Features + +* change connection encryption interface to uint8arraylist ([#278](https://github.com/libp2p/js-libp2p-interfaces/issues/278)) ([1fa580c](https://github.com/libp2p/js-libp2p-interfaces/commit/1fa580c5a45325dc9384738e9a78a238eabb81c3)) +* change stream muxer interface ([#279](https://github.com/libp2p/js-libp2p-interfaces/issues/279)) ([1ebe269](https://github.com/libp2p/js-libp2p-interfaces/commit/1ebe26988b6a286f36a4fc5177f502cfb60368a1)) + + +### Dependencies + +* update sibling dependencies ([f75e927](https://github.com/libp2p/js-libp2p-interfaces/commit/f75e9271345910e812ad600f936f4f774028e3fe)) +* update sibling dependencies ([d98a5ea](https://github.com/libp2p/js-libp2p-interfaces/commit/d98a5ea604c817cf6da47d9e86eea1e981b48711)) +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) +* update sibling dependencies ([93a89b1](https://github.com/libp2p/js-libp2p-interfaces/commit/93a89b1ca6d35fb5f26963ae7bb10026f3f5d45d)) + +## [@libp2p/interface-mocks-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v3.0.2...@libp2p/interface-mocks-v3.0.3) (2022-07-31) + + +### Dependencies + +* update uint8arraylist and p-wait-for deps ([#274](https://github.com/libp2p/js-libp2p-interfaces/issues/274)) ([c55f12e](https://github.com/libp2p/js-libp2p-interfaces/commit/c55f12e47be0a10e41709b0d6a60dd8bc1209ee5)) + +## [@libp2p/interface-mocks-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v3.0.1...@libp2p/interface-mocks-v3.0.2) (2022-07-31) + + +### Bug Fixes + +* mock connection manager close reciprocal connection ([#268](https://github.com/libp2p/js-libp2p-interfaces/issues/268)) ([f16dd7b](https://github.com/libp2p/js-libp2p-interfaces/commit/f16dd7bed2735e3a27e8febfe48bac75d4ff009f)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-mocks-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v3.0.0...@libp2p/interface-mocks-v3.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-mocks-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v2.1.0...@libp2p/interface-mocks-v3.0.0) (2022-06-24) + + +### ⚠ BREAKING CHANGES + +* StreamMuxer now has a `close` method + +### Features + +* add stream muxer close ([#254](https://github.com/libp2p/js-libp2p-interfaces/issues/254)) ([d1f511e](https://github.com/libp2p/js-libp2p-interfaces/commit/d1f511e4b5857769c4eddf902288dc69fcb667b4)) + + +### Trivial Changes + +* update sibling dependencies [skip ci] ([7f7fb67](https://github.com/libp2p/js-libp2p-interfaces/commit/7f7fb67b054688bfbc0cc68b9f2892bee8b41f13)) +* update sibling dependencies [skip ci] ([c522241](https://github.com/libp2p/js-libp2p-interfaces/commit/c522241b08cfef3995efb5415104f46521dcd3b7)) + +## [@libp2p/interface-mocks-v2.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v2.0.1...@libp2p/interface-mocks-v2.1.0) (2022-06-21) + + +### Features + +* add direction to StreamMuxerInit ([#253](https://github.com/libp2p/js-libp2p-interfaces/issues/253)) ([6d34d75](https://github.com/libp2p/js-libp2p-interfaces/commit/6d34d755ff4e798d52945f1f099052bdd6a83f2b)) + +## [@libp2p/interface-mocks-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v2.0.0...@libp2p/interface-mocks-v2.0.1) (2022-06-17) + + +### Bug Fixes + +* update stream handler args ([#247](https://github.com/libp2p/js-libp2p-interfaces/issues/247)) ([d29e134](https://github.com/libp2p/js-libp2p-interfaces/commit/d29e134bd70295c725bfd627d5887954d1a278ae)) + +## [@libp2p/interface-mocks-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v1.1.0...@libp2p/interface-mocks-v2.0.0) (2022-06-16) + + +### ⚠ BREAKING CHANGES + +* The Connection and Stream APIs have been updated + +### Features + +* store stream data on the stream, track the stream direction ([#245](https://github.com/libp2p/js-libp2p-interfaces/issues/245)) ([6d74d2f](https://github.com/libp2p/js-libp2p-interfaces/commit/6d74d2f9f344fb4d6741ba0d35263ebe351a4c65)) + + +### Trivial Changes + +* update deps ([970a940](https://github.com/libp2p/js-libp2p-interfaces/commit/970a940a2f65b946936a53febdc52527baefbd34)) +* update deps ([219e60e](https://github.com/libp2p/js-libp2p-interfaces/commit/219e60ec6f886b95803457fe48dfcdb4ed57e34c)) +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) + +## [@libp2p/interface-mocks-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v1.0.1...@libp2p/interface-mocks-v1.1.0) (2022-06-16) + + +### Features + +* define stream limits as input/output ([#240](https://github.com/libp2p/js-libp2p-interfaces/issues/240)) ([554fe95](https://github.com/libp2p/js-libp2p-interfaces/commit/554fe95865c4851fcef3b311d80d44f82a613969)) + +## [@libp2p/interface-mocks-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-mocks-v1.0.0...@libp2p/interface-mocks-v1.0.1) (2022-06-14) + + +### Bug Fixes + +* remove components from muxer factory function ([#238](https://github.com/libp2p/js-libp2p-interfaces/issues/238)) ([e4dab30](https://github.com/libp2p/js-libp2p-interfaces/commit/e4dab306d9bf406b9bb3cb92644e28cf81f7bda6)) + + +### Trivial Changes + +* update components module ([#235](https://github.com/libp2p/js-libp2p-interfaces/issues/235)) ([5844207](https://github.com/libp2p/js-libp2p-interfaces/commit/58442070af59aa852c83ec3aecdbd1d2c646b018)) +* update it-pushable dep ([#237](https://github.com/libp2p/js-libp2p-interfaces/issues/237)) ([2e16465](https://github.com/libp2p/js-libp2p-interfaces/commit/2e164658df344b5ec475be2a571df5d6f20ee086)) + +## [@libp2p/interface-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v2.0.2...@libp2p/interface-compliance-tests-v2.0.3) (2022-05-24) + + +### Bug Fixes + +* only close muxed stream for reading ([#220](https://github.com/libp2p/js-libp2p-interfaces/issues/220)) ([f2f7141](https://github.com/libp2p/js-libp2p-interfaces/commit/f2f7141f01af715e600201ac9e7e52fbbb5c7e1b)) + +## [@libp2p/interface-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v2.0.1...@libp2p/interface-compliance-tests-v2.0.2) (2022-05-24) + + +### Bug Fixes + +* accept abort options in connection.newStream ([#219](https://github.com/libp2p/js-libp2p-interfaces/issues/219)) ([8bfcbc9](https://github.com/libp2p/js-libp2p-interfaces/commit/8bfcbc9ee883336f213cdfc83e477549ca368df5)) +* chunk data in mock muxer ([#218](https://github.com/libp2p/js-libp2p-interfaces/issues/218)) ([14604f6](https://github.com/libp2p/js-libp2p-interfaces/commit/14604f69a858bf8c16ce118420c5e49f3f5331ea)) + +## [@libp2p/interface-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v2.0.0...@libp2p/interface-compliance-tests-v2.0.1) (2022-05-23) + + +### Bug Fixes + +* make stream return types synchronous ([#217](https://github.com/libp2p/js-libp2p-interfaces/issues/217)) ([2fe61b7](https://github.com/libp2p/js-libp2p-interfaces/commit/2fe61b7fbeda2e549edf095a927d623aa8eb476b)) + +## [@libp2p/interface-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.34...@libp2p/interface-compliance-tests-v2.0.0) (2022-05-20) + + +### ⚠ BREAKING CHANGES + +* This adds closeWrite and closeRead checks in the tests, which will cause test failures for muxers that don't implement those + +### Bug Fixes + +* close streams when connection is closed ([#214](https://github.com/libp2p/js-libp2p-interfaces/issues/214)) ([88fcd58](https://github.com/libp2p/js-libp2p-interfaces/commit/88fcd586276e03dd740c7095f05e21754ac1f3b5)), closes [#90](https://github.com/libp2p/js-libp2p-interfaces/issues/90) +* update interfaces ([#215](https://github.com/libp2p/js-libp2p-interfaces/issues/215)) ([72e6890](https://github.com/libp2p/js-libp2p-interfaces/commit/72e6890826dadbd6e7cbba5536bde350ca4286e6)) + +## [@libp2p/interface-compliance-tests-v1.1.34](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.33...@libp2p/interface-compliance-tests-v1.1.34) (2022-05-10) + + +### Trivial Changes + +* **deps:** bump sinon from 13.0.2 to 14.0.0 ([#211](https://github.com/libp2p/js-libp2p-interfaces/issues/211)) ([8859f70](https://github.com/libp2p/js-libp2p-interfaces/commit/8859f70943c0bcdb210f54a338ae901739e5e6f2)) + +## [@libp2p/interface-compliance-tests-v1.1.33](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.32...@libp2p/interface-compliance-tests-v1.1.33) (2022-05-06) + + +### Bug Fixes + +* add tag to peer discovery interface ([#210](https://github.com/libp2p/js-libp2p-interfaces/issues/210)) ([f99c833](https://github.com/libp2p/js-libp2p-interfaces/commit/f99c833c8436f8434f380d890ec5d267279312d7)) + +## [@libp2p/interface-compliance-tests-v1.1.32](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.31...@libp2p/interface-compliance-tests-v1.1.32) (2022-05-04) + + +### Bug Fixes + +* move startable and events interfaces ([#209](https://github.com/libp2p/js-libp2p-interfaces/issues/209)) ([8ce8a08](https://github.com/libp2p/js-libp2p-interfaces/commit/8ce8a08c94b0738aa32da516558977b195ddd8ed)) + +## [@libp2p/interface-compliance-tests-v1.1.31](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.30...@libp2p/interface-compliance-tests-v1.1.31) (2022-05-03) + + +### Bug Fixes + +* only send handled protocols ([#207](https://github.com/libp2p/js-libp2p-interfaces/issues/207)) ([1f7afc2](https://github.com/libp2p/js-libp2p-interfaces/commit/1f7afc29d72fde708064ec6479011dbc0a225962)) + +## [@libp2p/interface-compliance-tests-v1.1.30](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.29...@libp2p/interface-compliance-tests-v1.1.30) (2022-05-01) + + +### Bug Fixes + +* move connection manager mock to connection manager module ([#205](https://github.com/libp2p/js-libp2p-interfaces/issues/205)) ([a367375](https://github.com/libp2p/js-libp2p-interfaces/commit/a367375accc690d7b4608c9a3313f91df700efd8)) + +## [@libp2p/interface-compliance-tests-v1.1.29](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.28...@libp2p/interface-compliance-tests-v1.1.29) (2022-04-28) + + +### Bug Fixes + +* pubsub should not be startable ([#204](https://github.com/libp2p/js-libp2p-interfaces/issues/204)) ([59bd924](https://github.com/libp2p/js-libp2p-interfaces/commit/59bd9245a207268525bdd26a05c5306fe436fcc4)) + +## [@libp2p/interface-compliance-tests-v1.1.28](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.27...@libp2p/interface-compliance-tests-v1.1.28) (2022-04-28) + + +### Bug Fixes + +* pubsub and dht are always set ([#203](https://github.com/libp2p/js-libp2p-interfaces/issues/203)) ([86860c1](https://github.com/libp2p/js-libp2p-interfaces/commit/86860c1836a2464b2ad380b09542e3f3271ae287)) + +## [@libp2p/interface-compliance-tests-v1.1.27](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.26...@libp2p/interface-compliance-tests-v1.1.27) (2022-04-26) + + +### Bug Fixes + +* add delays for gossipsub ([#202](https://github.com/libp2p/js-libp2p-interfaces/issues/202)) ([cf85799](https://github.com/libp2p/js-libp2p-interfaces/commit/cf85799fdd0d4848ad2187bbbb0dd6ac5e8cb254)) + +## [@libp2p/interface-compliance-tests-v1.1.26](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.25...@libp2p/interface-compliance-tests-v1.1.26) (2022-04-25) + + +### Bug Fixes + +* stop pubsub after test ([#200](https://github.com/libp2p/js-libp2p-interfaces/issues/200)) ([2d2650c](https://github.com/libp2p/js-libp2p-interfaces/commit/2d2650cb8cabce137665aafd55a2fb14cbd5dacd)) + +## [@libp2p/interface-compliance-tests-v1.1.25](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.24...@libp2p/interface-compliance-tests-v1.1.25) (2022-04-22) + + +### Bug Fixes + +* update pubsub interface in line with gossipsub ([#199](https://github.com/libp2p/js-libp2p-interfaces/issues/199)) ([3f55596](https://github.com/libp2p/js-libp2p-interfaces/commit/3f555965cddea3ef03e7217b755c82aa4107e093)) + +## [@libp2p/interface-compliance-tests-v1.1.24](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.23...@libp2p/interface-compliance-tests-v1.1.24) (2022-04-21) + + +### Bug Fixes + +* test PubSub interface and not PubSubBaseProtocol ([#198](https://github.com/libp2p/js-libp2p-interfaces/issues/198)) ([96c15c9](https://github.com/libp2p/js-libp2p-interfaces/commit/96c15c9780821a3cb763e48854d64377bf562692)) + +## [@libp2p/interface-compliance-tests-v1.1.23](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.22...@libp2p/interface-compliance-tests-v1.1.23) (2022-04-20) + + +### Bug Fixes + +* emit pubsub messages using 'message' event ([#197](https://github.com/libp2p/js-libp2p-interfaces/issues/197)) ([df9b685](https://github.com/libp2p/js-libp2p-interfaces/commit/df9b685cea30653109f2fa2cb5583a3bca7b09bb)) + +## [@libp2p/interface-compliance-tests-v1.1.22](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.21...@libp2p/interface-compliance-tests-v1.1.22) (2022-04-19) + + +### Bug Fixes + +* move dev deps to prod ([#195](https://github.com/libp2p/js-libp2p-interfaces/issues/195)) ([3e1ffc7](https://github.com/libp2p/js-libp2p-interfaces/commit/3e1ffc7b174e74be483943ad4e5fcab823ae3f6d)) + +## [@libp2p/interface-compliance-tests-v1.1.21](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.20...@libp2p/interface-compliance-tests-v1.1.21) (2022-04-08) + + +### Bug Fixes + +* swap protobufjs for protons ([#191](https://github.com/libp2p/js-libp2p-interfaces/issues/191)) ([d72b30c](https://github.com/libp2p/js-libp2p-interfaces/commit/d72b30cfca4b9145e0b31db28e8fa3329a180e83)) + + +### Trivial Changes + +* update aegir ([#192](https://github.com/libp2p/js-libp2p-interfaces/issues/192)) ([41c1494](https://github.com/libp2p/js-libp2p-interfaces/commit/41c14941e8b67d6601a90b4d48a2776573d55e60)) + +## [@libp2p/interface-compliance-tests-v1.1.20](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.19...@libp2p/interface-compliance-tests-v1.1.20) (2022-03-24) + + +### Bug Fixes + +* rename peer data to peer info ([#187](https://github.com/libp2p/js-libp2p-interfaces/issues/187)) ([dfea342](https://github.com/libp2p/js-libp2p-interfaces/commit/dfea3429bad57abde040397e4e7a58539829e9c2)) + +## [@libp2p/interface-compliance-tests-v1.1.19](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.18...@libp2p/interface-compliance-tests-v1.1.19) (2022-03-22) + + +### Bug Fixes + +* add method for startable lifecyle ([#186](https://github.com/libp2p/js-libp2p-interfaces/issues/186)) ([2730e29](https://github.com/libp2p/js-libp2p-interfaces/commit/2730e2947bbd231db3f7f82951b51ee534733ab2)) + +## [@libp2p/interface-compliance-tests-v1.1.18](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.17...@libp2p/interface-compliance-tests-v1.1.18) (2022-03-20) + + +### Bug Fixes + +* update pubsub types ([#183](https://github.com/libp2p/js-libp2p-interfaces/issues/183)) ([7ef4baa](https://github.com/libp2p/js-libp2p-interfaces/commit/7ef4baad0fe30f783f3eecd5199ef92af08b7f57)) + +## [@libp2p/interface-compliance-tests-v1.1.17](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.16...@libp2p/interface-compliance-tests-v1.1.17) (2022-03-15) + + +### Bug Fixes + +* use custom event instead of error event ([#181](https://github.com/libp2p/js-libp2p-interfaces/issues/181)) ([71ab242](https://github.com/libp2p/js-libp2p-interfaces/commit/71ab2424dfbf6337111d6d9d994f27c7967c20f1)) + +## [@libp2p/interface-compliance-tests-v1.1.16](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.15...@libp2p/interface-compliance-tests-v1.1.16) (2022-03-15) + + +### Bug Fixes + +* simplify transport interface, update interfaces for use with libp2p ([#180](https://github.com/libp2p/js-libp2p-interfaces/issues/180)) ([ec81622](https://github.com/libp2p/js-libp2p-interfaces/commit/ec81622e5b7c6d256e0f8aed6d3695642473293b)) + +## [@libp2p/interface-compliance-tests-v1.1.15](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.14...@libp2p/interface-compliance-tests-v1.1.15) (2022-02-27) + + +### Bug Fixes + +* rename crypto to connection-encrypter ([#179](https://github.com/libp2p/js-libp2p-interfaces/issues/179)) ([d197f55](https://github.com/libp2p/js-libp2p-interfaces/commit/d197f554d7cdadb3b05ed2d6c69fda2c4362b1eb)) + +## [@libp2p/interface-compliance-tests-v1.1.14](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.13...@libp2p/interface-compliance-tests-v1.1.14) (2022-02-27) + + +### Bug Fixes + +* update package config and add connection gater interface ([#178](https://github.com/libp2p/js-libp2p-interfaces/issues/178)) ([c6079a6](https://github.com/libp2p/js-libp2p-interfaces/commit/c6079a6367f004788062df3e30ad2e26330d947b)) + +## [@libp2p/interface-compliance-tests-v1.1.13](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.12...@libp2p/interface-compliance-tests-v1.1.13) (2022-02-21) + + +### Bug Fixes + +* increase stream test timeout ([#175](https://github.com/libp2p/js-libp2p-interfaces/issues/175)) ([568aefb](https://github.com/libp2p/js-libp2p-interfaces/commit/568aefb5c099ba0161ffecf86bda238b92d396b0)) + +## [@libp2p/interface-compliance-tests-v1.1.12](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.11...@libp2p/interface-compliance-tests-v1.1.12) (2022-02-21) + + +### Bug Fixes + +* update muxer to pass transport tests ([#174](https://github.com/libp2p/js-libp2p-interfaces/issues/174)) ([466ed53](https://github.com/libp2p/js-libp2p-interfaces/commit/466ed53192aa196ac2dbdb83df3c8db9cd5b1e07)) + +## [@libp2p/interface-compliance-tests-v1.1.11](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.10...@libp2p/interface-compliance-tests-v1.1.11) (2022-02-18) + + +### Bug Fixes + +* remove delays from pubsub tests ([#173](https://github.com/libp2p/js-libp2p-interfaces/issues/173)) ([5c8fe09](https://github.com/libp2p/js-libp2p-interfaces/commit/5c8fe09294f0cbd8add1406a61fa7dbc5b4e788b)) + +## [@libp2p/interface-compliance-tests-v1.1.10](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.9...@libp2p/interface-compliance-tests-v1.1.10) (2022-02-18) + + +### Bug Fixes + +* simpler pubsub ([#172](https://github.com/libp2p/js-libp2p-interfaces/issues/172)) ([98715ed](https://github.com/libp2p/js-libp2p-interfaces/commit/98715ed73183b32e4fda3d878a462389548358d9)) + +## [@libp2p/interface-compliance-tests-v1.1.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.8...@libp2p/interface-compliance-tests-v1.1.9) (2022-02-17) + + +### Bug Fixes + +* update deps ([#171](https://github.com/libp2p/js-libp2p-interfaces/issues/171)) ([d0d2564](https://github.com/libp2p/js-libp2p-interfaces/commit/d0d2564a84a0722ab587a3aa6ec01e222442b100)) + +## [@libp2p/interface-compliance-tests-v1.1.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.7...@libp2p/interface-compliance-tests-v1.1.8) (2022-02-17) + + +### Bug Fixes + +* add multistream-select and update pubsub types ([#170](https://github.com/libp2p/js-libp2p-interfaces/issues/170)) ([b9ecb2b](https://github.com/libp2p/js-libp2p-interfaces/commit/b9ecb2bee8f2abc0c41bfcf7bf2025894e37ddc2)) + +## [@libp2p/interface-compliance-tests-v1.1.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.6...@libp2p/interface-compliance-tests-v1.1.7) (2022-02-16) + + +### Bug Fixes + +* test muxer ([#169](https://github.com/libp2p/js-libp2p-interfaces/issues/169)) ([574723d](https://github.com/libp2p/js-libp2p-interfaces/commit/574723d11007e875e7adfa5c32819445f9b8def7)) + +## [@libp2p/interface-compliance-tests-v1.1.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.5...@libp2p/interface-compliance-tests-v1.1.6) (2022-02-12) + + +### Bug Fixes + +* return registered topologies in mock ([#168](https://github.com/libp2p/js-libp2p-interfaces/issues/168)) ([1583019](https://github.com/libp2p/js-libp2p-interfaces/commit/158301982384a694ac3fb8f9df67c71b7b776b47)) + +## [@libp2p/interface-compliance-tests-v1.1.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.4...@libp2p/interface-compliance-tests-v1.1.5) (2022-02-12) + + +### Bug Fixes + +* hide implementations behind factory methods ([#167](https://github.com/libp2p/js-libp2p-interfaces/issues/167)) ([2fba080](https://github.com/libp2p/js-libp2p-interfaces/commit/2fba0800c9896af6dcc49da4fa904bb4a3e3e40d)) + +## [@libp2p/interface-compliance-tests-v1.1.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.3...@libp2p/interface-compliance-tests-v1.1.4) (2022-02-11) + + +### Bug Fixes + +* simpler topologies ([#164](https://github.com/libp2p/js-libp2p-interfaces/issues/164)) ([45fcaa1](https://github.com/libp2p/js-libp2p-interfaces/commit/45fcaa10a6a3215089340ff2eff117d7fd1100e7)) + +## [@libp2p/interface-compliance-tests-v1.1.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.2...@libp2p/interface-compliance-tests-v1.1.3) (2022-02-10) + + +### Bug Fixes + +* make registrar simpler ([#163](https://github.com/libp2p/js-libp2p-interfaces/issues/163)) ([d122f3d](https://github.com/libp2p/js-libp2p-interfaces/commit/d122f3daaccc04039d90814960da92b513265644)) + +## [@libp2p/interface-compliance-tests-v1.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.1...@libp2p/interface-compliance-tests-v1.1.2) (2022-02-10) + + +### Bug Fixes + +* remove args from listener events ([#162](https://github.com/libp2p/js-libp2p-interfaces/issues/162)) ([011ac89](https://github.com/libp2p/js-libp2p-interfaces/commit/011ac891ec7d44625cb4342f068bcd9f241a5b45)) + +## [@libp2p/interface-compliance-tests-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.1.0...@libp2p/interface-compliance-tests-v1.1.1) (2022-02-10) + + +### Bug Fixes + +* remove node event emitters ([#161](https://github.com/libp2p/js-libp2p-interfaces/issues/161)) ([221fb6a](https://github.com/libp2p/js-libp2p-interfaces/commit/221fb6a024430dc56288d73d8b8ce1aa88427701)) + +## [@libp2p/interface-compliance-tests-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.8...@libp2p/interface-compliance-tests-v1.1.0) (2022-02-09) + + +### Features + +* add peer store/records, and streams are just streams ([#160](https://github.com/libp2p/js-libp2p-interfaces/issues/160)) ([8860a0c](https://github.com/libp2p/js-libp2p-interfaces/commit/8860a0cd46b359a5648402d83870f7ff957222fe)) + +## [@libp2p/interface-compliance-tests-v1.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.7...@libp2p/interface-compliance-tests-v1.0.8) (2022-02-05) + + +### Bug Fixes + +* fix muxer tests ([#157](https://github.com/libp2p/js-libp2p-interfaces/issues/157)) ([7233c44](https://github.com/libp2p/js-libp2p-interfaces/commit/7233c4438479dff56a682f45209ef7a938d63857)) + +## [@libp2p/interface-compliance-tests-v1.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.6...@libp2p/interface-compliance-tests-v1.0.7) (2022-01-31) + + +### Trivial Changes + +* **deps:** bump sinon from 12.0.1 to 13.0.0 ([#154](https://github.com/libp2p/js-libp2p-interfaces/issues/154)) ([3fc8812](https://github.com/libp2p/js-libp2p-interfaces/commit/3fc8812897fa197e7b62f77614abaea4a5563404)) + +## [@libp2p/interface-compliance-tests-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.5...@libp2p/interface-compliance-tests-v1.0.6) (2022-01-29) + + +### Bug Fixes + +* remove extra fields ([#153](https://github.com/libp2p/js-libp2p-interfaces/issues/153)) ([ccd7cf3](https://github.com/libp2p/js-libp2p-interfaces/commit/ccd7cf3f5ac71337baf516d3b0f6fc724ee0d3b4)) + +## [@libp2p/interface-compliance-tests-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.4...@libp2p/interface-compliance-tests-v1.0.5) (2022-01-15) + + +### Bug Fixes + +* remove abort controller dep ([#151](https://github.com/libp2p/js-libp2p-interfaces/issues/151)) ([518bce1](https://github.com/libp2p/js-libp2p-interfaces/commit/518bce1f9bd1f8b2922338e0c65c9934af7da3af)) + +## [@libp2p/interface-compliance-tests-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.3...@libp2p/interface-compliance-tests-v1.0.4) (2022-01-15) + + +### Trivial Changes + +* update project config ([#149](https://github.com/libp2p/js-libp2p-interfaces/issues/149)) ([6eb8556](https://github.com/libp2p/js-libp2p-interfaces/commit/6eb85562c0da167d222808da10a7914daf12970b)) + +## [@libp2p/interface-compliance-tests-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.2...@libp2p/interface-compliance-tests-v1.0.3) (2022-01-14) + + +### Bug Fixes + +* update it-* deps to ts versions ([#148](https://github.com/libp2p/js-libp2p-interfaces/issues/148)) ([7a6fdd7](https://github.com/libp2p/js-libp2p-interfaces/commit/7a6fdd7622ce2870b89dbb849ab421d0dd714b43)) + +## [@libp2p/interface-compliance-tests-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-compliance-tests-v1.0.1...@libp2p/interface-compliance-tests-v1.0.2) (2022-01-08) + + +### Trivial Changes + +* add semantic release config ([#141](https://github.com/libp2p/js-libp2p-interfaces/issues/141)) ([5f0de59](https://github.com/libp2p/js-libp2p-interfaces/commit/5f0de59136b6343d2411abb2d6a4dd2cd0b7efe4)) +* update package versions ([#140](https://github.com/libp2p/js-libp2p-interfaces/issues/140)) ([cd844f6](https://github.com/libp2p/js-libp2p-interfaces/commit/cd844f6e39f4ee50d006e86eac8dadf696900eb5)) + +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.2.0 (2022-01-04) + + +### Features + +* add auto-publish ([7aede5d](https://github.com/libp2p/js-libp2p-interfaces/commit/7aede5df39ea6b5f243348ec9a212b3e33c16a81)) +* update package names ([#133](https://github.com/libp2p/js-libp2p-interfaces/issues/133)) ([337adc9](https://github.com/libp2p/js-libp2p-interfaces/commit/337adc9a9bc0278bdae8cbce9c57d07a83c8b5c2)) + + + + + +## [3.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@3.1.0...libp2p-interfaces-compliance-tests@3.1.1) (2022-01-02) + + +### Bug Fixes + +* move errors ([#132](https://github.com/libp2p/js-libp2p-interfaces/issues/132)) ([21d282a](https://github.com/libp2p/js-libp2p-interfaces/commit/21d282a6d77bd7d1a12daa1cc8b3a3fed8635dad)) + + + + + +# [3.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@3.0.0...libp2p-interfaces-compliance-tests@3.1.0) (2022-01-02) + + +### Bug Fixes + +* update dialer tests ([#116](https://github.com/libp2p/js-libp2p-interfaces/issues/116)) ([c679729](https://github.com/libp2p/js-libp2p-interfaces/commit/c679729113feb963ff27815fcafd7af51f722df7)) + + +### Features + +* simpler peer id ([#117](https://github.com/libp2p/js-libp2p-interfaces/issues/117)) ([fa2c4f5](https://github.com/libp2p/js-libp2p-interfaces/commit/fa2c4f5be74a5cfc11489771881e57b4e53bf174)) + + + + + +# [3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@2.0.0...libp2p-interfaces-compliance-tests@3.0.0) (2021-12-02) + + +### chore + +* update libp2p-crypto and peer-id ([c711e8b](https://github.com/libp2p/js-libp2p-interfaces/commit/c711e8bd4d606f6974b13fad2eeb723f93cebb87)) + + +### BREAKING CHANGES + +* requires node 15+ + + + + + +# [2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.1.2...libp2p-interfaces-compliance-tests@2.0.0) (2021-11-22) + + +### Features + +* split out code, convert to typescript ([#111](https://github.com/libp2p/js-libp2p-interfaces/issues/111)) ([e174bba](https://github.com/libp2p/js-libp2p-interfaces/commit/e174bba889388269b806643c79a6b53c8d6a0f8c)), closes [#110](https://github.com/libp2p/js-libp2p-interfaces/issues/110) [#101](https://github.com/libp2p/js-libp2p-interfaces/issues/101) + + +### BREAKING CHANGES + +* not all fields from concrete classes have been added to the interfaces, some adjustment may be necessary as this gets rolled out + + + + + +## [1.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.1.1...libp2p-interfaces-compliance-tests@1.1.2) (2021-10-18) + +**Note:** Version bump only for package libp2p-interfaces-compliance-tests + + + + + +## [1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.1.0...libp2p-interfaces-compliance-tests@1.1.1) (2021-09-20) + +**Note:** Version bump only for package libp2p-interfaces-compliance-tests + + + + + +# [1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.0.1...libp2p-interfaces-compliance-tests@1.1.0) (2021-08-20) + + +### Features + +* update uint8arrays ([#105](https://github.com/libp2p/js-libp2p-interfaces/issues/105)) ([9297a9c](https://github.com/libp2p/js-libp2p-interfaces/commit/9297a9c379276d03c8da849af6108b38e581b4a6)) + + + + + +## [1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces-compliance-tests@1.0.0...libp2p-interfaces-compliance-tests@1.0.1) (2021-07-08) + + +### Bug Fixes + +* make tests more reliable ([#103](https://github.com/libp2p/js-libp2p-interfaces/issues/103)) ([cd4c409](https://github.com/libp2p/js-libp2p-interfaces/commit/cd4c40908efe2e9ffc14aa61aace5176a43fd70a)) +* remove timeouts ([#104](https://github.com/libp2p/js-libp2p-interfaces/issues/104)) ([3699c17](https://github.com/libp2p/js-libp2p-interfaces/commit/3699c17f022da40a87ab24adc3b2081df7a0ddcd)) + + + + + +# 1.0.0 (2021-07-07) + + +### chore + +* monorepo separating interfaces and compliance tests ([#97](https://github.com/libp2p/js-libp2p-interfaces/issues/97)) ([946348f](https://github.com/libp2p/js-libp2p-interfaces/commit/946348f7f8acc1ff7bc9cd0ab4c2602d41106f76)) + + +### BREAKING CHANGES + +* the tests now live in the libp2p-interfaces-compliance-tests module diff --git a/packages/interface-mocks/LICENSE b/packages/interface-mocks/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-mocks/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-mocks/LICENSE-APACHE b/packages/interface-mocks/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-mocks/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-mocks/LICENSE-MIT b/packages/interface-mocks/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-mocks/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-mocks/README.md b/packages/interface-mocks/README.md new file mode 100644 index 0000000000..8b131cd614 --- /dev/null +++ b/packages/interface-mocks/README.md @@ -0,0 +1,50 @@ +# @libp2p/interface-mocks + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Mock implementations of several libp2p interfaces + +## Table of contents + +- [Install](#install) + - [Browser ` +``` + +## Usage + +Each [interface](../interfaces) has its documentation on how to use the compliance tests and should be used as the source of truth. + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-mocks/package.json b/packages/interface-mocks/package.json new file mode 100644 index 0000000000..12ed79bda4 --- /dev/null +++ b/packages/interface-mocks/package.json @@ -0,0 +1,181 @@ +{ + "name": "@libp2p/interface-mocks", + "version": "12.0.1", + "description": "Mock implementations of several libp2p interfaces", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-mocks#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "test": "aegir test", + "test:chrome": "aegir test -t browser --cov", + "test:chrome-webworker": "aegir test -t webworker", + "test:firefox": "aegir test -t browser -- --browser firefox", + "test:firefox-webworker": "aegir test -t webworker -- --browser firefox", + "test:node": "aegir test -t node --cov", + "test:electron-main": "aegir test -t electron-main", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-connection-encrypter": "^4.0.0", + "@libp2p/interface-connection-gater": "^3.0.0", + "@libp2p/interface-connection-manager": "^3.0.0", + "@libp2p/interface-libp2p": "^3.0.0", + "@libp2p/interface-metrics": "^4.0.0", + "@libp2p/interface-peer-discovery": "^2.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interface-peer-info": "^1.0.0", + "@libp2p/interface-pubsub": "^4.0.0", + "@libp2p/interface-registrar": "^2.0.0", + "@libp2p/interface-stream-muxer": "^4.0.0", + "@libp2p/interface-transport": "^4.0.0", + "@libp2p/interfaces": "^3.0.0", + "@libp2p/logger": "^2.1.1", + "@libp2p/multistream-select": "^3.1.8", + "@libp2p/peer-collections": "^3.0.1", + "@libp2p/peer-id": "^2.0.0", + "@libp2p/peer-id-factory": "^2.0.0", + "@multiformats/multiaddr": "^12.0.0", + "abortable-iterator": "^5.0.1", + "any-signal": "^4.1.1", + "it-handshake": "^4.1.3", + "it-map": "^3.0.2", + "it-ndjson": "^1.0.0", + "it-pair": "^2.0.2", + "it-pipe": "^3.0.1", + "it-pushable": "^3.1.3", + "it-stream-types": "^2.0.1", + "merge-options": "^3.0.4", + "uint8arraylist": "^2.4.3", + "uint8arrays": "^4.0.2" + }, + "devDependencies": { + "@libp2p/interface-connection-compliance-tests": "^2.0.0", + "@libp2p/interface-connection-encrypter-compliance-tests": "^5.0.0", + "@libp2p/interface-peer-discovery-compliance-tests": "^2.0.0", + "@libp2p/interface-stream-muxer-compliance-tests": "^7.0.0", + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-mocks/src/connection-encrypter.ts b/packages/interface-mocks/src/connection-encrypter.ts new file mode 100644 index 0000000000..281756bb06 --- /dev/null +++ b/packages/interface-mocks/src/connection-encrypter.ts @@ -0,0 +1,113 @@ +import { UnexpectedPeerError } from '@libp2p/interface-connection-encrypter/errors' +import { peerIdFromBytes } from '@libp2p/peer-id' +import { multiaddr } from '@multiformats/multiaddr' +import { handshake } from 'it-handshake' +import map from 'it-map' +import { duplexPair } from 'it-pair/duplex' +import { pipe } from 'it-pipe' +import type { ConnectionEncrypter } from '@libp2p/interface-connection-encrypter' +import type { Transform, Source } from 'it-stream-types' + +// A basic transform that does nothing to the data +const transform = (): Transform, AsyncGenerator> => { + return (source: Source) => (async function * () { + for await (const chunk of source) { + yield chunk + } + })() +} + +export function mockConnectionEncrypter (): ConnectionEncrypter { + const encrypter: ConnectionEncrypter = { + protocol: 'insecure', + secureInbound: async (localPeer, duplex, expectedPeer) => { + // 1. Perform a basic handshake. + const shake = handshake(duplex) + shake.write(localPeer.toBytes()) + const remoteId = await shake.read() + + if (remoteId == null) { + throw new Error('Could not read remote ID') + } + + const remotePeer = peerIdFromBytes(remoteId.slice()) + shake.rest() + + if (expectedPeer?.equals(remotePeer) === false) { + throw new UnexpectedPeerError() + } + + // 2. Create your encryption box/unbox wrapper + const wrapper = duplexPair() + const encrypt = transform() // Use transform iterables to modify data + const decrypt = transform() + + void pipe( + wrapper[0], // We write to wrapper + encrypt, // The data is encrypted + shake.stream, // It goes to the remote peer + source => map(source, (list) => list.subarray()), // turn lists into arrays + decrypt, // Decrypt the incoming data + wrapper[0] // Pipe to the wrapper + ) + + return { + conn: { + ...wrapper[1], + close: async () => { }, + localAddr: multiaddr('/ip4/127.0.0.1/tcp/4001'), + remoteAddr: multiaddr('/ip4/127.0.0.1/tcp/4002'), + timeline: { + open: Date.now() + }, + conn: true + }, + remotePeer, + remoteExtensions: {} + } + }, + secureOutbound: async (localPeer, duplex, remotePeer) => { + // 1. Perform a basic handshake. + const shake = handshake(duplex) + shake.write(localPeer.toBytes()) + const remoteId = await shake.read() + + if (remoteId == null) { + throw new Error('Could not read remote ID') + } + + shake.rest() + + // 2. Create your encryption box/unbox wrapper + const wrapper = duplexPair() + const encrypt = transform() + const decrypt = transform() + + void pipe( + wrapper[0], // We write to wrapper + encrypt, // The data is encrypted + shake.stream, // It goes to the remote peer + source => map(source, (list) => list.subarray()), // turn lists into arrays + decrypt, // Decrypt the incoming data + wrapper[0] // Pipe to the wrapper + ) + + return { + conn: { + ...wrapper[1], + close: async () => { }, + localAddr: multiaddr('/ip4/127.0.0.1/tcp/4001'), + remoteAddr: multiaddr('/ip4/127.0.0.1/tcp/4002'), + timeline: { + open: Date.now() + }, + conn: true + }, + remotePeer: peerIdFromBytes(remoteId.slice()), + remoteExtensions: {} + } + } + } + + return encrypter +} diff --git a/packages/interface-mocks/src/connection-gater.ts b/packages/interface-mocks/src/connection-gater.ts new file mode 100644 index 0000000000..86b873c74c --- /dev/null +++ b/packages/interface-mocks/src/connection-gater.ts @@ -0,0 +1,18 @@ +import type { ConnectionGater } from '@libp2p/interface-connection-gater' + +export function mockConnectionGater (): ConnectionGater { + return { + denyDialPeer: async () => Promise.resolve(false), + denyDialMultiaddr: async () => Promise.resolve(false), + denyInboundConnection: async () => Promise.resolve(false), + denyOutboundConnection: async () => Promise.resolve(false), + denyInboundEncryptedConnection: async () => Promise.resolve(false), + denyOutboundEncryptedConnection: async () => Promise.resolve(false), + denyInboundUpgradedConnection: async () => Promise.resolve(false), + denyOutboundUpgradedConnection: async () => Promise.resolve(false), + denyInboundRelayReservation: async () => Promise.resolve(false), + denyOutboundRelayedConnection: async () => Promise.resolve(false), + denyInboundRelayedConnection: async () => Promise.resolve(false), + filterMultiaddrForPeer: async () => Promise.resolve(true) + } +} diff --git a/packages/interface-mocks/src/connection-manager.ts b/packages/interface-mocks/src/connection-manager.ts new file mode 100644 index 0000000000..d91f0e738a --- /dev/null +++ b/packages/interface-mocks/src/connection-manager.ts @@ -0,0 +1,211 @@ +import { isPeerId, type PeerId } from '@libp2p/interface-peer-id' +import { CodeError } from '@libp2p/interfaces/errors' +import { PeerMap } from '@libp2p/peer-collections' +import { peerIdFromString } from '@libp2p/peer-id' +import { isMultiaddr, type Multiaddr } from '@multiformats/multiaddr' +import { connectionPair } from './connection.js' +import type { Connection } from '@libp2p/interface-connection' +import type { ConnectionManager, PendingDial } from '@libp2p/interface-connection-manager' +import type { Libp2pEvents } from '@libp2p/interface-libp2p' +import type { PubSub } from '@libp2p/interface-pubsub' +import type { Registrar } from '@libp2p/interface-registrar' +import type { EventEmitter } from '@libp2p/interfaces/events' +import type { Startable } from '@libp2p/interfaces/startable' + +export interface MockNetworkComponents { + peerId: PeerId + registrar: Registrar + connectionManager: ConnectionManager + pubsub?: PubSub + events: EventEmitter +} + +class MockNetwork { + private components: MockNetworkComponents[] = [] + + addNode (components: MockNetworkComponents): void { + this.components.push(components) + } + + getNode (peerId: PeerId | Multiaddr []): MockNetworkComponents { + if (Array.isArray(peerId) && peerId.length > 0) { + peerId = peerIdFromString(peerId[0].getPeerId() ?? '') + } else if (isPeerId(peerId)) { + for (const components of this.components) { + if (peerId.equals(components.peerId)) { + return components + } + } + } + + throw new CodeError('Peer not found', 'ERR_PEER_NOT_FOUND') + } + + reset (): void { + this.components = [] + } +} + +export const mockNetwork = new MockNetwork() + +export interface MockConnectionManagerComponents { + peerId: PeerId + registrar: Registrar + events: EventEmitter +} + +class MockConnectionManager implements ConnectionManager, Startable { + private connections: Connection[] = [] + private readonly components: MockConnectionManagerComponents + private started = false + + constructor (components: MockConnectionManagerComponents) { + this.components = components + } + + isStarted (): boolean { + return this.started + } + + async start (): Promise { + this.started = true + } + + async stop (): Promise { + for (const connection of this.connections) { + await this.closeConnections(connection.remotePeer) + } + + this.started = false + } + + getConnections (peerId?: PeerId): Connection[] { + if (peerId != null) { + return this.connections + .filter(c => c.remotePeer.toString() === peerId.toString()) + } + + return this.connections + } + + getConnectionsMap (): PeerMap { + const map = new PeerMap() + + for (const conn of this.connections) { + const conns: Connection[] = map.get(conn.remotePeer) ?? [] + conns.push(conn) + + map.set(conn.remotePeer, conns) + } + + return map + } + + async openConnection (peerId: PeerId | Multiaddr | Multiaddr[]): Promise { + if (this.components == null) { + throw new CodeError('Not initialized', 'ERR_NOT_INITIALIZED') + } + + if (isMultiaddr(peerId)) { + throw new CodeError('Dialing multiaddrs not supported', 'ERR_NOT_SUPPORTED') + } + + let existingConnections: Connection[] = [] + + if (Array.isArray(peerId) && peerId.length > 0) { + existingConnections = this.getConnections(peerIdFromString(peerId[0].getPeerId() ?? '')) + } else if (isPeerId(peerId)) { + existingConnections = this.getConnections(peerId) + } + + if (existingConnections.length > 0) { + return existingConnections[0] + } + + const componentsB = mockNetwork.getNode(peerId) + + const [aToB, bToA] = connectionPair(this.components, componentsB) + + // track connections + this.connections.push(aToB) + ;(componentsB.connectionManager as MockConnectionManager).connections.push(bToA) + + this.components.events.safeDispatchEvent('connection:open', { + detail: aToB + }) + + for (const protocol of this.components.registrar.getProtocols()) { + for (const topology of this.components.registrar.getTopologies(protocol)) { + topology.onConnect(componentsB.peerId, aToB) + } + } + + this.components.events.safeDispatchEvent('peer:connect', { detail: componentsB.peerId }) + + componentsB.events.safeDispatchEvent('connection:open', { + detail: bToA + }) + + for (const protocol of componentsB.registrar.getProtocols()) { + for (const topology of componentsB.registrar.getTopologies(protocol)) { + topology.onConnect(this.components.peerId, bToA) + } + } + + componentsB.events.safeDispatchEvent('peer:connect', { detail: this.components.peerId }) + + return aToB + } + + async closeConnections (peerId: PeerId): Promise { + if (this.components == null) { + throw new CodeError('Not initialized', 'ERR_NOT_INITIALIZED') + } + + const connections = this.getConnections(peerId) + + if (connections.length === 0) { + return + } + + const componentsB = mockNetwork.getNode(peerId) + + for (const protocol of this.components.registrar.getProtocols()) { + this.components.registrar.getTopologies(protocol).forEach(topology => { + topology.onDisconnect(componentsB.peerId) + }) + } + + for (const conn of connections) { + await conn.close() + } + + this.connections = this.connections.filter(c => !c.remotePeer.equals(peerId)) + + if (this.connections.filter(c => !c.remotePeer.equals(peerId)).length === 0) { + componentsB.events.safeDispatchEvent('peer:disconnect', { detail: peerId }) + } + + await componentsB.connectionManager?.closeConnections(this.components.peerId) + + if (componentsB.connectionManager?.getConnectionsMap().get(this.components.peerId) == null) { + componentsB.events.safeDispatchEvent('peer:disconnect', { detail: this.components.peerId }) + } + } + + async acceptIncomingConnection (): Promise { + return true + } + + afterUpgradeInbound (): void { + + } + + getDialQueue (): PendingDial[] { + return [] + } +} + +export function mockConnectionManager (components: MockConnectionManagerComponents): ConnectionManager { + return new MockConnectionManager(components) +} diff --git a/packages/interface-mocks/src/connection.ts b/packages/interface-mocks/src/connection.ts new file mode 100644 index 0000000000..ad9ab3a9f9 --- /dev/null +++ b/packages/interface-mocks/src/connection.ts @@ -0,0 +1,218 @@ +import * as STATUS from '@libp2p/interface-connection/status' +import { CodeError } from '@libp2p/interfaces/errors' +import { logger } from '@libp2p/logger' +import * as mss from '@libp2p/multistream-select' +import { peerIdFromString } from '@libp2p/peer-id' +import { duplexPair } from 'it-pair/duplex' +import { pipe } from 'it-pipe' +import { mockMultiaddrConnection } from './multiaddr-connection.js' +import { mockMuxer } from './muxer.js' +import { mockRegistrar } from './registrar.js' +import type { MultiaddrConnection, Connection, Stream, ConnectionStat, Direction } from '@libp2p/interface-connection' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Registrar } from '@libp2p/interface-registrar' +import type { StreamMuxer, StreamMuxerFactory } from '@libp2p/interface-stream-muxer' +import type { AbortOptions } from '@libp2p/interfaces' +import type { Multiaddr } from '@multiformats/multiaddr' +import type { Duplex, Source } from 'it-stream-types' +import type { Uint8ArrayList } from 'uint8arraylist' + +const log = logger('libp2p:mock-connection') + +export interface MockConnectionOptions { + direction?: Direction + registrar?: Registrar + muxerFactory?: StreamMuxerFactory +} + +interface MockConnectionInit { + remoteAddr: Multiaddr + remotePeer: PeerId + direction: Direction + maConn: MultiaddrConnection + muxer: StreamMuxer +} + +class MockConnection implements Connection { + public id: string + public remoteAddr: Multiaddr + public remotePeer: PeerId + public direction: Direction + public stat: ConnectionStat + public streams: Stream[] + public tags: string[] + + private readonly muxer: StreamMuxer + private readonly maConn: MultiaddrConnection + + constructor (init: MockConnectionInit) { + const { remoteAddr, remotePeer, direction, maConn, muxer } = init + + this.id = `mock-connection-${Math.random()}` + this.remoteAddr = remoteAddr + this.remotePeer = remotePeer + this.direction = direction + this.stat = { + status: STATUS.OPEN, + direction, + timeline: maConn.timeline, + multiplexer: 'test-multiplexer', + encryption: 'yes-yes-very-secure' + } + this.streams = [] + this.tags = [] + this.muxer = muxer + this.maConn = maConn + } + + async newStream (protocols: string | string[], options?: AbortOptions): Promise { + if (!Array.isArray(protocols)) { + protocols = [protocols] + } + + if (protocols.length === 0) { + throw new Error('protocols must have a length') + } + + if (this.stat.status !== STATUS.OPEN) { + throw new CodeError('connection must be open to create streams', 'ERR_CONNECTION_CLOSED') + } + + const id = `${Math.random()}` + const stream = await this.muxer.newStream(id) + const result = await mss.select(stream, protocols, options) + + const streamWithProtocol: Stream = { + ...stream, + ...result.stream, + stat: { + ...stream.stat, + direction: 'outbound', + protocol: result.protocol + } + } + + this.streams.push(streamWithProtocol) + + return streamWithProtocol + } + + addStream (stream: Stream): void { + this.streams.push(stream) + } + + removeStream (id: string): void { + this.streams = this.streams.filter(stream => stream.id !== id) + } + + async close (): Promise { + this.stat.status = STATUS.CLOSING + await this.maConn.close() + this.streams.forEach(s => { + s.close() + }) + this.stat.status = STATUS.CLOSED + this.stat.timeline.close = Date.now() + } +} + +export function mockConnection (maConn: MultiaddrConnection, opts: MockConnectionOptions = {}): Connection { + const remoteAddr = maConn.remoteAddr + const remotePeerIdStr = remoteAddr.getPeerId() ?? '12D3KooWCrhmFM1BCPGBkNzbPfDk4cjYmtAYSpZwUBC69Qg2kZyq' + + if (remotePeerIdStr == null) { + throw new Error('Remote multiaddr must contain a peer id') + } + + const remotePeer = peerIdFromString(remotePeerIdStr) + const direction = opts.direction ?? 'inbound' + const registrar = opts.registrar ?? mockRegistrar() + const muxerFactory = opts.muxerFactory ?? mockMuxer() + + const muxer = muxerFactory.createStreamMuxer({ + direction, + onIncomingStream: (muxedStream) => { + try { + mss.handle(muxedStream, registrar.getProtocols()) + .then(({ stream, protocol }) => { + log('%s: incoming stream opened on %s', direction, protocol) + muxedStream = { ...muxedStream, ...stream } + muxedStream.stat.protocol = protocol + + connection.addStream(muxedStream) + const { handler } = registrar.getHandler(protocol) + + handler({ connection, stream: muxedStream }) + }).catch(err => { + log.error(err) + }) + } catch (err: any) { + log.error(err) + } + }, + onStreamEnd: (muxedStream) => { + connection.removeStream(muxedStream.id) + } + }) + + void pipe( + maConn, muxer, maConn + ) + + const connection = new MockConnection({ + remoteAddr, + remotePeer, + direction, + maConn, + muxer + }) + + return connection +} + +export function mockStream (stream: Duplex, Source, Promise>): Stream { + return { + ...stream, + close: () => {}, + closeRead: () => {}, + closeWrite: () => {}, + abort: () => {}, + reset: () => {}, + stat: { + direction: 'outbound', + protocol: '/foo/1.0.0', + timeline: { + open: Date.now() + } + }, + metadata: {}, + id: `stream-${Date.now()}` + } +} + +export interface Peer { + peerId: PeerId + registrar: Registrar +} + +export function multiaddrConnectionPair (a: { peerId: PeerId, registrar: Registrar }, b: { peerId: PeerId, registrar: Registrar }): [ MultiaddrConnection, MultiaddrConnection ] { + const [peerBtoPeerA, peerAtoPeerB] = duplexPair() + + return [ + mockMultiaddrConnection(peerAtoPeerB, b.peerId), + mockMultiaddrConnection(peerBtoPeerA, a.peerId) + ] +} + +export function connectionPair (a: { peerId: PeerId, registrar: Registrar }, b: { peerId: PeerId, registrar: Registrar }): [ Connection, Connection ] { + const [peerBtoPeerA, peerAtoPeerB] = multiaddrConnectionPair(a, b) + + return [ + mockConnection(peerBtoPeerA, { + registrar: a.registrar + }), + mockConnection(peerAtoPeerB, { + registrar: b.registrar + }) + ] +} diff --git a/packages/interface-mocks/src/duplex.ts b/packages/interface-mocks/src/duplex.ts new file mode 100644 index 0000000000..736366c254 --- /dev/null +++ b/packages/interface-mocks/src/duplex.ts @@ -0,0 +1,10 @@ +import type { Duplex, Source } from 'it-stream-types' + +export function mockDuplex (): Duplex, Source, Promise> { + return { + source: (async function * () { + yield * [] + }()), + sink: async () => {} + } +} diff --git a/packages/interface-mocks/src/index.ts b/packages/interface-mocks/src/index.ts new file mode 100644 index 0000000000..8b78f1f7f3 --- /dev/null +++ b/packages/interface-mocks/src/index.ts @@ -0,0 +1,12 @@ +export { mockConnectionEncrypter } from './connection-encrypter.js' +export { mockConnectionGater } from './connection-gater.js' +export { mockConnectionManager, mockNetwork } from './connection-manager.js' +export { mockConnection, mockStream, connectionPair } from './connection.js' +export { mockMultiaddrConnection, mockMultiaddrConnPair } from './multiaddr-connection.js' +export { mockMuxer } from './muxer.js' +export { mockRegistrar } from './registrar.js' +export { mockUpgrader } from './upgrader.js' +export { mockDuplex } from './duplex.js' +export { mockMetrics } from './metrics.js' +export type { MockUpgraderInit } from './upgrader.js' +export type { MockNetworkComponents } from './connection-manager.js' diff --git a/packages/interface-mocks/src/metrics.ts b/packages/interface-mocks/src/metrics.ts new file mode 100644 index 0000000000..760ac8fcf1 --- /dev/null +++ b/packages/interface-mocks/src/metrics.ts @@ -0,0 +1,162 @@ +import type { MultiaddrConnection, Stream, Connection } from '@libp2p/interface-connection' +import type { Metric, MetricGroup, StopTimer, Metrics, CalculatedMetricOptions, MetricOptions } from '@libp2p/interface-metrics' + +class DefaultMetric implements Metric { + public value: number = 0 + + update (value: number): void { + this.value = value + } + + increment (value: number = 1): void { + this.value += value + } + + decrement (value: number = 1): void { + this.value -= value + } + + reset (): void { + this.value = 0 + } + + timer (): StopTimer { + const start = Date.now() + + return () => { + this.value = Date.now() - start + } + } +} + +class DefaultGroupMetric implements MetricGroup { + public values: Record = {} + + update (values: Record): void { + Object.entries(values).forEach(([key, value]) => { + this.values[key] = value + }) + } + + increment (values: Record): void { + Object.entries(values).forEach(([key, value]) => { + this.values[key] = this.values[key] ?? 0 + const inc = typeof value === 'number' ? value : 1 + + this.values[key] += Number(inc) + }) + } + + decrement (values: Record): void { + Object.entries(values).forEach(([key, value]) => { + this.values[key] = this.values[key] ?? 0 + const dec = typeof value === 'number' ? value : 1 + + this.values[key] -= Number(dec) + }) + } + + reset (): void { + this.values = {} + } + + timer (key: string): StopTimer { + const start = Date.now() + + return () => { + this.values[key] = Date.now() - start + } + } +} + +class MockMetrics implements Metrics { + public metrics = new Map() + + trackMultiaddrConnection (maConn: MultiaddrConnection): void { + + } + + trackProtocolStream (stream: Stream, connection: Connection): void { + + } + + registerMetric (name: string, opts: CalculatedMetricOptions): void + registerMetric (name: string, opts?: MetricOptions): Metric + registerMetric (name: string, opts: any): any { + if (name == null ?? name.trim() === '') { + throw new Error('Metric name is required') + } + + if (opts?.calculate != null) { + // calculated metric + this.metrics.set(name, opts.calculate) + return + } + + const metric = new DefaultMetric() + this.metrics.set(name, metric) + + return metric + } + + registerCounter (name: string, opts: CalculatedMetricOptions): void + registerCounter (name: string, opts?: MetricOptions): Metric + registerCounter (name: string, opts: any): any { + if (name == null ?? name.trim() === '') { + throw new Error('Metric name is required') + } + + if (opts?.calculate != null) { + // calculated metric + this.metrics.set(name, opts.calculate) + return + } + + const metric = new DefaultMetric() + this.metrics.set(name, metric) + + return metric + } + + registerMetricGroup (name: string, opts: CalculatedMetricOptions>): void + registerMetricGroup (name: string, opts?: MetricOptions): MetricGroup + registerMetricGroup (name: string, opts: any): any { + if (name == null ?? name.trim() === '') { + throw new Error('Metric name is required') + } + + if (opts?.calculate != null) { + // calculated metric + this.metrics.set(name, opts.calculate) + return + } + + const metric = new DefaultGroupMetric() + this.metrics.set(name, metric) + + return metric + } + + registerCounterGroup (name: string, opts: CalculatedMetricOptions>): void + registerCounterGroup (name: string, opts?: MetricOptions): MetricGroup + registerCounterGroup (name: string, opts: any): any { + if (name == null ?? name.trim() === '') { + throw new Error('Metric name is required') + } + + if (opts?.calculate != null) { + // calculated metric + this.metrics.set(name, opts.calculate) + return + } + + const metric = new DefaultGroupMetric() + this.metrics.set(name, metric) + + return metric + } +} + +export function mockMetrics (): () => Metrics { + return () => new MockMetrics() +} diff --git a/packages/interface-mocks/src/multiaddr-connection.ts b/packages/interface-mocks/src/multiaddr-connection.ts new file mode 100644 index 0000000000..868bbee1af --- /dev/null +++ b/packages/interface-mocks/src/multiaddr-connection.ts @@ -0,0 +1,67 @@ +import { multiaddr } from '@multiformats/multiaddr' +import { abortableSource } from 'abortable-iterator' +import { duplexPair } from 'it-pair/duplex' +import type { MultiaddrConnection } from '@libp2p/interface-connection' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Multiaddr } from '@multiformats/multiaddr' +import type { Duplex } from 'it-stream-types' + +export function mockMultiaddrConnection (source: Duplex> & Partial, peerId: PeerId): MultiaddrConnection { + const maConn: MultiaddrConnection = { + async close () { + + }, + timeline: { + open: Date.now() + }, + remoteAddr: multiaddr(`/ip4/127.0.0.1/tcp/4001/p2p/${peerId.toString()}`), + ...source + } + + return maConn +} + +export interface MockMultiaddrConnPairOptions { + addrs: Multiaddr[] + remotePeer: PeerId +} + +/** + * Returns both sides of a mocked MultiaddrConnection + */ +export function mockMultiaddrConnPair (opts: MockMultiaddrConnPairOptions): { inbound: MultiaddrConnection, outbound: MultiaddrConnection } { + const { addrs, remotePeer } = opts + const controller = new AbortController() + const [localAddr, remoteAddr] = addrs + const [inboundStream, outboundStream] = duplexPair() + + const outbound: MultiaddrConnection = { + ...outboundStream, + remoteAddr: remoteAddr.toString().includes(`/p2p/${remotePeer.toString()}`) ? remoteAddr : remoteAddr.encapsulate(`/p2p/${remotePeer.toString()}`), + timeline: { + open: Date.now() + }, + close: async () => { + outbound.timeline.close = Date.now() + controller.abort() + } + } + + const inbound: MultiaddrConnection = { + ...inboundStream, + remoteAddr: localAddr, + timeline: { + open: Date.now() + }, + close: async () => { + inbound.timeline.close = Date.now() + controller.abort() + } + } + + // Make the sources abortable so we can close them easily + inbound.source = abortableSource(inbound.source, controller.signal) + outbound.source = abortableSource(outbound.source, controller.signal) + + return { inbound, outbound } +} diff --git a/packages/interface-mocks/src/muxer.ts b/packages/interface-mocks/src/muxer.ts new file mode 100644 index 0000000000..00f4370d79 --- /dev/null +++ b/packages/interface-mocks/src/muxer.ts @@ -0,0 +1,447 @@ +import { CodeError } from '@libp2p/interfaces/errors' +import { type Logger, logger } from '@libp2p/logger' +import { abortableSource } from 'abortable-iterator' +import { anySignal } from 'any-signal' +import map from 'it-map' +import * as ndjson from 'it-ndjson' +import { pipe } from 'it-pipe' +import { type Pushable, pushable } from 'it-pushable' +import { Uint8ArrayList } from 'uint8arraylist' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { toString as uint8ArrayToString } from 'uint8arrays/to-string' +import type { Stream } from '@libp2p/interface-connection' +import type { StreamMuxer, StreamMuxerFactory, StreamMuxerInit } from '@libp2p/interface-stream-muxer' +import type { Source } from 'it-stream-types' + +let muxers = 0 +let streams = 0 +const MAX_MESSAGE_SIZE = 1024 * 1024 + +interface DataMessage { + id: string + type: 'data' + direction: 'initiator' | 'recipient' + chunk: string +} + +interface ResetMessage { + id: string + type: 'reset' + direction: 'initiator' | 'recipient' +} + +interface CloseMessage { + id: string + type: 'close' + direction: 'initiator' | 'recipient' +} + +interface CreateMessage { + id: string + type: 'create' + direction: 'initiator' +} + +type StreamMessage = DataMessage | ResetMessage | CloseMessage | CreateMessage + +class MuxedStream { + public id: string + public input: Pushable + public stream: Stream + public type: 'initiator' | 'recipient' + + private sinkEnded: boolean + private sourceEnded: boolean + private readonly abortController: AbortController + private readonly resetController: AbortController + private readonly closeController: AbortController + private readonly log: Logger + + constructor (init: { id: string, type: 'initiator' | 'recipient', push: Pushable, onEnd: (err?: Error) => void }) { + const { id, type, push, onEnd } = init + + this.log = logger(`libp2p:mock-muxer:stream:${id}:${type}`) + + this.id = id + this.type = type + this.abortController = new AbortController() + this.resetController = new AbortController() + this.closeController = new AbortController() + + this.sourceEnded = false + this.sinkEnded = false + + let endErr: Error | undefined + + const onSourceEnd = (err?: Error): void => { + if (this.sourceEnded) { + return + } + + this.log('onSourceEnd sink ended? %s', this.sinkEnded) + + this.sourceEnded = true + + if (err != null && endErr == null) { + endErr = err + } + + if (this.sinkEnded) { + this.stream.stat.timeline.close = Date.now() + + if (onEnd != null) { + onEnd(endErr) + } + } + } + + const onSinkEnd = (err?: Error): void => { + if (this.sinkEnded) { + return + } + + this.log('onSinkEnd source ended? %s', this.sourceEnded) + + this.sinkEnded = true + + if (err != null && endErr == null) { + endErr = err + } + + if (this.sourceEnded) { + this.stream.stat.timeline.close = Date.now() + + if (onEnd != null) { + onEnd(endErr) + } + } + } + + this.input = pushable({ + onEnd: onSourceEnd + }) + + this.stream = { + id, + sink: async (source) => { + if (this.sinkEnded) { + throw new CodeError('stream closed for writing', 'ERR_SINK_ENDED') + } + + const signal = anySignal([ + this.abortController.signal, + this.resetController.signal, + this.closeController.signal + ]) + + source = abortableSource(source, signal) + + try { + if (this.type === 'initiator') { + // If initiator, open a new stream + const createMsg: CreateMessage = { + id: this.id, + type: 'create', + direction: this.type + } + push.push(createMsg) + } + + const list = new Uint8ArrayList() + + for await (const chunk of source) { + list.append(chunk) + + while (list.length > 0) { + const available = Math.min(list.length, MAX_MESSAGE_SIZE) + const dataMsg: DataMessage = { + id, + type: 'data', + chunk: uint8ArrayToString(list.subarray(0, available), 'base64pad'), + direction: this.type + } + + push.push(dataMsg) + list.consume(available) + } + } + } catch (err: any) { + if (err.type === 'aborted' && err.message === 'The operation was aborted') { + if (this.closeController.signal.aborted) { + return + } + + if (this.resetController.signal.aborted) { + err.message = 'stream reset' + err.code = 'ERR_STREAM_RESET' + } + + if (this.abortController.signal.aborted) { + err.message = 'stream aborted' + err.code = 'ERR_STREAM_ABORT' + } + } + + // Send no more data if this stream was remotely reset + if (err.code !== 'ERR_STREAM_RESET') { + const resetMsg: ResetMessage = { + id, + type: 'reset', + direction: this.type + } + push.push(resetMsg) + } + + this.log('sink erred', err) + + this.input.end(err) + onSinkEnd(err) + return + } finally { + signal.clear() + } + + this.log('sink ended') + + onSinkEnd() + + const closeMsg: CloseMessage = { + id, + type: 'close', + direction: this.type + } + push.push(closeMsg) + }, + source: this.input, + + // Close for reading + close: () => { + this.stream.closeRead() + this.stream.closeWrite() + }, + + closeRead: () => { + this.input.end() + }, + + closeWrite: () => { + this.closeController.abort() + + const closeMsg: CloseMessage = { + id, + type: 'close', + direction: this.type + } + push.push(closeMsg) + onSinkEnd() + }, + + // Close for reading and writing (local error) + abort: (err: Error) => { + // End the source with the passed error + this.input.end(err) + this.abortController.abort() + onSinkEnd(err) + }, + + // Close immediately for reading and writing (remote error) + reset: () => { + const err = new CodeError('stream reset', 'ERR_STREAM_RESET') + this.resetController.abort() + this.input.end(err) + onSinkEnd(err) + }, + stat: { + direction: type === 'initiator' ? 'outbound' : 'inbound', + timeline: { + open: Date.now() + } + }, + metadata: {} + } + } +} + +class MockMuxer implements StreamMuxer { + public source: AsyncGenerator + public input: Pushable + public streamInput: Pushable + public name: string + public protocol: string = '/mock-muxer/1.0.0' + + private readonly closeController: AbortController + private readonly registryInitiatorStreams: Map + private readonly registryRecipientStreams: Map + private readonly options: StreamMuxerInit + + private readonly log: Logger + + constructor (init?: StreamMuxerInit) { + this.name = `muxer:${muxers++}` + this.log = logger(`libp2p:mock-muxer:${this.name}`) + this.registryInitiatorStreams = new Map() + this.registryRecipientStreams = new Map() + this.log('create muxer') + this.options = init ?? { direction: 'inbound' } + this.closeController = new AbortController() + // receives data from the muxer at the other end of the stream + this.source = this.input = pushable({ + onEnd: (err) => { + this.close(err) + } + }) + + // receives messages from all of the muxed streams + this.streamInput = pushable({ + objectMode: true + }) + } + + // receive incoming messages + async sink (source: Source): Promise { + try { + await pipe( + abortableSource(source, this.closeController.signal), + (source) => map(source, buf => uint8ArrayToString(buf.subarray())), + ndjson.parse, + async (source) => { + for await (const message of source) { + this.log.trace('-> %s %s %s', message.type, message.direction, message.id) + this.handleMessage(message) + } + } + ) + + this.log('muxed stream ended') + this.input.end() + } catch (err: any) { + this.log('muxed stream errored', err) + this.input.end(err) + } + } + + handleMessage (message: StreamMessage): void { + let muxedStream: MuxedStream | undefined + + const registry = message.direction === 'initiator' ? this.registryRecipientStreams : this.registryInitiatorStreams + + if (message.type === 'create') { + if (registry.has(message.id)) { + throw new Error(`Already had stream for ${message.id}`) + } + + muxedStream = this.createStream(message.id, 'recipient') + registry.set(muxedStream.stream.id, muxedStream) + + if (this.options.onIncomingStream != null) { + this.options.onIncomingStream(muxedStream.stream) + } + } + + muxedStream = registry.get(message.id) + + if (muxedStream == null) { + this.log.error(`No stream found for ${message.id}`) + + return + } + + if (message.type === 'data') { + muxedStream.input.push(new Uint8ArrayList(uint8ArrayFromString(message.chunk, 'base64pad'))) + } else if (message.type === 'reset') { + this.log('-> reset stream %s %s', muxedStream.type, muxedStream.stream.id) + muxedStream.stream.reset() + } else if (message.type === 'close') { + this.log('-> closing stream %s %s', muxedStream.type, muxedStream.stream.id) + muxedStream.stream.closeRead() + } + } + + get streams (): Stream[] { + return Array.from(this.registryRecipientStreams.values()) + .concat(Array.from(this.registryInitiatorStreams.values())) + .map(({ stream }) => stream) + } + + newStream (name?: string): Stream { + if (this.closeController.signal.aborted) { + throw new Error('Muxer already closed') + } + this.log('newStream %s', name) + const storedStream = this.createStream(name, 'initiator') + this.registryInitiatorStreams.set(storedStream.stream.id, storedStream) + + return storedStream.stream + } + + createStream (name?: string, type: 'initiator' | 'recipient' = 'initiator'): MuxedStream { + const id = name ?? `${this.name}:stream:${streams++}` + + this.log('createStream %s %s', type, id) + + const muxedStream: MuxedStream = new MuxedStream({ + id, + type, + push: this.streamInput, + onEnd: () => { + this.log('stream ended %s %s', type, id) + + if (type === 'initiator') { + this.registryInitiatorStreams.delete(id) + } else { + this.registryRecipientStreams.delete(id) + } + + if (this.options.onStreamEnd != null) { + this.options.onStreamEnd(muxedStream.stream) + } + } + }) + + return muxedStream + } + + close (err?: Error): void { + if (this.closeController.signal.aborted) return + this.log('closing muxed streams') + + if (err == null) { + this.streams.forEach(s => { + s.close() + }) + } else { + this.streams.forEach(s => { + s.abort(err) + }) + } + this.closeController.abort() + this.input.end(err) + } +} + +class MockMuxerFactory implements StreamMuxerFactory { + public protocol: string = '/mock-muxer/1.0.0' + + createStreamMuxer (init?: StreamMuxerInit): StreamMuxer { + const mockMuxer = new MockMuxer(init) + + void Promise.resolve().then(async () => { + void pipe( + mockMuxer.streamInput, + ndjson.stringify, + (source) => map(source, str => new Uint8ArrayList(uint8ArrayFromString(str))), + async (source) => { + for await (const buf of source) { + mockMuxer.input.push(buf.subarray()) + } + } + ) + }) + + return mockMuxer + } +} + +export function mockMuxer (): MockMuxerFactory { + return new MockMuxerFactory() +} diff --git a/packages/interface-mocks/src/peer-discovery.ts b/packages/interface-mocks/src/peer-discovery.ts new file mode 100644 index 0000000000..88a39a8c81 --- /dev/null +++ b/packages/interface-mocks/src/peer-discovery.ts @@ -0,0 +1,60 @@ +import { peerDiscovery } from '@libp2p/interface-peer-discovery' +import { EventEmitter } from '@libp2p/interfaces/events' +import * as PeerIdFactory from '@libp2p/peer-id-factory' +import { multiaddr } from '@multiformats/multiaddr' +import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface-peer-discovery' +import type { PeerInfo } from '@libp2p/interface-peer-info' + +interface MockDiscoveryInit { + discoveryDelay?: number +} + +/** + * Emits 'peer' events on discovery. + */ +export class MockDiscovery extends EventEmitter implements PeerDiscovery { + public readonly options: MockDiscoveryInit + private _isRunning: boolean + private _timer: any + + constructor (init = {}) { + super() + + this.options = init + this._isRunning = false + } + + readonly [peerDiscovery] = this + + start (): void { + this._isRunning = true + this._discoverPeer() + } + + stop (): void { + clearTimeout(this._timer) + this._isRunning = false + } + + isStarted (): boolean { + return this._isRunning + } + + _discoverPeer (): void { + if (!this._isRunning) return + + PeerIdFactory.createEd25519PeerId() + .then(peerId => { + this._timer = setTimeout(() => { + this.safeDispatchEvent('peer', { + detail: { + id: peerId, + multiaddrs: [multiaddr('/ip4/127.0.0.1/tcp/8000')], + protocols: [] + } + }) + }, this.options.discoveryDelay ?? 1000) + }) + .catch(() => {}) + } +} diff --git a/packages/interface-mocks/src/registrar.ts b/packages/interface-mocks/src/registrar.ts new file mode 100644 index 0000000000..c6c1482533 --- /dev/null +++ b/packages/interface-mocks/src/registrar.ts @@ -0,0 +1,87 @@ +import merge from 'merge-options' +import type { Connection } from '@libp2p/interface-connection' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { IncomingStreamData, Registrar, StreamHandler, Topology, StreamHandlerOptions, StreamHandlerRecord } from '@libp2p/interface-registrar' + +export class MockRegistrar implements Registrar { + private readonly topologies = new Map>() + private readonly handlers = new Map() + + getProtocols (): string[] { + return Array.from(this.handlers.keys()).sort() + } + + async handle (protocol: string, handler: StreamHandler, opts?: StreamHandlerOptions): Promise { + const options = merge.bind({ ignoreUndefined: true })({ + maxInboundStreams: 1, + maxOutboundStreams: 1 + }, opts) + + if (this.handlers.has(protocol)) { + throw new Error(`Handler already registered for protocol ${protocol}`) + } + + this.handlers.set(protocol, { + handler, + options + }) + } + + async unhandle (protocol: string): Promise { + this.handlers.delete(protocol) + } + + getHandler (protocol: string): StreamHandlerRecord { + const handler = this.handlers.get(protocol) + + if (handler == null) { + throw new Error(`No handler registered for protocol ${protocol}`) + } + + return handler + } + + async register (protocol: string, topology: Topology): Promise { + const id = `topology-id-${Math.random()}` + let topologies = this.topologies.get(protocol) + + if (topologies == null) { + topologies = [] + } + + topologies.push({ + id, + topology + }) + + this.topologies.set(protocol, topologies) + + return id + } + + unregister (id: string | string[]): void { + if (!Array.isArray(id)) { + id = [id] + } + + id.forEach(id => this.topologies.delete(id)) + } + + getTopologies (protocol: string): Topology[] { + return (this.topologies.get(protocol) ?? []).map(t => t.topology) + } +} + +export function mockRegistrar (): Registrar { + return new MockRegistrar() +} + +export async function mockIncomingStreamEvent (protocol: string, conn: Connection, remotePeer: PeerId): Promise { + return { + ...await conn.newStream([protocol]), + // @ts-expect-error incomplete implementation + connection: { + remotePeer + } + } +} diff --git a/packages/interface-mocks/src/upgrader.ts b/packages/interface-mocks/src/upgrader.ts new file mode 100644 index 0000000000..7739633495 --- /dev/null +++ b/packages/interface-mocks/src/upgrader.ts @@ -0,0 +1,49 @@ +import { mockConnection } from './connection.js' +import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection' +import type { Libp2pEvents } from '@libp2p/interface-libp2p' +import type { Registrar } from '@libp2p/interface-registrar' +import type { Upgrader, UpgraderOptions } from '@libp2p/interface-transport' +import type { EventEmitter } from '@libp2p/interfaces/events' + +export interface MockUpgraderInit { + registrar?: Registrar + events?: EventEmitter +} + +class MockUpgrader implements Upgrader { + private readonly registrar?: Registrar + private readonly events?: EventEmitter + + constructor (init: MockUpgraderInit) { + this.registrar = init.registrar + this.events = init.events + } + + async upgradeOutbound (multiaddrConnection: MultiaddrConnection, opts: UpgraderOptions = {}): Promise { + const connection = mockConnection(multiaddrConnection, { + direction: 'outbound', + registrar: this.registrar, + ...opts + }) + + this.events?.safeDispatchEvent('connection:open', { detail: connection }) + + return connection + } + + async upgradeInbound (multiaddrConnection: MultiaddrConnection, opts: UpgraderOptions = {}): Promise { + const connection = mockConnection(multiaddrConnection, { + direction: 'inbound', + registrar: this.registrar, + ...opts + }) + + this.events?.safeDispatchEvent('connection:open', { detail: connection }) + + return connection + } +} + +export function mockUpgrader (init: MockUpgraderInit = {}): Upgrader { + return new MockUpgrader(init) +} diff --git a/packages/interface-mocks/test/connection-encrypter.spec.ts b/packages/interface-mocks/test/connection-encrypter.spec.ts new file mode 100644 index 0000000000..73f0ca513e --- /dev/null +++ b/packages/interface-mocks/test/connection-encrypter.spec.ts @@ -0,0 +1,13 @@ +import tests from '@libp2p/interface-connection-encrypter-compliance-tests' +import { mockConnectionEncrypter } from '../src/connection-encrypter.js' + +describe('mock connection encrypter compliance tests', () => { + tests({ + async setup () { + return mockConnectionEncrypter() + }, + async teardown () { + + } + }) +}) diff --git a/packages/interface-mocks/test/connection.spec.ts b/packages/interface-mocks/test/connection.spec.ts new file mode 100644 index 0000000000..901d641fb8 --- /dev/null +++ b/packages/interface-mocks/test/connection.spec.ts @@ -0,0 +1,38 @@ +import tests from '@libp2p/interface-connection-compliance-tests' +import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { pipe } from 'it-pipe' +import { connectionPair } from '../src/connection.js' +import { mockRegistrar } from '../src/registrar.js' +import type { Connection } from '@libp2p/interface-connection' + +describe('mock connection compliance tests', () => { + let connections: Connection[] = [] + + tests({ + async setup () { + const componentsA = { + peerId: await createEd25519PeerId(), + registrar: mockRegistrar() + } + const componentsB = { + peerId: await createEd25519PeerId(), + registrar: mockRegistrar() + } + connections = connectionPair(componentsA, componentsB) + + await componentsB.registrar.handle('/echo/0.0.1', (data) => { + void pipe( + data.stream, + data.stream + ) + }) + + return connections[0] + }, + async teardown () { + await Promise.all(connections.map(async conn => { + await conn.close() + })) + } + }) +}) diff --git a/packages/interface-mocks/test/muxer.spec.ts b/packages/interface-mocks/test/muxer.spec.ts new file mode 100644 index 0000000000..4d7f280d67 --- /dev/null +++ b/packages/interface-mocks/test/muxer.spec.ts @@ -0,0 +1,13 @@ +import tests from '@libp2p/interface-stream-muxer-compliance-tests' +import { mockMuxer } from '../src/muxer.js' + +describe('mock stream muxer compliance tests', () => { + tests({ + async setup () { + return mockMuxer() + }, + async teardown () { + + } + }) +}) diff --git a/packages/interface-mocks/test/peer-discovery.spec.ts b/packages/interface-mocks/test/peer-discovery.spec.ts new file mode 100644 index 0000000000..ad2076499a --- /dev/null +++ b/packages/interface-mocks/test/peer-discovery.spec.ts @@ -0,0 +1,21 @@ +import tests from '@libp2p/interface-peer-discovery-compliance-tests' +import { MockDiscovery } from '../src/peer-discovery.js' + +describe('mock peer discovery compliance tests', () => { + let intervalId: any + + tests({ + async setup () { + const mockDiscovery = new MockDiscovery({ + discoveryDelay: 1 + }) + + intervalId = setInterval(mockDiscovery._discoverPeer, 1000) + + return mockDiscovery + }, + async teardown () { + clearInterval(intervalId) + } + }) +}) diff --git a/packages/interface-mocks/tsconfig.json b/packages/interface-mocks/tsconfig.json new file mode 100644 index 0000000000..d49aa5945a --- /dev/null +++ b/packages/interface-mocks/tsconfig.json @@ -0,0 +1,66 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interface-connection-compliance-tests" + }, + { + "path": "../interface-connection-encrypter" + }, + { + "path": "../interface-connection-encrypter-compliance-tests" + }, + { + "path": "../interface-connection-gater" + }, + { + "path": "../interface-connection-manager" + }, + { + "path": "../interface-libp2p" + }, + { + "path": "../interface-metrics" + }, + { + "path": "../interface-peer-discovery" + }, + { + "path": "../interface-peer-discovery-compliance-tests" + }, + { + "path": "../interface-peer-id" + }, + { + "path": "../interface-peer-info" + }, + { + "path": "../interface-pubsub" + }, + { + "path": "../interface-registrar" + }, + { + "path": "../interface-stream-muxer" + }, + { + "path": "../interface-stream-muxer-compliance-tests" + }, + { + "path": "../interface-transport" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-peer-discovery-compliance-tests/CHANGELOG.md b/packages/interface-peer-discovery-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..3095d8070c --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/CHANGELOG.md @@ -0,0 +1,90 @@ +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.7...@libp2p/interface-peer-discovery-compliance-tests-v2.0.8) (2023-05-04) + + +### Dependencies + +* update sibling dependencies ([45cf513](https://github.com/libp2p/js-libp2p-interfaces/commit/45cf513090d2a069bb6752ad2e231df65c76df36)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.6...@libp2p/interface-peer-discovery-compliance-tests-v2.0.7) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.5...@libp2p/interface-peer-discovery-compliance-tests-v2.0.6) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.4...@libp2p/interface-peer-discovery-compliance-tests-v2.0.5) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.3...@libp2p/interface-peer-discovery-compliance-tests-v2.0.4) (2023-01-03) + + +### Bug Fixes + +* refactor peer discovery compliance test ([#328](https://github.com/libp2p/js-libp2p-interfaces/issues/328)) ([87b4608](https://github.com/libp2p/js-libp2p-interfaces/commit/87b4608ae4c373c8dd59b1b68a63293fe9e15d69)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.2...@libp2p/interface-peer-discovery-compliance-tests-v2.0.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.1...@libp2p/interface-peer-discovery-compliance-tests-v2.0.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v2.0.0...@libp2p/interface-peer-discovery-compliance-tests-v2.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v1.0.2...@libp2p/interface-peer-discovery-compliance-tests-v2.0.0) (2022-10-12) + + +### ⚠ BREAKING CHANGES + +* modules no longer implement `Initializable` instead switching to constructor injection + +### Bug Fixes + +* remove @libp2p/components ([#301](https://github.com/libp2p/js-libp2p-interfaces/issues/301)) ([1d37dc6](https://github.com/libp2p/js-libp2p-interfaces/commit/1d37dc6d3197838a71895d5769ad8bba6eb38fd3)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v1.0.1...@libp2p/interface-peer-discovery-compliance-tests-v1.0.2) (2022-09-21) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-peer-discovery-compliance-tests-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-compliance-tests-v1.0.0...@libp2p/interface-peer-discovery-compliance-tests-v1.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) diff --git a/packages/interface-peer-discovery-compliance-tests/LICENSE b/packages/interface-peer-discovery-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-peer-discovery-compliance-tests/LICENSE-APACHE b/packages/interface-peer-discovery-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-peer-discovery-compliance-tests/LICENSE-MIT b/packages/interface-peer-discovery-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-peer-discovery-compliance-tests/README.md b/packages/interface-peer-discovery-compliance-tests/README.md new file mode 100644 index 0000000000..b59ca18214 --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/README.md @@ -0,0 +1,55 @@ +# @libp2p/interface-peer-discovery-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for implementations of the libp2p Peer Discovery interface + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-peer-discovery-compliance-tests +``` + +## Usage + +```js +import tests from '@libp2p/interface-peer-discovery-compliance-tests' + +describe('your peer discovery implementation', () => { + tests({ + // Options should be passed to your implementation + async setup (options) { + return new YourImplementation() + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-peer-discovery-compliance-tests/package.json b/packages/interface-peer-discovery-compliance-tests/package.json new file mode 100644 index 0000000000..c09f705e82 --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/package.json @@ -0,0 +1,142 @@ +{ + "name": "@libp2p/interface-peer-discovery-compliance-tests", + "version": "2.0.8", + "description": "Compliance tests for implementations of the libp2p Peer Discovery interface", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-peer-discovery-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-peer-discovery": "^2.0.0", + "@libp2p/interfaces": "^3.0.0", + "@multiformats/multiaddr": "^12.0.0", + "aegir": "^39.0.5", + "delay": "^6.0.0", + "p-defer": "^4.0.0" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-peer-discovery-compliance-tests/src/index.ts b/packages/interface-peer-discovery-compliance-tests/src/index.ts new file mode 100644 index 0000000000..64c751b59c --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/src/index.ts @@ -0,0 +1,90 @@ +import { start, stop } from '@libp2p/interfaces/startable' +import { isMultiaddr } from '@multiformats/multiaddr' +import { expect } from 'aegir/chai' +import delay from 'delay' +import pDefer from 'p-defer' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { PeerDiscovery } from '@libp2p/interface-peer-discovery' + +export default (common: TestSetup): void => { + describe('interface-peer-discovery compliance tests', () => { + let discovery: PeerDiscovery + + beforeEach(async () => { + discovery = await common.setup() + }) + + afterEach('ensure discovery was stopped', async () => { + await stop(discovery) + + await common.teardown() + }) + + it('can start the service', async () => { + await start(discovery) + }) + + it('can start and stop the service', async () => { + await start(discovery) + await stop(discovery) + }) + + it('should not fail to stop the service if it was not started', async () => { + await stop(discovery) + }) + + it('should not fail to start the service if it is already started', async () => { + await start(discovery) + await start(discovery) + }) + + it('should emit a peer event after start', async () => { + const defer = pDefer() + + discovery.addEventListener('peer', (evt) => { + const { id, multiaddrs } = evt.detail + expect(id).to.exist() + expect(id) + .to.have.property('type') + .that.is.oneOf(['RSA', 'Ed25519', 'secp256k1']) + expect(multiaddrs).to.exist() + + multiaddrs.forEach((m) => expect(isMultiaddr(m)).to.eql(true)) + + defer.resolve() + }) + + await start(discovery) + + await defer.promise + }) + + it('should not receive a peer event before start', async () => { + discovery.addEventListener('peer', () => { + throw new Error('should not receive a peer event before start') + }) + + await delay(2000) + }) + + it('should not receive a peer event after stop', async () => { + const deferStart = pDefer() + + discovery.addEventListener('peer', () => { + deferStart.resolve() + }) + + await start(discovery) + + await deferStart.promise + + await stop(discovery) + + discovery.addEventListener('peer', () => { + throw new Error('should not receive a peer event after stop') + }) + + await delay(2000) + }) + }) +} diff --git a/packages/interface-peer-discovery-compliance-tests/tsconfig.json b/packages/interface-peer-discovery-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..faf685538c --- /dev/null +++ b/packages/interface-peer-discovery-compliance-tests/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-peer-discovery" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-peer-discovery/CHANGELOG.md b/packages/interface-peer-discovery/CHANGELOG.md new file mode 100644 index 0000000000..778f7bfde4 --- /dev/null +++ b/packages/interface-peer-discovery/CHANGELOG.md @@ -0,0 +1,69 @@ +## [@libp2p/interface-peer-discovery-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.1.1...@libp2p/interface-peer-discovery-v2.0.0) (2023-05-04) + + +### ⚠ BREAKING CHANGES + +* the `symbol` export is now named `peerDiscovery` and the getter with that name should return an instance of `PeerDiscovery` + +### Features + +* rename peer discovery symbol to peerDiscovery ([#394](https://github.com/libp2p/js-libp2p-interfaces/issues/394)) ([5957c77](https://github.com/libp2p/js-libp2p-interfaces/commit/5957c77718df6e6336ca22386d8c03a045fd1d89)) + +## [@libp2p/interface-peer-discovery-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.1.0...@libp2p/interface-peer-discovery-v1.1.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-peer-discovery-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.0.5...@libp2p/interface-peer-discovery-v1.1.0) (2023-04-27) + + +### Features + +* add routing symbols ([#388](https://github.com/libp2p/js-libp2p-interfaces/issues/388)) ([9ee7691](https://github.com/libp2p/js-libp2p-interfaces/commit/9ee76915d2b8298d99557e105c4f71d585e97e7d)) + +## [@libp2p/interface-peer-discovery-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.0.4...@libp2p/interface-peer-discovery-v1.0.5) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-peer-discovery-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.0.3...@libp2p/interface-peer-discovery-v1.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-peer-discovery-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.0.2...@libp2p/interface-peer-discovery-v1.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-peer-discovery-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.0.1...@libp2p/interface-peer-discovery-v1.0.2) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-peer-discovery-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-discovery-v1.0.0...@libp2p/interface-peer-discovery-v1.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) diff --git a/packages/interface-peer-discovery/LICENSE b/packages/interface-peer-discovery/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-peer-discovery/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-peer-discovery/LICENSE-APACHE b/packages/interface-peer-discovery/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-peer-discovery/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-peer-discovery/LICENSE-MIT b/packages/interface-peer-discovery/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-peer-discovery/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-peer-discovery/README.md b/packages/interface-peer-discovery/README.md new file mode 100644 index 0000000000..c7bcc6798e --- /dev/null +++ b/packages/interface-peer-discovery/README.md @@ -0,0 +1,118 @@ +# @libp2p/interface-peer-discovery + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Peer Discovery interface for libp2p + +## Table of contents + +- [Install](#install) +- [Modules that implement the interface](#modules-that-implement-the-interface) +- [Badge](#badge) +- [Usage](#usage) + - [Node.js](#nodejs) +- [API](#api) + - [`start` the service](#start-the-service) + - [`stop` the service](#stop-the-service) + - [discovering peers](#discovering-peers) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-peer-discovery +``` + +The primary goal of this module is to enable developers to pick and/or swap their Peer Discovery modules as they see fit for their application, without having to go through shims or compatibility issues. This module and test suite was heavily inspired by [abstract-blob-store](https://github.com/maxogden/abstract-blob-store). + +Publishing a test suite as a module lets multiple modules all ensure compatibility since they use the same test suite. + +The API is presented with both Node.js and Go primitives, however, there is not actual limitations for it to be extended for any other language, pushing forward the cross compatibility and interop through different stacks. + +## Modules that implement the interface + +- [JavaScript libp2p-mdns](https://github.com/libp2p/js-libp2p-mdns) +- [JavaScript libp2p-bootstrap](https://github.com/libp2p/js-libp2p-bootstrap) +- [JavaScript libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) +- [JavaScript libp2p-webrtc-star](https://github.com/libp2p/js-libp2p-webrtc-star) +- [JavaScript libp2p-websocket-star](https://github.com/libp2p/js-libp2p-websocket-star) +- [TypeScript discv5](https://github.com/chainsafe/discv5) + +Send a PR to add a new one if you happen to find or write one. + +## Badge + +Include this badge in your readme if you make a new module that uses interface-peer-discovery API. + +![](img/badge.png) + +## Usage + +### Node.js + +Install `interface-discovery` as one of the dependencies of your project and as a test file. Then, using `mocha` (for JavaScript) or a test runner with compatible API, do: + +```js +const tests = require('libp2p-interfaces-compliance-tests/peer-discovery') + +describe('your discovery', () => { + // use all of the test suits + tests({ + setup () { + return YourDiscovery + }, + teardown () { + // Clean up any resources created by setup() + } + }) +}) +``` + +## API + +A valid (read: that follows this abstraction) Peer Discovery module must implement the following API: + +### `start` the service + +- `await discovery.start()` + +Start the discovery service. + +It returns a `Promise` + +### `stop` the service + +- `await discovery.stop()` + +Stop the discovery service. + +It returns a `Promise` + +### discovering peers + +- `discovery.on('peer', (peerData) => {})` + +Every time a peer is discovered by a discovery service, it emits a `peer` event with the discovered peer's information, which must contain the following properties: + +- `<`[`PeerId`](https://github.com/libp2p/js-peer-id)`>` `peerData.id` +- `>` `peerData.multiaddrs` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-peer-discovery/img/badge.png b/packages/interface-peer-discovery/img/badge.png new file mode 100644 index 0000000000..785abc493c Binary files /dev/null and b/packages/interface-peer-discovery/img/badge.png differ diff --git a/packages/interface-peer-discovery/img/badge.sketch b/packages/interface-peer-discovery/img/badge.sketch new file mode 100644 index 0000000000..51a982d06d Binary files /dev/null and b/packages/interface-peer-discovery/img/badge.sketch differ diff --git a/packages/interface-peer-discovery/img/badge.svg b/packages/interface-peer-discovery/img/badge.svg new file mode 100644 index 0000000000..8ecfc6dee3 --- /dev/null +++ b/packages/interface-peer-discovery/img/badge.svg @@ -0,0 +1,39 @@ + + + + badge + Created with Sketch. + + + + + + + + + + + + Peer Discovery + + + Compatibl + e + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/interface-peer-discovery/package.json b/packages/interface-peer-discovery/package.json new file mode 100644 index 0000000000..05ccd1766d --- /dev/null +++ b/packages/interface-peer-discovery/package.json @@ -0,0 +1,140 @@ +{ + "name": "@libp2p/interface-peer-discovery", + "version": "2.0.0", + "description": "Peer Discovery interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-peer-discovery#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-info": "^1.0.0", + "@libp2p/interfaces": "^3.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-peer-discovery/src/index.ts b/packages/interface-peer-discovery/src/index.ts new file mode 100644 index 0000000000..b0840503d6 --- /dev/null +++ b/packages/interface-peer-discovery/src/index.ts @@ -0,0 +1,29 @@ +import type { PeerInfo } from '@libp2p/interface-peer-info' +import type { EventEmitter } from '@libp2p/interfaces/events' + +/** + * Any object that implements this Symbol as a property should return a + * PeerDiscovery instance as the property value, similar to how + * `Symbol.Iterable` can be used to return an `Iterable` from an `Iterator`. + * + * @example + * + * ```js + * import { peerDiscovery, PeerDiscovery } from '@libp2p/peer-discovery' + * + * class MyPeerDiscoverer implements PeerDiscovery { + * get [peerDiscovery] () { + * return this + * } + * + * // ...other methods + * } + * ``` + */ +export const peerDiscovery = Symbol.for('@libp2p/peer-discovery') + +export interface PeerDiscoveryEvents { + 'peer': CustomEvent +} + +export interface PeerDiscovery extends EventEmitter {} diff --git a/packages/interface-peer-discovery/tsconfig.json b/packages/interface-peer-discovery/tsconfig.json new file mode 100644 index 0000000000..84bbd0ffe3 --- /dev/null +++ b/packages/interface-peer-discovery/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-info" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-peer-id/CHANGELOG.md b/packages/interface-peer-id/CHANGELOG.md new file mode 100644 index 0000000000..268e8ca277 --- /dev/null +++ b/packages/interface-peer-id/CHANGELOG.md @@ -0,0 +1,108 @@ +## [@libp2p/interface-peer-id-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v2.0.1...@libp2p/interface-peer-id-v2.0.2) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-peer-id-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v2.0.0...@libp2p/interface-peer-id-v2.0.1) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-peer-id-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.1.2...@libp2p/interface-peer-id-v2.0.0) (2023-01-06) + + +### ⚠ BREAKING CHANGES + +* bump multiformats from 10.0.3 to 11.0.0 (#329) + +### Dependencies + +* bump multiformats from 10.0.3 to 11.0.0 ([#329](https://github.com/libp2p/js-libp2p-interfaces/issues/329)) ([ba3a98b](https://github.com/libp2p/js-libp2p-interfaces/commit/ba3a98be61e3cf0996fefbd3004e974bb41ad2f0)) + +## [@libp2p/interface-peer-id-v1.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.1.1...@libp2p/interface-peer-id-v1.1.2) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-peer-id-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.1.0...@libp2p/interface-peer-id-v1.1.1) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-peer-id-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.0.6...@libp2p/interface-peer-id-v1.1.0) (2022-12-07) + + +### Features + +* expose supported peer id types ([#318](https://github.com/libp2p/js-libp2p-interfaces/issues/318)) ([1197484](https://github.com/libp2p/js-libp2p-interfaces/commit/11974843445a7f4792192340c0697d40bf87fddc)) + +## [@libp2p/interface-peer-id-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.0.5...@libp2p/interface-peer-id-v1.0.6) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-peer-id-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.0.4...@libp2p/interface-peer-id-v1.0.5) (2022-10-12) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* bump multiformats from 9.9.0 to 10.0.0 ([#302](https://github.com/libp2p/js-libp2p-interfaces/issues/302)) ([fe11d69](https://github.com/libp2p/js-libp2p-interfaces/commit/fe11d69b6aca3dd6ef6053bec27b534ec9908aa1)) + +## [@libp2p/interface-peer-id-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.0.3...@libp2p/interface-peer-id-v1.0.4) (2022-06-27) + + +### Trivial Changes + +* update `peer-id` link to new implementation ([#261](https://github.com/libp2p/js-libp2p-interfaces/issues/261)) ([a2dda7d](https://github.com/libp2p/js-libp2p-interfaces/commit/a2dda7d0cfa33737ebc6bb4ae56de5b55e951c63)) + +## [@libp2p/interface-peer-id-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.0.2...@libp2p/interface-peer-id-v1.0.3) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-peer-id-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.0.1...@libp2p/interface-peer-id-v1.0.2) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) + +## [@libp2p/interface-peer-id-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-id-v1.0.0...@libp2p/interface-peer-id-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-peer-id-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-peer-id/LICENSE b/packages/interface-peer-id/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-peer-id/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-peer-id/LICENSE-APACHE b/packages/interface-peer-id/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-peer-id/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-peer-id/LICENSE-MIT b/packages/interface-peer-id/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-peer-id/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-peer-id/README.md b/packages/interface-peer-id/README.md new file mode 100644 index 0000000000..3246aa028b --- /dev/null +++ b/packages/interface-peer-id/README.md @@ -0,0 +1,80 @@ +# @libp2p/interface-peer-id + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Peer Identifier interface for libp2p + +## Table of contents + +- [Install](#install) +- [Modules that implement the interface](#modules-that-implement-the-interface) +- [Badge](#badge) +- [Usage](#usage) + - [Node.js](#nodejs) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-peer-id +``` + +The primary goal of this module is to enable developers to implement PeerId modules. This module and test suite was heavily inspired by earlier implementation of [PeerId](https://github.com/libp2p/js-peer-id). + +Publishing a test suite as a module lets multiple modules all ensure compatibility since they use the same test suite. + +The API is presented with both Node.js and Go primitives, however, there is not actual limitations for it to be extended for any other language, pushing forward the cross compatibility and interop through different stacks. + +## Modules that implement the interface + +- [JavaScript libp2p-peer-id](https://github.com/libp2p/js-libp2p-peer-id) + +Send a PR to add a new one if you happen to find or write one. + +## Badge + +Include this badge in your readme if you make a new module that uses interface-peer-id API. + +![](/img/badge.png) + +## Usage + +### Node.js + +Install `libp2p-interfaces-compliance-tests` as one of the development dependencies of your project and as a test file. Then, using `mocha` (for JavaScript) or a test runner with compatible API, do: + +```js +const tests = require('libp2p-interfaces-compliance-tests/peer-id') + +describe('your peer id', () => { + // use all of the test suits + tests({ + setup () { + return YourPeerIdFactory + }, + teardown () { + // Clean up any resources created by setup() + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-peer-id/package.json b/packages/interface-peer-id/package.json new file mode 100644 index 0000000000..3a5610ae56 --- /dev/null +++ b/packages/interface-peer-id/package.json @@ -0,0 +1,139 @@ +{ + "name": "@libp2p/interface-peer-id", + "version": "2.0.2", + "description": "Peer Identifier interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-peer-id#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "multiformats": "^11.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-peer-id/src/index.ts b/packages/interface-peer-id/src/index.ts new file mode 100644 index 0000000000..39b629141d --- /dev/null +++ b/packages/interface-peer-id/src/index.ts @@ -0,0 +1,39 @@ +import type { CID } from 'multiformats/cid' +import type { MultihashDigest } from 'multiformats/hashes/interface' + +export type PeerIdType = 'RSA' | 'Ed25519' | 'secp256k1' + +interface BasePeerId { + readonly type: PeerIdType + readonly multihash: MultihashDigest + readonly privateKey?: Uint8Array + readonly publicKey?: Uint8Array + + toString: () => string + toCID: () => CID + toBytes: () => Uint8Array + equals: (other: PeerId | Uint8Array | string) => boolean +} + +export interface RSAPeerId extends BasePeerId { + readonly type: 'RSA' + readonly publicKey?: Uint8Array +} + +export interface Ed25519PeerId extends BasePeerId { + readonly type: 'Ed25519' + readonly publicKey: Uint8Array +} + +export interface Secp256k1PeerId extends BasePeerId { + readonly type: 'secp256k1' + readonly publicKey: Uint8Array +} + +export type PeerId = RSAPeerId | Ed25519PeerId | Secp256k1PeerId + +export const symbol = Symbol.for('@libp2p/peer-id') + +export function isPeerId (other: any): other is PeerId { + return other != null && Boolean(other[symbol]) +} diff --git a/packages/interface-peer-id/tsconfig.json b/packages/interface-peer-id/tsconfig.json new file mode 100644 index 0000000000..5fe8ea40d7 --- /dev/null +++ b/packages/interface-peer-id/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ] +} diff --git a/packages/interface-peer-info/CHANGELOG.md b/packages/interface-peer-info/CHANGELOG.md new file mode 100644 index 0000000000..e4ac0e783d --- /dev/null +++ b/packages/interface-peer-info/CHANGELOG.md @@ -0,0 +1,91 @@ +## [@libp2p/interface-peer-info-v1.0.10](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.9...@libp2p/interface-peer-info-v1.0.10) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-peer-info-v1.0.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.8...@libp2p/interface-peer-info-v1.0.9) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-peer-info-v1.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.7...@libp2p/interface-peer-info-v1.0.8) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-peer-info-v1.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.6...@libp2p/interface-peer-info-v1.0.7) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-peer-info-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.5...@libp2p/interface-peer-info-v1.0.6) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-peer-info-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.4...@libp2p/interface-peer-info-v1.0.5) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-peer-info-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.3...@libp2p/interface-peer-info-v1.0.4) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-peer-info-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.2...@libp2p/interface-peer-info-v1.0.3) (2022-09-21) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-peer-info-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.1...@libp2p/interface-peer-info-v1.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-peer-info-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-info-v1.0.0...@libp2p/interface-peer-info-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-peer-info-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-peer-info/LICENSE b/packages/interface-peer-info/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-peer-info/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-peer-info/LICENSE-APACHE b/packages/interface-peer-info/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-peer-info/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-peer-info/LICENSE-MIT b/packages/interface-peer-info/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-peer-info/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-peer-info/README.md b/packages/interface-peer-info/README.md new file mode 100644 index 0000000000..32d57fa659 --- /dev/null +++ b/packages/interface-peer-info/README.md @@ -0,0 +1,36 @@ +# @libp2p/interface-peer-info + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Peer Info interface for libp2p + +## Table of contents + +- [Install](#install) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-peer-info +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-peer-info/package.json b/packages/interface-peer-info/package.json new file mode 100644 index 0000000000..3916e089be --- /dev/null +++ b/packages/interface-peer-info/package.json @@ -0,0 +1,140 @@ +{ + "name": "@libp2p/interface-peer-info", + "version": "1.0.10", + "description": "Peer Info interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-peer-info#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-id": "^2.0.0", + "@multiformats/multiaddr": "^12.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-peer-info/src/index.ts b/packages/interface-peer-info/src/index.ts new file mode 100644 index 0000000000..59ae2b5d33 --- /dev/null +++ b/packages/interface-peer-info/src/index.ts @@ -0,0 +1,8 @@ +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Multiaddr } from '@multiformats/multiaddr' + +export interface PeerInfo { + id: PeerId + multiaddrs: Multiaddr[] + protocols: string[] +} diff --git a/packages/interface-peer-info/tsconfig.json b/packages/interface-peer-info/tsconfig.json new file mode 100644 index 0000000000..d8db0b667f --- /dev/null +++ b/packages/interface-peer-info/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-peer-routing/CHANGELOG.md b/packages/interface-peer-routing/CHANGELOG.md new file mode 100644 index 0000000000..a6d8da477d --- /dev/null +++ b/packages/interface-peer-routing/CHANGELOG.md @@ -0,0 +1,79 @@ +## [@libp2p/interface-peer-routing-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.1.0...@libp2p/interface-peer-routing-v1.1.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-peer-routing-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.8...@libp2p/interface-peer-routing-v1.1.0) (2023-04-27) + + +### Features + +* add routing symbols ([#388](https://github.com/libp2p/js-libp2p-interfaces/issues/388)) ([9ee7691](https://github.com/libp2p/js-libp2p-interfaces/commit/9ee76915d2b8298d99557e105c4f71d585e97e7d)) + +## [@libp2p/interface-peer-routing-v1.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.7...@libp2p/interface-peer-routing-v1.0.8) (2023-03-09) + + +### Documentation + +* update content/peer routing interface comments ([#346](https://github.com/libp2p/js-libp2p-interfaces/issues/346)) ([8080944](https://github.com/libp2p/js-libp2p-interfaces/commit/8080944d3c3a81834c6b432843441996cd9e34e5)) + +## [@libp2p/interface-peer-routing-v1.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.6...@libp2p/interface-peer-routing-v1.0.7) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-peer-routing-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.5...@libp2p/interface-peer-routing-v1.0.6) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-peer-routing-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.4...@libp2p/interface-peer-routing-v1.0.5) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-peer-routing-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.3...@libp2p/interface-peer-routing-v1.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-peer-routing-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.2...@libp2p/interface-peer-routing-v1.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-peer-routing-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.1...@libp2p/interface-peer-routing-v1.0.2) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-peer-routing-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-routing-v1.0.0...@libp2p/interface-peer-routing-v1.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) diff --git a/packages/interface-peer-routing/LICENSE b/packages/interface-peer-routing/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-peer-routing/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-peer-routing/LICENSE-APACHE b/packages/interface-peer-routing/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-peer-routing/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-peer-routing/LICENSE-MIT b/packages/interface-peer-routing/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-peer-routing/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-peer-routing/README.md b/packages/interface-peer-routing/README.md new file mode 100644 index 0000000000..cfbeb3c47a --- /dev/null +++ b/packages/interface-peer-routing/README.md @@ -0,0 +1,83 @@ +# @libp2p/interface-peer-routing + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Peer Routing interface for libp2p + +## Table of contents + +- - [Install](#install) +- [Modules that implement the interface](#modules-that-implement-the-interface) +- [Badge](#badge) +- [How to use the battery of tests](#how-to-use-the-battery-of-tests) + - [Node.js](#nodejs) +- [API](#api) + - - [findPeer](#findpeer) + - [API Docs](#api-docs) + - [License](#license) + - [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-peer-routing +``` + +The primary goal of this module is to enable developers to pick and swap their Peer Routing module as they see fit for their libp2p installation, without having to go through shims or compatibility issues. This module and test suite were heavily inspired by abstract-blob-store and interface-stream-muxer. + +Publishing a test suite as a module lets multiple modules all ensure compatibility since they use the same test suite. + +# Modules that implement the interface + +- [JavaScript libp2p-kad-dht](https://github.com/libp2p/js-libp2p-kad-dht) +- [JavaScript libp2p-delegated-peer-routing](https://github.com/libp2p/js-libp2p-delegated-peer-routing) + +# Badge + +Include this badge in your readme if you make a module that is compatible with the interface-record-store API. You can validate this by running the tests. + +![](img/badge.png) + +# How to use the battery of tests + +## Node.js + +TBD + +# API + +A valid (read: that follows this abstraction) Peer Routing module must implement the following API. + +### findPeer + +- `findPeer(peerId)` + +Query the network for all multiaddresses associated with a `PeerId`. + +**Parameters** + +- [peerId](https://github.com/libp2p/js-peer-id). + +**Returns** + +It returns the [peerId](https://github.com/libp2p/js-peer-id) together with the known peers [multiaddrs](https://github.com/multiformats/js-multiaddr), as follows: + +`Promise<{ id: PeerId, multiaddrs: Multiaddr[] }>` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-peer-routing/img/badge.png b/packages/interface-peer-routing/img/badge.png new file mode 100644 index 0000000000..44127db9ee Binary files /dev/null and b/packages/interface-peer-routing/img/badge.png differ diff --git a/packages/interface-peer-routing/img/badge.sketch b/packages/interface-peer-routing/img/badge.sketch new file mode 100644 index 0000000000..614a374496 Binary files /dev/null and b/packages/interface-peer-routing/img/badge.sketch differ diff --git a/packages/interface-peer-routing/img/badge.svg b/packages/interface-peer-routing/img/badge.svg new file mode 100644 index 0000000000..f3c41b0470 --- /dev/null +++ b/packages/interface-peer-routing/img/badge.svg @@ -0,0 +1,19 @@ + + + + badge + Created with Sketch. + + + + + Peer Routin + g + + + Compatibl + e + + + + \ No newline at end of file diff --git a/packages/interface-peer-routing/package.json b/packages/interface-peer-routing/package.json new file mode 100644 index 0000000000..c7e022b1bd --- /dev/null +++ b/packages/interface-peer-routing/package.json @@ -0,0 +1,141 @@ +{ + "name": "@libp2p/interface-peer-routing", + "version": "1.1.1", + "description": "Peer Routing interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-peer-routing#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interface-peer-info": "^1.0.0", + "@libp2p/interfaces": "^3.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-peer-routing/src/index.ts b/packages/interface-peer-routing/src/index.ts new file mode 100644 index 0000000000..d4bbef25c8 --- /dev/null +++ b/packages/interface-peer-routing/src/index.ts @@ -0,0 +1,53 @@ +import type { PeerId } from '@libp2p/interface-peer-id' +import type { PeerInfo } from '@libp2p/interface-peer-info' +import type { AbortOptions } from '@libp2p/interfaces' + +/** + * Any object that implements this Symbol as a property should return a + * PeerRouting instance as the property value, similar to how + * `Symbol.Iterable` can be used to return an `Iterable` from an `Iterator`. + * + * @example + * + * ```js + * import { peerRouting, PeerRouting } from '@libp2p/peer-routing' + * + * class MyPeerRouter implements PeerRouting { + * get [peerRouting] () { + * return this + * } + * + * // ...other methods + * } + * ``` + */ +export const peerRouting = Symbol.for('@libp2p/peer-routing') + +export interface PeerRouting { + /** + * Searches the network for peer info corresponding to the passed peer id. + * + * @example + * + * ```js + * // ... + * const peer = await peerRouting.findPeer(peerId, options) + * ``` + */ + findPeer: (peerId: PeerId, options?: AbortOptions) => Promise + + /** + * Search the network for peers that are closer to the passed key. Peer + * info should be yielded in ever-increasing closeness to the key. + * + * @example + * + * ```js + * // Iterate over the closest peers found for the given key + * for await (const peer of peerRouting.getClosestPeers(key)) { + * console.log(peer.id, peer.multiaddrs) + * } + * ``` + */ + getClosestPeers: (key: Uint8Array, options?: AbortOptions) => AsyncIterable +} diff --git a/packages/interface-peer-routing/tsconfig.json b/packages/interface-peer-routing/tsconfig.json new file mode 100644 index 0000000000..02d375dbd5 --- /dev/null +++ b/packages/interface-peer-routing/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-id" + }, + { + "path": "../interface-peer-info" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-peer-store/CHANGELOG.md b/packages/interface-peer-store/CHANGELOG.md new file mode 100644 index 0000000000..d9858e5e11 --- /dev/null +++ b/packages/interface-peer-store/CHANGELOG.md @@ -0,0 +1,136 @@ +## [@libp2p/interface-peer-store-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v2.0.3...@libp2p/interface-peer-store-v2.0.4) (2023-06-11) + + +### Bug Fixes + +* add peer store query interfaces ([#412](https://github.com/libp2p/js-libp2p-interfaces/issues/412)) ([0247215](https://github.com/libp2p/js-libp2p-interfaces/commit/0247215b8132096884af22499d8a6828281861d0)) + +## [@libp2p/interface-peer-store-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v2.0.2...@libp2p/interface-peer-store-v2.0.3) (2023-05-10) + + +### Bug Fixes + +* expose peerstore consume peer record method ([#398](https://github.com/libp2p/js-libp2p-interfaces/issues/398)) ([80222b8](https://github.com/libp2p/js-libp2p-interfaces/commit/80222b8474396aaa070fb44d859965ab14080f48)) + + +### Trivial Changes + +* correct the peerStore.save doc ([#397](https://github.com/libp2p/js-libp2p-interfaces/issues/397)) ([6998722](https://github.com/libp2p/js-libp2p-interfaces/commit/69987220a1038318d3798260af517873a30c838f)) + +## [@libp2p/interface-peer-store-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v2.0.1...@libp2p/interface-peer-store-v2.0.2) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-peer-store-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v2.0.0...@libp2p/interface-peer-store-v2.0.1) (2023-04-24) + + +### Bug Fixes + +* allow deleting tags/metadata with undefined fields ([#384](https://github.com/libp2p/js-libp2p-interfaces/issues/384)) ([64598ec](https://github.com/libp2p/js-libp2p-interfaces/commit/64598ec27495d4de5c05b573fd2f3f902166b596)) + +## [@libp2p/interface-peer-store-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.9...@libp2p/interface-peer-store-v2.0.0) (2023-04-21) + + +### ⚠ BREAKING CHANGES + +* make peer store methods atomic (#368) + +### Bug Fixes + +* make peer store methods atomic ([#368](https://github.com/libp2p/js-libp2p-interfaces/issues/368)) ([47c8b78](https://github.com/libp2p/js-libp2p-interfaces/commit/47c8b78e72fbbf9548d88a5fe0df965444254708)) + +## [@libp2p/interface-peer-store-v1.2.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.8...@libp2p/interface-peer-store-v1.2.9) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-peer-store-v1.2.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.7...@libp2p/interface-peer-store-v1.2.8) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-peer-store-v1.2.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.6...@libp2p/interface-peer-store-v1.2.7) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-peer-store-v1.2.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.5...@libp2p/interface-peer-store-v1.2.6) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-peer-store-v1.2.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.4...@libp2p/interface-peer-store-v1.2.5) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-peer-store-v1.2.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.3...@libp2p/interface-peer-store-v1.2.4) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-peer-store-v1.2.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.2...@libp2p/interface-peer-store-v1.2.3) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-peer-store-v1.2.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.1...@libp2p/interface-peer-store-v1.2.2) (2022-09-21) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#289](https://github.com/libp2p/js-libp2p-interfaces/issues/289)) ([81daf98](https://github.com/libp2p/js-libp2p-interfaces/commit/81daf9803a952cc8241c0956272b7f5625088636)) + +## [@libp2p/interface-peer-store-v1.2.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.2.0...@libp2p/interface-peer-store-v1.2.1) (2022-08-03) + + +### Bug Fixes + +* update peer store interface deps ([#277](https://github.com/libp2p/js-libp2p-interfaces/issues/277)) ([9945e16](https://github.com/libp2p/js-libp2p-interfaces/commit/9945e16f1653f22ad190be19fc6038378ae6d0d2)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) +* update sibling dependencies [skip ci] ([39eed35](https://github.com/libp2p/js-libp2p-interfaces/commit/39eed35c17920032ef821eede4d09fe14f8b30ab)) + +## [@libp2p/interface-peer-store-v1.2.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.1.0...@libp2p/interface-peer-store-v1.2.0) (2022-06-27) + + +### Features + +* export common tags ([#263](https://github.com/libp2p/js-libp2p-interfaces/issues/263)) ([8ca626e](https://github.com/libp2p/js-libp2p-interfaces/commit/8ca626e0b39f943244bb5ba005b84e2155d471fd)) + +## [@libp2p/interface-peer-store-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-peer-store-v1.0.0...@libp2p/interface-peer-store-v1.1.0) (2022-06-24) + + +### Features + +* add peer tagging ([#255](https://github.com/libp2p/js-libp2p-interfaces/issues/255)) ([80dadd9](https://github.com/libp2p/js-libp2p-interfaces/commit/80dadd99dc593ce43141a0072a4697339d01b222)) + + +### Trivial Changes + +* update aegir ([b0bcff9](https://github.com/libp2p/js-libp2p-interfaces/commit/b0bcff92f59aed4bb61dd4b67facc9a077de9ea6)) diff --git a/packages/interface-peer-store/LICENSE b/packages/interface-peer-store/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-peer-store/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-peer-store/LICENSE-APACHE b/packages/interface-peer-store/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-peer-store/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-peer-store/LICENSE-MIT b/packages/interface-peer-store/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-peer-store/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-peer-store/README.md b/packages/interface-peer-store/README.md new file mode 100644 index 0000000000..ac9d9b048e --- /dev/null +++ b/packages/interface-peer-store/README.md @@ -0,0 +1,50 @@ +# @libp2p/interface-peer-store + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Peer Store interface for libp2p + +## Table of contents + +- [Install](#install) +- [Usage](#usage) + - [Tags](#tags) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-peer-store +``` + +## Usage + +### Tags + +Common tags can be imported from the `@libp2p/interface-peer-store/tag` module: + +```js +import { KEEP_ALIVE } from '@libp2p/interface-peer-store/tags' + +await peerStore.tagPeer(peerId, KEEP_ALIVE) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-peer-store/package.json b/packages/interface-peer-store/package.json new file mode 100644 index 0000000000..fe9d8f1e64 --- /dev/null +++ b/packages/interface-peer-store/package.json @@ -0,0 +1,160 @@ +{ + "name": "@libp2p/interface-peer-store", + "version": "2.0.4", + "description": "Peer Store interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-peer-store#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ], + "src/*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ] + } + }, + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./tags": { + "types": "./dist/src/tags.d.ts", + "import": "./dist/src/tags.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-id": "^2.0.0", + "@multiformats/multiaddr": "^12.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-peer-store/src/index.ts b/packages/interface-peer-store/src/index.ts new file mode 100644 index 0000000000..7350ccc448 --- /dev/null +++ b/packages/interface-peer-store/src/index.ts @@ -0,0 +1,272 @@ +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Multiaddr } from '@multiformats/multiaddr' + +/** + * A multiaddr with an optional flag that indicates if its trustworthy + */ +export interface Address { + /** + * Peer multiaddr + */ + multiaddr: Multiaddr + + /** + * Obtained from a signed peer record + */ + isCertified: boolean +} + +/** + * Data stored in the peer store about peers + */ +export interface Peer { + /** + * Peer's peer-id instance + */ + id: PeerId + + /** + * Peer's addresses containing a list of multiaddrs and a isCertified field + * indicating if the address was loaded from a signed peer record or not + */ + addresses: Address[] + + /** + * Peer's supported protocols + */ + protocols: string[] + + /** + * Peer's metadata map + */ + metadata: Map + + /** + * Tags a peer has + */ + tags: Map + + /** + * The last peer record envelope received + */ + peerRecordEnvelope?: Uint8Array +} + +/** + * Peer data used to update the peer store + */ +export interface PeerData { + /** + * Peer's addresses containing its multiaddrs and metadata - multiaddrs + * passed here can be treated as certified if the `isCertifed` value is + * set to true. + * + * If both addresses and multiaddrs are specified they will be merged + * together with entries in addresses taking precedence. + */ + addresses?: Address[] + + /** + * Peer's multiaddrs - any multiaddrs passed here will be treated as + * uncertified. + * + * If both addresses and multiaddrs are specified they will be merged + * together with entries in addresses taking precedence. + */ + multiaddrs?: Multiaddr[] + + /** + * Peer's supported protocols + */ + protocols?: string[] + + /** + * Peer's metadata map. When merging pass undefined as values to remove metadata. + */ + metadata?: Map | Record + + /** + * Peer tags. When merging pass undefined as values to remove tags. + */ + tags?: Map | Record + + /** + * If this Peer has an RSA key, it's public key can be set with this property + */ + publicKey?: Uint8Array + + /** + * The last peer record envelope received + */ + peerRecordEnvelope?: Uint8Array +} + +export interface TagOptions { + /** + * An optional tag value (1-100) + */ + value?: number + + /** + * An optional duration in ms after which the tag will expire + */ + ttl?: number +} + +export interface Tag { + /** + * The tag value + */ + value: number +} + +/** + * A predicate by which to filter lists of peers + */ +export interface PeerQueryFilter { (peer: Peer): boolean } + +/** + * A predicate by which to sort lists of peers + */ +export interface PeerQueryOrder { (a: Peer, b: Peer): -1 | 0 | 1 } + +/** + * A query for getting lists of peers + */ +export interface PeerQuery { + filters?: PeerQueryFilter[] + orders?: PeerQueryOrder[] + limit?: number + offset?: number +} + +export interface PeerStore { + /** + * Loop over every peer - the looping is async because we read from a + * datastore but the peer operation is sync, this is to prevent + * long-lived peer operations causing deadlocks over the datastore + * which can happen if they try to access the peer store during the + * loop + * + * @example + * + * ```js + * await peerStore.forEach(peer => { + * // ... + * }) + * ``` + */ + forEach: (fn: (peer: Peer) => void, query?: PeerQuery) => Promise + + /** + * Returns all peers in the peer store. + * + * @example + * + * ```js + * for (const peer of await peerStore.all()) { + * // ... + * } + * ``` + */ + all: (query?: PeerQuery) => Promise + + /** + * Delete all data stored for the passed peer + * + * @example + * + * ```js + * await peerStore.addressBook.set(peerId, multiaddrs) + * await peerStore.addressBook.get(peerId) + * // multiaddrs[] + * + * await peerStore.delete(peerId) + * + * await peerStore.addressBook.get(peerId) + * // [] + * ``` + */ + delete: (peerId: PeerId) => Promise + + /** + * Returns true if the passed PeerId is in the peer store + * + * @example + * + * ```js + * await peerStore.has(peerId) + * // false + * await peerStore.addressBook.add(peerId, multiaddrs) + * await peerStore.has(peerId) + * // true + * ``` + */ + has: (peerId: PeerId) => Promise + + /** + * Returns all data stored for the passed PeerId + * + * @example + * + * ```js + * const peer = await peerStore.get(peerId) + * // { .. } + * ``` + */ + get: (peerId: PeerId) => Promise + + /** + * Adds a peer to the peer store, overwriting any existing data + * + * @example + * + * ```js + * await peerStore.save(peerId, { + * multiaddrs + * }) + * ``` + */ + save: (id: PeerId, data: PeerData) => Promise + + /** + * Adds a peer to the peer store, overwriting only the passed fields + * + * @example + * + * ```js + * await peerStore.patch(peerId, { + * multiaddrs + * }) + * ``` + */ + patch: (id: PeerId, data: PeerData) => Promise + + /** + * Adds a peer to the peer store, deeply merging any existing data. + * + * @example + * + * ```js + * await peerStore.merge(peerId, { + * multiaddrs + * }) + * ``` + */ + merge: (id: PeerId, data: PeerData) => Promise + + /** + * Unmarshal and verify a signed peer record, extract the multiaddrs and + * overwrite the stored addresses for the peer. + * + * Optionally pass an expected PeerId to verify that the peer record was + * signed by that peer. + * + * @example + * + * ```js + * await peerStore.consumePeerRecord(buf, expectedPeer) + * ``` + */ + consumePeerRecord: (buf: Uint8Array, expectedPeer?: PeerId) => Promise +} diff --git a/packages/interface-peer-store/src/tags.ts b/packages/interface-peer-store/src/tags.ts new file mode 100644 index 0000000000..121f6a0e96 --- /dev/null +++ b/packages/interface-peer-store/src/tags.ts @@ -0,0 +1,2 @@ + +export const KEEP_ALIVE = 'keep-alive' diff --git a/packages/interface-peer-store/tsconfig.json b/packages/interface-peer-store/tsconfig.json new file mode 100644 index 0000000000..d8db0b667f --- /dev/null +++ b/packages/interface-peer-store/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-pubsub-compliance-tests/CHANGELOG.md b/packages/interface-pubsub-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..3b82510891 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/CHANGELOG.md @@ -0,0 +1,225 @@ +## [@libp2p/interface-pubsub-compliance-tests-v5.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v5.0.6...@libp2p/interface-pubsub-compliance-tests-v5.0.7) (2023-05-04) + + +### Dependencies + +* update sibling dependencies ([eae5fe0](https://github.com/libp2p/js-libp2p-interfaces/commit/eae5fe02ea11c2930242a8d91ee4bc22f9bebc5c)) + +## [@libp2p/interface-pubsub-compliance-tests-v5.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v5.0.5...@libp2p/interface-pubsub-compliance-tests-v5.0.6) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-pubsub-compliance-tests-v5.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v5.0.4...@libp2p/interface-pubsub-compliance-tests-v5.0.5) (2023-04-21) + + +### Dependencies + +* update sibling dependencies ([74f82d5](https://github.com/libp2p/js-libp2p-interfaces/commit/74f82d53fc89740f4bafa22721a59ab70c3c92a8)) +* update sibling dependencies ([6c18790](https://github.com/libp2p/js-libp2p-interfaces/commit/6c18790f6178053c69a8cd6bd289fd749d4e9633)) + +## [@libp2p/interface-pubsub-compliance-tests-v5.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v5.0.3...@libp2p/interface-pubsub-compliance-tests-v5.0.4) (2023-04-18) + + +### Dependencies + +* update sibling dependencies ([294d970](https://github.com/libp2p/js-libp2p-interfaces/commit/294d970d6e4fbbf6a3f0944394c4c8dea06d1265)) +* update sibling dependencies ([3d23367](https://github.com/libp2p/js-libp2p-interfaces/commit/3d233676a17299bfa1b59d309543598176826523)) + +## [@libp2p/interface-pubsub-compliance-tests-v5.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v5.0.2...@libp2p/interface-pubsub-compliance-tests-v5.0.3) (2023-04-14) + + +### Dependencies + +* update sibling dependencies ([34b1627](https://github.com/libp2p/js-libp2p-interfaces/commit/34b1627458b2ada5e94e00cf4bcba41a77232090)) + +## [@libp2p/interface-pubsub-compliance-tests-v5.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v5.0.1...@libp2p/interface-pubsub-compliance-tests-v5.0.2) (2023-03-10) + + +### Bug Fixes + +* reject promise with error not string ([#350](https://github.com/libp2p/js-libp2p-interfaces/issues/350)) ([9435da9](https://github.com/libp2p/js-libp2p-interfaces/commit/9435da9a4015757b7945fdd55d142c4bd1950c59)) + +## [@libp2p/interface-pubsub-compliance-tests-v5.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v5.0.0...@libp2p/interface-pubsub-compliance-tests-v5.0.1) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-pubsub-compliance-tests-v5.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v4.0.4...@libp2p/interface-pubsub-compliance-tests-v5.0.0) (2023-01-06) + + +### ⚠ BREAKING CHANGES + +* update peer-id dep to pull in new multiformats (#331) + +### Bug Fixes + +* update peer-id dep to pull in new multiformats ([#331](https://github.com/libp2p/js-libp2p-interfaces/issues/331)) ([fb8b7ba](https://github.com/libp2p/js-libp2p-interfaces/commit/fb8b7ba654a30a08da0652e2833e36dd3bb85e90)) + + +### Dependencies + +* update sibling dependencies ([1442ad3](https://github.com/libp2p/js-libp2p-interfaces/commit/1442ad37e44f886a423e7a09e53e0b1796327fde)) + +## [@libp2p/interface-pubsub-compliance-tests-v4.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v4.0.3...@libp2p/interface-pubsub-compliance-tests-v4.0.4) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-pubsub-compliance-tests-v4.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v4.0.2...@libp2p/interface-pubsub-compliance-tests-v4.0.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-pubsub-compliance-tests-v4.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v4.0.1...@libp2p/interface-pubsub-compliance-tests-v4.0.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + + +### Dependencies + +* bump sinon from 14.0.2 to 15.0.0 ([#316](https://github.com/libp2p/js-libp2p-interfaces/issues/316)) ([d37721c](https://github.com/libp2p/js-libp2p-interfaces/commit/d37721c9143cd3eeafb5f8249b07d9f2fbce0f54)) + +## [@libp2p/interface-pubsub-compliance-tests-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v4.0.0...@libp2p/interface-pubsub-compliance-tests-v4.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Dependencies + +* update sibling dependencies ([45af2ca](https://github.com/libp2p/js-libp2p-interfaces/commit/45af2cadd55ad58d0c5ee2d11a0b8a39f6300454)) + +## [@libp2p/interface-pubsub-compliance-tests-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v3.0.0...@libp2p/interface-pubsub-compliance-tests-v4.0.0) (2022-10-12) + + +### ⚠ BREAKING CHANGES + +* modules no longer implement `Initializable` instead switching to constructor injection + +### Bug Fixes + +* export network components type ([79a5d8f](https://github.com/libp2p/js-libp2p-interfaces/commit/79a5d8fc57ae47274ff9ad9c3969c5898f07eb1d)) +* remove @libp2p/components ([#301](https://github.com/libp2p/js-libp2p-interfaces/issues/301)) ([1d37dc6](https://github.com/libp2p/js-libp2p-interfaces/commit/1d37dc6d3197838a71895d5769ad8bba6eb38fd3)) +* update mock network components use ([c760e95](https://github.com/libp2p/js-libp2p-interfaces/commit/c760e95f07b6199f08adb20c1e3a4265649fdda0)) + + +### Dependencies + +* update sibling dependencies ([d3226f7](https://github.com/libp2p/js-libp2p-interfaces/commit/d3226f7383de85cae2b4771c22eea22c4bb5bbeb)) + +## [@libp2p/interface-pubsub-compliance-tests-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v2.0.5...@libp2p/interface-pubsub-compliance-tests-v3.0.0) (2022-10-11) + + +### ⚠ BREAKING CHANGES + +* add topicValidators to pubsub interface (#298) + +### Bug Fixes + +* add topicValidators to pubsub interface ([#298](https://github.com/libp2p/js-libp2p-interfaces/issues/298)) ([e5ff819](https://github.com/libp2p/js-libp2p-interfaces/commit/e5ff819c6dd235b2ea9ea5133457b384c4411cf3)) + + +### Dependencies + +* update sibling dependencies ([8f3680e](https://github.com/libp2p/js-libp2p-interfaces/commit/8f3680e2d87e424936dfe7128b859795f0327d9a)) + +## [@libp2p/interface-pubsub-compliance-tests-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v2.0.4...@libp2p/interface-pubsub-compliance-tests-v2.0.5) (2022-10-07) + + +### Dependencies + +* bump @libp2p/components from 2.1.1 to 3.0.0 ([#299](https://github.com/libp2p/js-libp2p-interfaces/issues/299)) ([b3f493c](https://github.com/libp2p/js-libp2p-interfaces/commit/b3f493c5e260f697f66de54b56379d036ca3db59)) + +## [@libp2p/interface-pubsub-compliance-tests-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v2.0.3...@libp2p/interface-pubsub-compliance-tests-v2.0.4) (2022-10-06) + + +### Dependencies + +* update sibling dependencies ([2f46d7f](https://github.com/libp2p/js-libp2p-interfaces/commit/2f46d7ff4189c29a63bac93b0b5b73de0a75922f)) + +## [@libp2p/interface-pubsub-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v2.0.2...@libp2p/interface-pubsub-compliance-tests-v2.0.3) (2022-10-04) + + +### Dependencies + +* update sibling dependencies ([1b11e8e](https://github.com/libp2p/js-libp2p-interfaces/commit/1b11e8e9cc2ea1d4d26233f9c11a57e185ea23ed)) + +## [@libp2p/interface-pubsub-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v2.0.1...@libp2p/interface-pubsub-compliance-tests-v2.0.2) (2022-08-10) + + +### Dependencies + +* update sibling dependencies ([fc4c49c](https://github.com/libp2p/js-libp2p-interfaces/commit/fc4c49c22334b9f2059b08e13ba94f3e8938482e)) + +## [@libp2p/interface-pubsub-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v2.0.0...@libp2p/interface-pubsub-compliance-tests-v2.0.1) (2022-07-31) + + +### Dependencies + +* update uint8arraylist and p-wait-for deps ([#274](https://github.com/libp2p/js-libp2p-interfaces/issues/274)) ([c55f12e](https://github.com/libp2p/js-libp2p-interfaces/commit/c55f12e47be0a10e41709b0d6a60dd8bc1209ee5)) + +## [@libp2p/interface-pubsub-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v1.0.4...@libp2p/interface-pubsub-compliance-tests-v2.0.0) (2022-07-31) + + +### ⚠ BREAKING CHANGES + +* The `Message` type is now either a `SignedMessage` +or a `UnsignedMessage` + +### Features + +* pubsub Message types for signature policies ([#266](https://github.com/libp2p/js-libp2p-interfaces/issues/266)) ([9eb710b](https://github.com/libp2p/js-libp2p-interfaces/commit/9eb710bcbdb0aef95c7a8613e00065a3b7c7f887)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) +* update sibling dependencies [skip ci] ([fbd5281](https://github.com/libp2p/js-libp2p-interfaces/commit/fbd52811b1d074df0755a3ee10c33a99ccc86842)) + +## [@libp2p/interface-pubsub-compliance-tests-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v1.0.3...@libp2p/interface-pubsub-compliance-tests-v1.0.4) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-pubsub-compliance-tests-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v1.0.2...@libp2p/interface-pubsub-compliance-tests-v1.0.3) (2022-06-24) + + +### Trivial Changes + +* update sibling dependencies [skip ci] ([c5c41c5](https://github.com/libp2p/js-libp2p-interfaces/commit/c5c41c521cf970addc1840d8519cdaa542a0db16)) + +## [@libp2p/interface-pubsub-compliance-tests-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v1.0.1...@libp2p/interface-pubsub-compliance-tests-v1.0.2) (2022-06-16) + + +### Trivial Changes + +* update deps ([54fbb37](https://github.com/libp2p/js-libp2p-interfaces/commit/54fbb37c8644a3fd6833c12550a57bf1a9292902)) +* update deps ([970a940](https://github.com/libp2p/js-libp2p-interfaces/commit/970a940a2f65b946936a53febdc52527baefbd34)) + +## [@libp2p/interface-pubsub-compliance-tests-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-compliance-tests-v1.0.0...@libp2p/interface-pubsub-compliance-tests-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update components module ([#235](https://github.com/libp2p/js-libp2p-interfaces/issues/235)) ([5844207](https://github.com/libp2p/js-libp2p-interfaces/commit/58442070af59aa852c83ec3aecdbd1d2c646b018)) diff --git a/packages/interface-pubsub-compliance-tests/LICENSE b/packages/interface-pubsub-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-pubsub-compliance-tests/LICENSE-APACHE b/packages/interface-pubsub-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-pubsub-compliance-tests/LICENSE-MIT b/packages/interface-pubsub-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-pubsub-compliance-tests/README.md b/packages/interface-pubsub-compliance-tests/README.md new file mode 100644 index 0000000000..8c6a5c6164 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/README.md @@ -0,0 +1,55 @@ +# @libp2p/interface-pubsub-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for implementations of the libp2p PubSub interface + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-pubsub-compliance-tests +``` + +## Usage + +```js +import tests from '@libp2p/interface-pubsub-compliance-tests' + +describe('your pubsub implementation', () => { + tests({ + // Options should be passed to your implementation + async setup (options) { + return new YourImplementation() + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-pubsub-compliance-tests/package.json b/packages/interface-pubsub-compliance-tests/package.json new file mode 100644 index 0000000000..e53a1add68 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/package.json @@ -0,0 +1,150 @@ +{ + "name": "@libp2p/interface-pubsub-compliance-tests", + "version": "5.0.7", + "description": "Compliance tests for implementations of the libp2p PubSub interface", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-pubsub-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-connection-manager": "^3.0.0", + "@libp2p/interface-mocks": "^12.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interface-pubsub": "^4.0.0", + "@libp2p/interface-registrar": "^2.0.0", + "@libp2p/interfaces": "^3.0.0", + "@libp2p/peer-id-factory": "^2.0.0", + "aegir": "^39.0.5", + "delay": "^6.0.0", + "p-defer": "^4.0.0", + "p-event": "^5.0.1", + "p-wait-for": "^5.0.0", + "sinon": "^15.0.0", + "uint8arrays": "^4.0.2" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-pubsub-compliance-tests/src/api.ts b/packages/interface-pubsub-compliance-tests/src/api.ts new file mode 100644 index 0000000000..00b180f1c0 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/api.ts @@ -0,0 +1,114 @@ +import { mockNetwork } from '@libp2p/interface-mocks' +import { isStartable, start, stop } from '@libp2p/interfaces/startable' +import { expect } from 'aegir/chai' +import delay from 'delay' +import pDefer from 'p-defer' +import pWaitFor from 'p-wait-for' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { createComponents } from './utils.js' +import type { PubSubArgs, PubSubComponents } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { PubSub } from '@libp2p/interface-pubsub' + +const topic = 'foo' +const data = uint8ArrayFromString('bar') + +export default (common: TestSetup): void => { + describe('pubsub api', () => { + let pubsub: PubSub + let components: PubSubComponents + + // Create pubsub router + beforeEach(async () => { + mockNetwork.reset() + components = await createComponents() + + pubsub = components.pubsub = await common.setup({ + components, + init: { + emitSelf: true + } + }) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(components)) + await common.teardown() + mockNetwork.reset() + }) + + it('can start correctly', async () => { + if (!isStartable(pubsub)) { + return + } + + sinon.spy(components.registrar, 'register') + + await start(...Object.values(components)) + + expect(pubsub.isStarted()).to.equal(true) + expect(components.registrar.register).to.have.property('callCount', 1) + }) + + it('can stop correctly', async () => { + if (!isStartable(pubsub)) { + return + } + + sinon.spy(components.registrar, 'unregister') + + await start(...Object.values(components)) + await stop(...Object.values(components)) + + expect(pubsub.isStarted()).to.equal(false) + expect(components.registrar.unregister).to.have.property('callCount', 1) + }) + + it('can subscribe and unsubscribe correctly', async () => { + const handler = (): void => { + throw new Error('a message should not be received') + } + + await start(...Object.values(components)) + pubsub.subscribe(topic) + pubsub.addEventListener('message', handler) + + await pWaitFor(() => { + const topics = pubsub.getTopics() + return topics.length === 1 && topics[0] === topic + }) + + pubsub.removeEventListener('message', handler) + pubsub.unsubscribe(topic) + + await pWaitFor(() => pubsub.getTopics().length === 0) + + // Publish to guarantee the handler is not called + await pubsub.publish(topic, data) + + // handlers are called async + await delay(100) + + await stop(...Object.values(components)) + }) + + it('can subscribe and publish correctly', async () => { + const defer = pDefer() + + await start(...Object.values(components)) + + pubsub.subscribe(topic) + pubsub.addEventListener('message', (evt) => { + expect(evt).to.have.nested.property('detail.topic', topic) + expect(evt).to.have.deep.nested.property('detail.data', data) + defer.resolve() + }) + await pubsub.publish(topic, data) + await defer.promise + + await stop(...Object.values(components)) + }) + }) +} diff --git a/packages/interface-pubsub-compliance-tests/src/connection-handlers.ts b/packages/interface-pubsub-compliance-tests/src/connection-handlers.ts new file mode 100644 index 0000000000..24656a0c7f --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/connection-handlers.ts @@ -0,0 +1,413 @@ +import { mockNetwork } from '@libp2p/interface-mocks' +import { start, stop } from '@libp2p/interfaces/startable' +import { expect } from 'aegir/chai' +import pDefer from 'p-defer' +import { pEvent } from 'p-event' +import pWaitFor from 'p-wait-for' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { toString as uint8ArrayToString } from 'uint8arrays/to-string' +import { createComponents } from './utils.js' +import type { PubSubArgs } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { MockNetworkComponents } from '@libp2p/interface-mocks' +import type { Message, PubSub } from '@libp2p/interface-pubsub' + +export default (common: TestSetup): void => { + describe('pubsub connection handlers', () => { + let psA: PubSub + let psB: PubSub + let componentsA: MockNetworkComponents + let componentsB: MockNetworkComponents + + describe('nodes send state on connection', () => { + // Create pubsub nodes and connect them + beforeEach(async () => { + mockNetwork.reset() + + componentsA = await createComponents() + componentsB = await createComponents() + + psA = componentsA.pubsub = await common.setup({ + components: componentsA, + init: {} + }) + + psB = componentsB.pubsub = await common.setup({ + components: componentsB, + init: {} + }) + + // Start pubsub + await start(...Object.values(componentsA), ...Object.values(componentsB)) + + expect(psA.getPeers()).to.be.empty() + expect(psB.getPeers()).to.be.empty() + + // Make subscriptions prior to nodes connected + psA.subscribe('Za') + psB.subscribe('Zb') + + expect(psA.getPeers()).to.be.empty() + expect(psA.getTopics()).to.deep.equal(['Za']) + expect(psB.getPeers()).to.be.empty() + expect(psB.getTopics()).to.deep.equal(['Zb']) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(componentsA), ...Object.values(componentsB)) + await common.teardown() + mockNetwork.reset() + }) + + it('existing subscriptions are sent upon peer connection', async function () { + const subscriptionsChanged = Promise.all([ + pEvent(psA, 'subscription-change'), + pEvent(psB, 'subscription-change') + ]) + + await componentsA.connectionManager.openConnection(componentsB.peerId) + + await subscriptionsChanged + + expect(psA.getPeers()).to.have.lengthOf(1) + expect(psB.getPeers()).to.have.lengthOf(1) + + expect(psA.getTopics()).to.deep.equal(['Za']) + expect(psB.getTopics()).to.deep.equal(['Zb']) + + expect(psA.getSubscribers('Zb').map(p => p.toString())).to.deep.equal([componentsB.peerId.toString()]) + expect(psB.getSubscribers('Za').map(p => p.toString())).to.deep.equal([componentsA.peerId.toString()]) + }) + }) + + describe('pubsub started before connect', () => { + let psA: PubSub + let psB: PubSub + let componentsA: MockNetworkComponents + let componentsB: MockNetworkComponents + + // Create pubsub nodes and start them + beforeEach(async () => { + mockNetwork.reset() + componentsA = await createComponents() + componentsB = await createComponents() + + psA = componentsA.pubsub = await common.setup({ + components: componentsA, + init: {} + }) + psB = componentsB.pubsub = await common.setup({ + components: componentsB, + init: {} + }) + + await start(...Object.values(componentsA), ...Object.values(componentsB)) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(componentsA), ...Object.values(componentsB)) + await common.teardown() + mockNetwork.reset() + }) + + it('should get notified of connected peers on dial', async () => { + await componentsA.connectionManager.openConnection(componentsB.peerId) + + return Promise.all([ + pWaitFor(() => psA.getPeers().length === 1), + pWaitFor(() => psB.getPeers().length === 1) + ]) + }) + + it('should receive pubsub messages', async () => { + const defer = pDefer() + const topic = 'test-topic' + const data = uint8ArrayFromString('hey!') + + await componentsA.connectionManager.openConnection(componentsB.peerId) + + let subscribedTopics = psA.getTopics() + expect(subscribedTopics).to.not.include(topic) + + psA.subscribe(topic) + psA.addEventListener('message', (evt) => { + if (evt.detail.topic === topic) { + const msg = evt.detail + expect(msg.data).to.equalBytes(data) + defer.resolve() + } + }) + psA.subscribe(topic) + + subscribedTopics = psA.getTopics() + expect(subscribedTopics).to.include(topic) + + // wait for psB to know about psA subscription + await pWaitFor(() => { + const subscribedPeers = psB.getSubscribers(topic) + return subscribedPeers.map(p => p.toString()).includes(componentsA.peerId.toString()) // eslint-disable-line max-nested-callbacks + }) + await psB.publish(topic, data) + + await defer.promise + }) + }) + + describe('pubsub started after connect', () => { + let psA: PubSub + let psB: PubSub + let componentsA: MockNetworkComponents + let componentsB: MockNetworkComponents + + // Create pubsub nodes + beforeEach(async () => { + mockNetwork.reset() + componentsA = await createComponents() + componentsB = await createComponents() + + psA = componentsA.pubsub = await common.setup({ + components: componentsA, + init: {} + }) + psB = componentsB.pubsub = await common.setup({ + components: componentsB, + init: {} + }) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(componentsA), ...Object.values(componentsB)) + await common.teardown() + mockNetwork.reset() + }) + + it('should get notified of connected peers after starting', async () => { + await start(...Object.values(componentsA), ...Object.values(componentsB)) + + await componentsA.connectionManager.openConnection(componentsB.peerId) + + return Promise.all([ + pWaitFor(() => psA.getPeers().length === 1), + pWaitFor(() => psB.getPeers().length === 1) + ]) + }) + + it('should receive pubsub messages', async () => { + const defer = pDefer() + const topic = 'test-topic' + const data = uint8ArrayFromString('hey!') + + await start(...Object.values(componentsA), ...Object.values(componentsB)) + + await componentsA.connectionManager.openConnection(componentsB.peerId) + + await Promise.all([ + pWaitFor(() => psA.getPeers().length === 1), + pWaitFor(() => psB.getPeers().length === 1) + ]) + + let subscribedTopics = psA.getTopics() + expect(subscribedTopics).to.not.include(topic) + + psA.subscribe(topic) + psA.addEventListener('message', (evt) => { + if (evt.detail.topic === topic) { + const msg = evt.detail + expect(msg.data).to.equalBytes(data) + defer.resolve() + } + }) + psA.subscribe(topic) + + subscribedTopics = psA.getTopics() + expect(subscribedTopics).to.include(topic) + + // wait for psB to know about psA subscription + await pWaitFor(() => { + const subscribedPeers = psB.getSubscribers(topic) + return subscribedPeers.map(p => p.toString()).includes(componentsA.peerId.toString()) // eslint-disable-line max-nested-callbacks + }) + await psB.publish(topic, data) + + await defer.promise + }) + }) + + describe('pubsub with intermittent connections', () => { + let psA: PubSub + let psB: PubSub + let componentsA: MockNetworkComponents + let componentsB: MockNetworkComponents + + // Create pubsub nodes and start them + beforeEach(async () => { + mockNetwork.reset() + componentsA = await createComponents() + componentsB = await createComponents() + + psA = componentsA.pubsub = await common.setup({ + components: componentsA, + init: {} + }) + psB = componentsB.pubsub = await common.setup({ + components: componentsB, + init: {} + }) + + await start(...Object.values(componentsA), ...Object.values(componentsB)) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(componentsA), ...Object.values(componentsB)) + await common.teardown() + mockNetwork.reset() + }) + + it.skip('should receive pubsub messages after a node restart', async function () { + const topic = 'test-topic' + const data = uint8ArrayFromString('hey!') + + let counter = 0 + const defer1 = pDefer() + const defer2 = pDefer() + + await componentsA.connectionManager.openConnection(componentsB.peerId) + + let subscribedTopics = psA.getTopics() + expect(subscribedTopics).to.not.include(topic) + + psA.subscribe(topic) + psA.addEventListener('message', (evt) => { + if (evt.detail.topic === topic) { + const msg = evt.detail + expect(msg.data).to.equalBytes(data) + counter++ + counter === 1 ? defer1.resolve() : defer2.resolve() + } + }) + psA.subscribe(topic) + + subscribedTopics = psA.getTopics() + expect(subscribedTopics).to.include(topic) + + // wait for psB to know about psA subscription + await pWaitFor(() => { + const subscribedPeers = psB.getSubscribers(topic) + return subscribedPeers.map(p => p.toString()).includes(componentsA.peerId.toString()) // eslint-disable-line max-nested-callbacks + }) + await psB.publish(topic, data) + + await defer1.promise + + await stop(psB) + await pWaitFor(() => { + // @ts-expect-error protected fields + const aHasConnectionToB = psA._libp2p.connectionManager.get(psB.peerId) + // @ts-expect-error protected fields + const bHasConnectionToA = psB._libp2p.connectionManager.get(psA.peerId) + + return aHasConnectionToB != null && bHasConnectionToA != null + }) + await start(psB) + + await componentsA.connectionManager.openConnection(componentsB.peerId) + + // wait for remoteLibp2p to know about libp2p subscription + await pWaitFor(() => { + const subscribedPeers = psB.getSubscribers(topic) + return subscribedPeers.toString().includes(componentsA.peerId.toString()) + }) + + await psB.publish(topic, data) + + await defer2.promise + }) + + it.skip('should handle quick reconnects with a delayed disconnect', async () => { + // Subscribe on both + let aReceivedFirstMessageFromB = false + let aReceivedSecondMessageFromB = false + let bReceivedFirstMessageFromA = false + let bReceivedSecondMessageFromA = false + const topic = 'reconnect-channel' + + const handlerSpyA = (evt: CustomEvent): void => { + if (evt.detail.topic !== topic) { + return + } + + const message = evt.detail + const data = uint8ArrayToString(message.data) + + if (data === 'message-from-b-1') { + aReceivedFirstMessageFromB = true + } + + if (data === 'message-from-b-2') { + aReceivedSecondMessageFromB = true + } + } + const handlerSpyB = (evt: CustomEvent): void => { + if (evt.detail.topic !== topic) { + return + } + + const message = evt.detail + const data = uint8ArrayToString(message.data) + + if (data === 'message-from-a-1') { + bReceivedFirstMessageFromA = true + } + + if (data === 'message-from-a-2') { + bReceivedSecondMessageFromA = true + } + } + + psA.addEventListener('message', handlerSpyA) + psB.addEventListener('message', handlerSpyB) + psA.subscribe(topic) + psB.subscribe(topic) + + // Create two connections to the remote peer + // @ts-expect-error protected fields + const originalConnection = await psA._libp2p.dialer.connectToPeer(psB.peerId) + + // second connection + await componentsA.connectionManager.openConnection(componentsB.peerId) + + // Wait for subscriptions to occur + await pWaitFor(() => { + return psA.getSubscribers(topic).map(p => p.toString()).includes(componentsB.peerId.toString()) && + psB.getSubscribers(topic).map(p => p.toString()).includes(componentsA.peerId.toString()) + }) + + // Verify messages go both ways + await psA.publish(topic, uint8ArrayFromString('message-from-a-1')) + await psB.publish(topic, uint8ArrayFromString('message-from-b-1')) + await pWaitFor(() => { + return aReceivedFirstMessageFromB && bReceivedFirstMessageFromA + }) + + // Disconnect the first connection (this acts as a delayed reconnect) + // @ts-expect-error protected fields + const psAConnUpdateSpy = sinon.spy(psA._libp2p.connectionManager.connections, 'set') + + await originalConnection.close() + await pWaitFor(() => psAConnUpdateSpy.callCount === 1) + + // Verify messages go both ways after the disconnect + await psA.publish(topic, uint8ArrayFromString('message-from-a-2')) + await psB.publish(topic, uint8ArrayFromString('message-from-b-2')) + await pWaitFor(() => { + return aReceivedSecondMessageFromB && bReceivedSecondMessageFromA + }) + }) + }) + }) +} diff --git a/packages/interface-pubsub-compliance-tests/src/emit-self.ts b/packages/interface-pubsub-compliance-tests/src/emit-self.ts new file mode 100644 index 0000000000..956a1f2143 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/emit-self.ts @@ -0,0 +1,99 @@ +import { mockNetwork } from '@libp2p/interface-mocks' +import { start, stop } from '@libp2p/interfaces/startable' +import { expect } from 'aegir/chai' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { createComponents } from './utils.js' +import type { PubSubArgs, PubSubComponents } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { PubSub } from '@libp2p/interface-pubsub' + +const topic = 'foo' +const data = uint8ArrayFromString('bar') +const shouldNotHappen = (): void => expect.fail() + +export default (common: TestSetup): void => { + describe('emit self', () => { + describe('enabled', () => { + let pubsub: PubSub + let components: PubSubComponents + + before(async () => { + mockNetwork.reset() + components = await createComponents() + + pubsub = components.pubsub = await common.setup({ + components, + init: { + emitSelf: true + } + }) + + await start(...Object.values(components)) + pubsub.subscribe(topic) + }) + + after(async () => { + sinon.restore() + await stop(...Object.values(components)) + await common.teardown() + mockNetwork.reset() + }) + + it('should emit to self on publish', async () => { + const promise = new Promise((resolve) => { + pubsub.addEventListener('message', (evt) => { + if (evt.detail.topic === topic) { + resolve() + } + }, { + once: true + }) + }) + + const result = await pubsub.publish(topic, data) + + await promise + + expect(result).to.have.property('recipients').with.lengthOf(1) + }) + }) + + describe('disabled', () => { + let pubsub: PubSub + let components: PubSubComponents + + before(async () => { + mockNetwork.reset() + components = await createComponents() + pubsub = components.pubsub = await common.setup({ + components, + init: { + emitSelf: false + } + }) + + await start(...Object.values(components)) + pubsub.subscribe(topic) + }) + + after(async () => { + sinon.restore() + await stop(...Object.values(components)) + await common.teardown() + mockNetwork.reset() + }) + + it('should not emit to self on publish', async () => { + pubsub.addEventListener('message', shouldNotHappen, { + once: true + }) + + await pubsub.publish(topic, data) + + // Wait 1 second to guarantee that self is not noticed + await new Promise((resolve) => setTimeout(resolve, 1000)) + }) + }) + }) +} diff --git a/packages/interface-pubsub-compliance-tests/src/index.ts b/packages/interface-pubsub-compliance-tests/src/index.ts new file mode 100644 index 0000000000..7cf2d45fc5 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/index.ts @@ -0,0 +1,34 @@ +import apiTest from './api.js' +import connectionHandlersTest from './connection-handlers.js' +import emitSelfTest from './emit-self.js' +import messagesTest from './messages.js' +import multipleNodesTest from './multiple-nodes.js' +import twoNodesTest from './two-nodes.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { ConnectionManager } from '@libp2p/interface-connection-manager' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { PubSub, PubSubInit } from '@libp2p/interface-pubsub' +import type { Registrar } from '@libp2p/interface-registrar' + +export interface PubSubComponents { + peerId: PeerId + registrar: Registrar + connectionManager: ConnectionManager + pubsub?: PubSub +} + +export interface PubSubArgs { + components: PubSubComponents + init: PubSubInit +} + +export default (common: TestSetup): void => { + describe('interface-pubsub compliance tests', () => { + apiTest(common) + emitSelfTest(common) + messagesTest(common) + connectionHandlersTest(common) + twoNodesTest(common) + multipleNodesTest(common) + }) +} diff --git a/packages/interface-pubsub-compliance-tests/src/messages.ts b/packages/interface-pubsub-compliance-tests/src/messages.ts new file mode 100644 index 0000000000..ddbd9d59c6 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/messages.ts @@ -0,0 +1,59 @@ +import { mockNetwork } from '@libp2p/interface-mocks' +import { start, stop } from '@libp2p/interfaces/startable' +import { expect } from 'aegir/chai' +import { pEvent } from 'p-event' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { createComponents } from './utils.js' +import type { PubSubArgs, PubSubComponents } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Message, PubSub } from '@libp2p/interface-pubsub' + +const topic = 'foo' +const data = uint8ArrayFromString('bar') + +export default (common: TestSetup): void => { + describe('messages', () => { + let pubsub: PubSub + let components: PubSubComponents + + // Create pubsub router + beforeEach(async () => { + mockNetwork.reset() + components = await createComponents() + + pubsub = components.pubsub = await common.setup({ + components, + init: { + emitSelf: true + } + }) + await start(...Object.values(components)) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(components)) + await common.teardown() + mockNetwork.reset() + }) + + it('should emit normalized signed messages on publish', async () => { + const eventPromise = pEvent<'message', CustomEvent>(pubsub, 'message') + + pubsub.globalSignaturePolicy = 'StrictSign' + pubsub.subscribe(topic) + await pubsub.publish(topic, data) + + const event = await eventPromise + const message = event.detail + + if (message.type === 'signed') { + expect(message.from.toString()).to.equal(components.peerId.toString()) + expect(message.sequenceNumber).to.not.eql(undefined) + expect(message.key).to.not.eql(undefined) + expect(message.signature).to.not.eql(undefined) + } + }) + }) +} diff --git a/packages/interface-pubsub-compliance-tests/src/multiple-nodes.ts b/packages/interface-pubsub-compliance-tests/src/multiple-nodes.ts new file mode 100644 index 0000000000..d5c4c58545 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/multiple-nodes.ts @@ -0,0 +1,440 @@ +/* eslint max-nested-callbacks: ["error", 6] */ +import { mockNetwork } from '@libp2p/interface-mocks' +import { start, stop } from '@libp2p/interfaces/startable' +import { expect } from 'aegir/chai' +import delay from 'delay' +import pDefer from 'p-defer' +import pWaitFor from 'p-wait-for' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { toString as uint8ArrayToString } from 'uint8arrays/to-string' +import { createComponents, waitForSubscriptionUpdate } from './utils.js' +import type { PubSubArgs, PubSubComponents } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Message, PubSub } from '@libp2p/interface-pubsub' + +export default (common: TestSetup): void => { + describe('pubsub with multiple nodes', function () { + describe('every peer subscribes to the topic', () => { + describe('line', () => { + // line + // ◉────◉────◉ + // a b c + let psA: PubSub + let psB: PubSub + let psC: PubSub + let componentsA: PubSubComponents + let componentsB: PubSubComponents + let componentsC: PubSubComponents + + // Create and start pubsub nodes + beforeEach(async () => { + mockNetwork.reset() + + componentsA = await createComponents() + componentsB = await createComponents() + componentsC = await createComponents() + + psA = componentsA.pubsub = await common.setup({ + components: componentsA, + init: { + emitSelf: true + } + }) + psB = componentsB.pubsub = await common.setup({ + components: componentsB, + init: { + emitSelf: true + } + }) + psC = componentsC.pubsub = await common.setup({ + components: componentsC, + init: { + emitSelf: true + } + }) + + // Start pubsub modes + await start(...Object.values(componentsA), ...Object.values(componentsB), ...Object.values(componentsC)) + + // Connect nodes + await componentsA.connectionManager.openConnection(componentsB.peerId) + await componentsB.connectionManager.openConnection(componentsC.peerId) + + // Wait for peers to be ready in pubsub + await pWaitFor(() => + psA.getPeers().length === 1 && + psC.getPeers().length === 1 && + psA.getPeers().length === 1 + ) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(componentsA), ...Object.values(componentsB), ...Object.values(componentsC)) + await common.teardown() + mockNetwork.reset() + }) + + it('subscribe to the topic on node a', async () => { + const topic = 'Z' + + psA.subscribe(topic) + expect(psA.getTopics()).to.deep.equal([topic]) + + await waitForSubscriptionUpdate(psB, componentsA.peerId) + + expect(psB.getPeers().length).to.equal(2) + expect(psB.getSubscribers(topic).map(p => p.toString())).to.deep.equal([componentsA.peerId.toString()]) + + expect(psC.getPeers().length).to.equal(1) + expect(psC.getSubscribers(topic)).to.be.empty() + }) + + it('subscribe to the topic on node b', async () => { + const topic = 'Z' + psB.subscribe(topic) + expect(psB.getTopics()).to.deep.equal([topic]) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psC, componentsB.peerId) + ]) + + expect(psA.getPeers().length).to.equal(1) + expect(psA.getSubscribers(topic).map(p => p.toString())).to.deep.equal([componentsB.peerId.toString()]) + + expect(psC.getPeers().length).to.equal(1) + expect(psC.getSubscribers(topic).map(p => p.toString())).to.deep.equal([componentsB.peerId.toString()]) + }) + + it('subscribe to the topic on node c', async () => { + const topic = 'Z' + const defer = pDefer() + + psC.subscribe(topic) + expect(psC.getTopics()).to.deep.equal([topic]) + + psB.addEventListener('subscription-change', () => { + expect(psA.getPeers().length).to.equal(1) + expect(psB.getPeers().length).to.equal(2) + expect(psB.getSubscribers(topic).map(p => p.toString())).to.deep.equal([componentsC.peerId.toString()]) + + defer.resolve() + }, { + once: true + }) + + return defer.promise + }) + + it('publish on node a', async () => { + const topic = 'Z' + const defer = pDefer() + + psA.subscribe(topic) + psB.subscribe(topic) + psC.subscribe(topic) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psB, componentsA.peerId), + waitForSubscriptionUpdate(psC, componentsB.peerId) + ]) + + // GossipSub needs time to build the mesh overlay + await delay(1000) + + let counter = 0 + + psA.addEventListener('message', incMsg) + psB.addEventListener('message', incMsg) + psC.addEventListener('message', incMsg) + + const result = await psA.publish(topic, uint8ArrayFromString('hey')) + + expect(result).to.have.property('recipients').with.property('length').greaterThanOrEqual(1) + + function incMsg (evt: CustomEvent): void { + const msg = evt.detail + + if (msg.topic !== topic) { + return + } + + expect(uint8ArrayToString(msg.data)).to.equal('hey') + check() + } + + function check (): void { + if (++counter === 3) { + psA.removeEventListener('message', incMsg) + psB.removeEventListener('message', incMsg) + psC.removeEventListener('message', incMsg) + defer.resolve() + } + } + + return defer.promise + }) + + // since the topology is the same, just the publish + // gets sent by other peer, we reused the same peers + describe('1 level tree', () => { + // 1 level tree + // ┌◉┐ + // │b│ + // ◉─┘ └─◉ + // a c + + it('publish on node b', async () => { + const topic = 'Z' + const defer = pDefer() + let counter = 0 + + psA.subscribe(topic) + psB.subscribe(topic) + psC.subscribe(topic) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psB, componentsA.peerId), + waitForSubscriptionUpdate(psC, componentsB.peerId) + ]) + + // GossipSub needs time to build the mesh overlay + await delay(1000) + + psA.addEventListener('message', incMsg) + psB.addEventListener('message', incMsg) + psC.addEventListener('message', incMsg) + + await psB.publish(topic, uint8ArrayFromString('hey')) + + function incMsg (evt: CustomEvent): void { + const msg = evt.detail + + if (msg.topic !== topic) { + return + } + + expect(uint8ArrayToString(msg.data)).to.equal('hey') + check() + } + + function check (): void { + if (++counter === 3) { + psA.removeEventListener('message', incMsg) + psB.removeEventListener('message', incMsg) + psC.removeEventListener('message', incMsg) + defer.resolve() + } + } + + return defer.promise + }) + }) + }) + + describe('2 level tree', () => { + // 2 levels tree + // ┌◉┐ + // │c│ + // ┌◉─┘ └─◉┐ + // │b d│ + // ◉─┘ └─◉ + // a + let psA: PubSub + let psB: PubSub + let psC: PubSub + let psD: PubSub + let psE: PubSub + let componentsA: PubSubComponents + let componentsB: PubSubComponents + let componentsC: PubSubComponents + let componentsD: PubSubComponents + let componentsE: PubSubComponents + + // Create and start pubsub nodes + beforeEach(async () => { + mockNetwork.reset() + + componentsA = await createComponents() + componentsB = await createComponents() + componentsC = await createComponents() + componentsD = await createComponents() + componentsE = await createComponents() + + psA = componentsA.pubsub = await common.setup({ + components: componentsA, + init: { + emitSelf: true + } + }) + psB = componentsB.pubsub = await common.setup({ + components: componentsB, + init: { + emitSelf: true + } + }) + psC = componentsC.pubsub = await common.setup({ + components: componentsC, + init: { + emitSelf: true + } + }) + psD = componentsD.pubsub = await common.setup({ + components: componentsD, + init: { + emitSelf: true + } + }) + psE = componentsE.pubsub = await common.setup({ + components: componentsE, + init: { + emitSelf: true + } + }) + + // Start pubsub nodes + await start( + ...Object.values(componentsA), + ...Object.values(componentsB), + ...Object.values(componentsC), + ...Object.values(componentsD), + ...Object.values(componentsE) + ) + + // connect nodes + await componentsA.connectionManager.openConnection(componentsB.peerId) + await componentsB.connectionManager.openConnection(componentsC.peerId) + await componentsC.connectionManager.openConnection(componentsD.peerId) + await componentsD.connectionManager.openConnection(componentsE.peerId) + + // Wait for peers to be ready in pubsub + await pWaitFor(() => + psA.getPeers().length === 1 && + psB.getPeers().length === 2 && + psC.getPeers().length === 2 && + psD.getPeers().length === 2 && + psE.getPeers().length === 1 + ) + }) + + afterEach(async () => { + await stop( + ...Object.values(componentsA), + ...Object.values(componentsB), + ...Object.values(componentsC), + ...Object.values(componentsD), + ...Object.values(componentsE) + ) + await common.teardown() + mockNetwork.reset() + }) + + it('subscribes', () => { + psA.subscribe('Z') + expect(psA.getTopics()).to.deep.equal(['Z']) + psB.subscribe('Z') + expect(psB.getTopics()).to.deep.equal(['Z']) + psC.subscribe('Z') + expect(psC.getTopics()).to.deep.equal(['Z']) + psD.subscribe('Z') + expect(psD.getTopics()).to.deep.equal(['Z']) + psE.subscribe('Z') + expect(psE.getTopics()).to.deep.equal(['Z']) + }) + + it('publishes from c', async function () { + const defer = pDefer() + let counter = 0 + const topic = 'Z' + + psA.subscribe(topic) + psA.addEventListener('message', incMsg) + psB.subscribe(topic) + psB.addEventListener('message', incMsg) + psC.subscribe(topic) + psC.addEventListener('message', incMsg) + psD.subscribe(topic) + psD.addEventListener('message', incMsg) + psE.subscribe(topic) + psE.addEventListener('message', incMsg) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psB, componentsA.peerId), + waitForSubscriptionUpdate(psC, componentsB.peerId), + waitForSubscriptionUpdate(psD, componentsC.peerId), + waitForSubscriptionUpdate(psE, componentsD.peerId) + ]) + + // GossipSub needs time to build the mesh overlay + await delay(1000) + + await psC.publish('Z', uint8ArrayFromString('hey from c')) + + function incMsg (evt: CustomEvent): void { + const msg = evt.detail + + if (msg.topic !== topic) { + return + } + + expect(uint8ArrayToString(msg.data)).to.equal('hey from c') + check() + } + + function check (): void { + if (++counter === 5) { + psA.unsubscribe('Z') + psB.unsubscribe('Z') + psC.unsubscribe('Z') + psD.unsubscribe('Z') + psE.unsubscribe('Z') + defer.resolve() + } + } + + return defer.promise + }) + }) + }) + + describe('only some nodes subscribe the networks', () => { + describe('line', () => { + // line + // ◉────◎────◉ + // a b c + + before(() => { }) + after(() => { }) + }) + + describe('1 level tree', () => { + // 1 level tree + // ┌◉┐ + // │b│ + // ◎─┘ └─◉ + // a c + + before(() => { }) + after(() => { }) + }) + + describe('2 level tree', () => { + // 2 levels tree + // ┌◉┐ + // │c│ + // ┌◎─┘ └─◉┐ + // │b d│ + // ◉─┘ └─◎ + // a e + + before(() => { }) + after(() => { }) + }) + }) + }) +} diff --git a/packages/interface-pubsub-compliance-tests/src/two-nodes.ts b/packages/interface-pubsub-compliance-tests/src/two-nodes.ts new file mode 100644 index 0000000000..77862601d5 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/two-nodes.ts @@ -0,0 +1,273 @@ +/* eslint max-nested-callbacks: ["error", 6] */ +import { mockNetwork } from '@libp2p/interface-mocks' +import { TopicValidatorResult } from '@libp2p/interface-pubsub' +import { start, stop } from '@libp2p/interfaces/startable' +import { expect } from 'aegir/chai' +import pDefer from 'p-defer' +import pWaitFor from 'p-wait-for' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { toString as uint8ArrayToString } from 'uint8arrays/to-string' +import { createComponents, waitForSubscriptionUpdate } from './utils.js' +import type { PubSubArgs, PubSubComponents } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Message, PubSub } from '@libp2p/interface-pubsub' + +const topic = 'foo' + +function shouldNotHappen (): void { + expect.fail() +} + +export default (common: TestSetup): void => { + describe('pubsub with two nodes', () => { + let psA: PubSub + let psB: PubSub + let componentsA: PubSubComponents + let componentsB: PubSubComponents + + // Create pubsub nodes and connect them + beforeEach(async () => { + mockNetwork.reset() + + componentsA = await createComponents() + componentsB = await createComponents() + + psA = componentsA.pubsub = await common.setup({ + components: componentsA, + init: { + emitSelf: true + } + }) + psB = componentsB.pubsub = await common.setup({ + components: componentsB, + init: { + emitSelf: false + } + }) + + // Start pubsub and connect nodes + await start(...Object.values(componentsA), ...Object.values(componentsB)) + + expect(psA.getPeers()).to.be.empty() + expect(psB.getPeers()).to.be.empty() + + await componentsA.connectionManager.openConnection(componentsB.peerId) + + // Wait for peers to be ready in pubsub + await pWaitFor(() => psA.getPeers().length === 1 && psB.getPeers().length === 1) + }) + + afterEach(async () => { + sinon.restore() + await stop(...Object.values(componentsA), ...Object.values(componentsB)) + await common.teardown() + mockNetwork.reset() + }) + + it('Subscribe to a topic in nodeA', async () => { + const defer = pDefer() + + psB.addEventListener('subscription-change', (evt) => { + const { peerId: changedPeerId, subscriptions: changedSubs } = evt.detail + expect(psA.getTopics()).to.deep.equal([topic]) + expect(psB.getPeers()).to.have.lengthOf(1) + expect(psB.getSubscribers(topic).map(p => p.toString())).to.deep.equal([componentsA.peerId.toString()]) + expect(changedPeerId).to.deep.equal(psB.getPeers()[0]) + expect(changedSubs).to.have.lengthOf(1) + expect(changedSubs[0].topic).to.equal(topic) + expect(changedSubs[0].subscribe).to.equal(true) + defer.resolve() + }, { + once: true + }) + psA.subscribe(topic) + + return defer.promise + }) + + it('Publish to a topic in nodeA', async () => { + const defer = pDefer() + + psA.addEventListener('message', (evt) => { + if (evt.detail.topic === topic) { + const msg = evt.detail + expect(uint8ArrayToString(msg.data)).to.equal('hey') + psB.removeEventListener('message', shouldNotHappen) + defer.resolve() + } + }, { + once: true + }) + + psA.subscribe(topic) + psB.subscribe(topic) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psB, componentsA.peerId) + ]) + + await psA.publish(topic, uint8ArrayFromString('hey')) + + return defer.promise + }) + + it('Publish to a topic in nodeB', async () => { + const defer = pDefer() + + psA.addEventListener('message', (evt) => { + if (evt.detail.topic !== topic) { + return + } + + const msg = evt.detail + psA.addEventListener('message', (evt) => { + if (evt.detail.topic === topic) { + shouldNotHappen() + } + }, { + once: true + }) + expect(uint8ArrayToString(msg.data)).to.equal('banana') + + setTimeout(() => { + psA.removeEventListener('message') + psB.removeEventListener('message') + + defer.resolve() + }, 100) + }, { + once: true + }) + + psB.addEventListener('message', shouldNotHappen) + + psA.subscribe(topic) + psB.subscribe(topic) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psB, componentsA.peerId) + ]) + + await psB.publish(topic, uint8ArrayFromString('banana')) + + return defer.promise + }) + + it('validate topic message', async () => { + const defer = pDefer() + + psA.subscribe(topic) + + psB.topicValidators.set(topic, (peer, message) => { + if (!peer.equals(componentsA.peerId)) { + defer.reject(new Error('Invalid peer id in topic validator fn')) + return TopicValidatorResult.Reject + } + + if (uint8ArrayToString(message.data) !== 'hey') { + defer.reject(new Error('Invalid message in topic validator fn')) + return TopicValidatorResult.Reject + } + + defer.resolve() + return TopicValidatorResult.Accept + }) + psB.subscribe(topic) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psB, componentsA.peerId) + ]) + + await psA.publish(topic, uint8ArrayFromString('hey')) + + return defer.promise + }) + + it('Publish 10 msg to a topic in nodeB', async () => { + const defer = pDefer() + let counter = 0 + + psB.addEventListener('message', shouldNotHappen) + psA.addEventListener('message', receivedMsg) + + function receivedMsg (evt: CustomEvent): void { + const msg = evt.detail + if (msg.type === 'unsigned') { + expect(uint8ArrayToString(msg.data)).to.equal('banana') + expect(msg.topic).to.be.equal(topic) + } else { + expect(uint8ArrayToString(msg.data)).to.equal('banana') + expect(msg.from.toString()).to.equal(componentsB.peerId.toString()) + expect(msg.sequenceNumber).to.be.a('BigInt') + expect(msg.topic).to.be.equal(topic) + } + + if (++counter === 10) { + psA.removeEventListener('message', receivedMsg) + psB.removeEventListener('message', shouldNotHappen) + + defer.resolve() + } + } + + psA.subscribe(topic) + psB.subscribe(topic) + + await Promise.all([ + waitForSubscriptionUpdate(psA, componentsB.peerId), + waitForSubscriptionUpdate(psB, componentsA.peerId) + ]) + + await Promise.all( + Array.from({ length: 10 }, async (_, i) => { + await psB.publish(topic, uint8ArrayFromString('banana')) + }) + ) + + return defer.promise + }) + + it('Unsubscribe from topic in nodeA', async () => { + const defer = pDefer() + let callCount = 0 + + psB.addEventListener('subscription-change', (evt) => { + callCount++ + + if (callCount === 1) { + // notice subscribe + const { peerId: changedPeerId, subscriptions: changedSubs } = evt.detail + expect(psB.getPeers()).to.have.lengthOf(1) + expect(psB.getTopics()).to.be.empty() + expect(changedPeerId).to.deep.equal(psB.getPeers()[0]) + expect(changedSubs).to.have.lengthOf(1) + expect(changedSubs[0].topic).to.equal(topic) + expect(changedSubs[0].subscribe).to.equal(true) + } else { + // notice unsubscribe + const { peerId: changedPeerId, subscriptions: changedSubs } = evt.detail + expect(psB.getPeers()).to.have.lengthOf(1) + expect(psB.getTopics()).to.be.empty() + expect(changedPeerId).to.deep.equal(psB.getPeers()[0]) + expect(changedSubs).to.have.lengthOf(1) + expect(changedSubs[0].topic).to.equal(topic) + expect(changedSubs[0].subscribe).to.equal(false) + + defer.resolve() + } + }) + + psA.subscribe(topic) + expect(psA.getTopics()).to.not.be.empty() + + psA.unsubscribe(topic) + expect(psA.getTopics()).to.be.empty() + + return defer.promise + }) + }) +} diff --git a/packages/interface-pubsub-compliance-tests/src/utils.ts b/packages/interface-pubsub-compliance-tests/src/utils.ts new file mode 100644 index 0000000000..80e52c5362 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/src/utils.ts @@ -0,0 +1,27 @@ +import { mockConnectionManager, mockRegistrar, mockNetwork } from '@libp2p/interface-mocks' +import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { pEvent } from 'p-event' +import pWaitFor from 'p-wait-for' +import type { MockNetworkComponents } from '@libp2p/interface-mocks' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { PubSub, SubscriptionChangeData } from '@libp2p/interface-pubsub' + +export async function waitForSubscriptionUpdate (a: PubSub, b: PeerId): Promise { + await pWaitFor(async () => { + const event = await pEvent<'subscription-change', CustomEvent>(a, 'subscription-change') + + return event.detail.peerId.equals(b) + }) +} + +export async function createComponents (): Promise { + const components: any = { + peerId: await createEd25519PeerId(), + registrar: mockRegistrar() + } + components.connectionManager = mockConnectionManager(components) + + mockNetwork.addNode(components) + + return components +} diff --git a/packages/interface-pubsub-compliance-tests/tsconfig.json b/packages/interface-pubsub-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..e128c8d1e9 --- /dev/null +++ b/packages/interface-pubsub-compliance-tests/tsconfig.json @@ -0,0 +1,33 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-connection-manager" + }, + { + "path": "../interface-mocks" + }, + { + "path": "../interface-peer-id" + }, + { + "path": "../interface-pubsub" + }, + { + "path": "../interface-registrar" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-pubsub/CHANGELOG.md b/packages/interface-pubsub/CHANGELOG.md new file mode 100644 index 0000000000..97617fba67 --- /dev/null +++ b/packages/interface-pubsub/CHANGELOG.md @@ -0,0 +1,148 @@ +## [@libp2p/interface-pubsub-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v4.0.0...@libp2p/interface-pubsub-v4.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-pubsub-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.7...@libp2p/interface-pubsub-v4.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-pubsub-v3.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.6...@libp2p/interface-pubsub-v3.0.7) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-pubsub-v3.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.5...@libp2p/interface-pubsub-v3.0.6) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-pubsub-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.4...@libp2p/interface-pubsub-v3.0.5) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-pubsub-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.3...@libp2p/interface-pubsub-v3.0.4) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-pubsub-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.2...@libp2p/interface-pubsub-v3.0.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-pubsub-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.1...@libp2p/interface-pubsub-v3.0.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-pubsub-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v3.0.0...@libp2p/interface-pubsub-v3.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-pubsub-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v2.1.0...@libp2p/interface-pubsub-v3.0.0) (2022-10-11) + + +### ⚠ BREAKING CHANGES + +* add topicValidators to pubsub interface (#298) + +### Bug Fixes + +* add topicValidators to pubsub interface ([#298](https://github.com/libp2p/js-libp2p-interfaces/issues/298)) ([e5ff819](https://github.com/libp2p/js-libp2p-interfaces/commit/e5ff819c6dd235b2ea9ea5133457b384c4411cf3)) + +## [@libp2p/interface-pubsub-v2.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v2.0.1...@libp2p/interface-pubsub-v2.1.0) (2022-09-09) + + +### Features + +* add dialer interface ([#285](https://github.com/libp2p/js-libp2p-interfaces/issues/285)) ([1e62df4](https://github.com/libp2p/js-libp2p-interfaces/commit/1e62df4f15b45abe62fe8400dbd88866a2bc13cd)) + +## [@libp2p/interface-pubsub-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v2.0.0...@libp2p/interface-pubsub-v2.0.1) (2022-08-07) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-pubsub-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v1.0.4...@libp2p/interface-pubsub-v2.0.0) (2022-07-31) + + +### ⚠ BREAKING CHANGES + +* The `Message` type is now either a `SignedMessage` +or a `UnsignedMessage` +* the inbound/outbound stream types have changed + +### Features + +* pubsub Message types for signature policies ([#266](https://github.com/libp2p/js-libp2p-interfaces/issues/266)) ([9eb710b](https://github.com/libp2p/js-libp2p-interfaces/commit/9eb710bcbdb0aef95c7a8613e00065a3b7c7f887)) + + +### Bug Fixes + +* make stream types Uint8ArrayLists ([#272](https://github.com/libp2p/js-libp2p-interfaces/issues/272)) ([ace7e0c](https://github.com/libp2p/js-libp2p-interfaces/commit/ace7e0cdb81dd241a8e96a44e841d38b2b80e031)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-pubsub-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v1.0.3...@libp2p/interface-pubsub-v1.0.4) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-pubsub-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v1.0.2...@libp2p/interface-pubsub-v1.0.3) (2022-06-17) + + +### Bug Fixes + +* add stream control for pubsub ([#248](https://github.com/libp2p/js-libp2p-interfaces/issues/248)) ([e687895](https://github.com/libp2p/js-libp2p-interfaces/commit/e687895267d98fcd99d6d0d849527ab9eed69695)) + +## [@libp2p/interface-pubsub-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v1.0.1...@libp2p/interface-pubsub-v1.0.2) (2022-06-16) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) + +## [@libp2p/interface-pubsub-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-pubsub-v1.0.0...@libp2p/interface-pubsub-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update it-pushable dep ([#237](https://github.com/libp2p/js-libp2p-interfaces/issues/237)) ([2e16465](https://github.com/libp2p/js-libp2p-interfaces/commit/2e164658df344b5ec475be2a571df5d6f20ee086)) diff --git a/packages/interface-pubsub/LICENSE b/packages/interface-pubsub/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-pubsub/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-pubsub/LICENSE-APACHE b/packages/interface-pubsub/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-pubsub/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-pubsub/LICENSE-MIT b/packages/interface-pubsub/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-pubsub/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-pubsub/README.md b/packages/interface-pubsub/README.md new file mode 100644 index 0000000000..c5d0dbf9f9 --- /dev/null +++ b/packages/interface-pubsub/README.md @@ -0,0 +1,323 @@ +# @libp2p/interface-pubsub + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> PubSub interface for libp2p + +## Table of contents + +- - [Install](#install) +- [Table of Contents ](#table-of-contents----omit-in-toc---) + - [Implementations using this interface](#implementations-using-this-interface) + - [Interface usage](#interface-usage) + - [Extend interface](#extend-interface) + - [Example](#example) + - [API](#api) + - [Constructor](#constructor) + - [`new Pubsub({options})`](#new-pubsuboptions) + - [Parameters](#parameters) + - [Start](#start) + - [`pubsub.start()`](#pubsubstart) + - [Stop](#stop) + - [`pubsub.stop()`](#pubsubstop) + - [Publish](#publish) + - [`pubsub.publish(topic, message)`](#pubsubpublishtopic-message) + - [Parameters](#parameters-1) + - [Returns](#returns) + - [Subscribe](#subscribe) + - [`pubsub.subscribe(topic)`](#pubsubsubscribetopic) + - [Parameters](#parameters-2) + - [Unsubscribe](#unsubscribe) + - [`pubsub.unsubscribe(topic)`](#pubsubunsubscribetopic) + - [Parameters](#parameters-3) + - [Get Topics](#get-topics) + - [`pubsub.getTopics()`](#pubsubgettopics) + - [Returns](#returns-1) + - [Get Peers Subscribed to a topic](#get-peers-subscribed-to-a-topic) + - [`pubsub.getSubscribers(topic)`](#pubsubgetsubscriberstopic) + - [Parameters](#parameters-4) + - [Returns](#returns-2) + - [Validate](#validate) + - [`pubsub.validate(message)`](#pubsubvalidatemessage) + - [Parameters](#parameters-5) + - [Returns](#returns-3) + - [Test suite usage](#test-suite-usage) + - [API Docs](#api-docs) + - [License](#license) + - [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-pubsub +``` + +The `interface-pubsub` contains the base implementation for a libp2p pubsub router implementation. This interface should be used to implement a pubsub router compatible with libp2p. It includes a test suite that pubsub routers should run, in order to ensure compatibility with libp2p. + +# Table of Contents + +- [Implementations using this interface](#implementations-using-this-interface) +- [Interface usage](#interface-usage) + - [Extend interface](#extend-interface) + - [Example](#example) +- [API](#api) + - [Constructor](#constructor) + - [`new Pubsub({options})`](#new-pubsuboptions) + - [Parameters](#parameters) + - [Start](#start) + - [`pubsub.start()`](#pubsubstart) + - [Stop](#stop) + - [`pubsub.stop()`](#pubsubstop) + - [Publish](#publish) + - [`pubsub.publish(topic, message)`](#pubsubpublishtopic-message) + - [Parameters](#parameters-1) + - [Returns](#returns) + - [Subscribe](#subscribe) + - [`pubsub.subscribe(topic)`](#pubsubsubscribetopic) + - [Parameters](#parameters-2) + - [Unsubscribe](#unsubscribe) + - [`pubsub.unsubscribe(topic)`](#pubsubunsubscribetopic) + - [Parameters](#parameters-3) + - [Get Topics](#get-topics) + - [`pubsub.getTopics()`](#pubsubgettopics) + - [Returns](#returns-1) + - [Get Peers Subscribed to a topic](#get-peers-subscribed-to-a-topic) + - [`pubsub.getSubscribers(topic)`](#pubsubgetsubscriberstopic) + - [Parameters](#parameters-4) + - [Returns](#returns-2) + - [Validate](#validate) + - [`pubsub.validate(message)`](#pubsubvalidatemessage) + - [Parameters](#parameters-5) + - [Returns](#returns-3) +- [Test suite usage](#test-suite-usage) +- [License](#license) + - [Contribution](#contribution) + +## Implementations using this interface + +You can check the following implementations as examples for building your own pubsub router. + +- [libp2p/js-libp2p-floodsub](https://github.com/libp2p/js-libp2p-floodsub) +- [ChainSafe/js-libp2p-gossipsub](https://github.com/ChainSafe/js-libp2p-gossipsub) + +## Interface usage + +`interface-pubsub` abstracts the implementation protocol registration within `libp2p` and takes care of all the protocol connections and streams, as well as the subscription management and the features describe in the libp2p [pubsub specs](https://github.com/libp2p/specs/tree/master/pubsub). This way, a pubsub implementation can focus on its message routing algorithm, instead of also needing to create the setup for it. + +### Extend interface + +A pubsub router implementation should start by extending the `interface-pubsub` class and **MUST** override the `_publish` function, according to the router algorithms. This function is responsible for forwarding publish messages to other peers, as well as forwarding received messages if the router provides the `canRelayMessage` option to the base implementation. + +Other functions, such as `start`, `stop`, `subscribe`, `unsubscribe`, `_encodeRpc`, `_decodeRpc`, `_processRpcMessage`, `_addPeer` and `_removePeer` may be overwritten if the pubsub implementation needs to customize their logic. Implementations overriding these functions **MUST** call `super`. + +The `start` and `stop` functions are responsible for the registration of the pubsub protocol with libp2p. The `stop` function also guarantees that the open streams in the protocol are properly closed. + +The `subscribe` and `unsubscribe` functions take care of the subscription management and its inherent message propagation. + +When using a custom protobuf definition for message marshalling, you should override `_encodeRpc` and `_decodeRpc` to use the new protobuf instead of the default one. + +`_processRpcMessage` is responsible for handling messages received from other peers. This should be extended if further operations/validations are needed by the router. + +The `_addPeer` and `_removePeer` functions are called when new peers running the pubsub router protocol establish a connection with the peer. They are used for tracking the open streams between the peers. + +All the remaining functions **MUST NOT** be overwritten. + +### Example + +The following example aims to show how to create your pubsub implementation extending this base protocol. The pubsub implementation will handle the subscriptions logic. + +```JavaScript +const Pubsub = require('libp2p-interfaces/src/pubsub') + +class PubsubImplementation extends Pubsub { + constructor({ libp2p, options }) + super({ + debugName: 'libp2p:pubsub', + multicodecs: '/pubsub-implementation/1.0.0', + libp2p, + globalSigningPolicy: options.globalSigningPolicy + }) + } + + _publish (message) { + // Required to be implemented by the subclass + // Routing logic for the message + } +} +``` + +## API + +The interface aims to specify a common interface that all pubsub router implementation should follow. A pubsub router implementation should extend the [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter). When peers receive pubsub messages, these messages will be emitted by the event emitter where the `eventName` will be the `topic` associated with the message. + +### Constructor + +The base class constructor configures the pubsub instance for use with a libp2p instance. It includes settings for logging, signature policies, etc. + +#### `new Pubsub({options})` + +##### Parameters + +| Name | Type | Description | Default | +| ----------------------------- | -------------------------------- | ----------------------------------------------- | -------------------- | +| options.libp2p | `Libp2p` | libp2p instance | required, no default | +| options.debugName | `string` | log namespace | required, no default | +| options.multicodecs | `string \| Array` | protocol identifier(s) | required, no default | +| options.globalSignaturePolicy | `'StrictSign' \| 'StrictNoSign'` | signature policy to be globally applied | `'StrictSign'` | +| options.canRelayMessage | `boolean` | if can relay messages if not subscribed | `false` | +| options.emitSelf | `boolean` | if `publish` should emit to self, if subscribed | `false` | + +### Start + +Starts the pubsub subsystem. The protocol will be registered to `libp2p`, which will result in pubsub being notified when peers who support the protocol connect/disconnect to `libp2p`. + +#### `pubsub.start()` + +### Stop + +Stops the pubsub subsystem. The protocol will be unregistered from `libp2p`, which will remove all listeners for the protocol and the established connections will be closed. + +#### `pubsub.stop()` + +### Publish + +Publish data message to pubsub topics. + +#### `pubsub.publish(topic, message)` + +##### Parameters + +| Name | Type | Description | +| ------- | ------------ | ------------------ | +| topic | `string` | pubsub topic | +| message | `Uint8Array` | message to publish | + +##### Returns + +| Type | Description | +| --------------- | ----------------------------------------------------- | +| `Promise` | resolves once the message is published to the network | + +### Subscribe + +Subscribe to the given topic. + +#### `pubsub.subscribe(topic)` + +##### Parameters + +| Name | Type | Description | +| ----- | -------- | ------------ | +| topic | `string` | pubsub topic | + +### Unsubscribe + +Unsubscribe from the given topic. + +#### `pubsub.unsubscribe(topic)` + +##### Parameters + +| Name | Type | Description | +| ----- | -------- | ------------ | +| topic | `string` | pubsub topic | + +### Get Topics + +Get the list of topics which the peer is subscribed to. + +#### `pubsub.getTopics()` + +##### Returns + +| Type | Description | +| --------------- | -------------------------- | +| `Array` | Array of subscribed topics | + +### Get Peers Subscribed to a topic + +Get a list of the [PeerId](https://github.com/libp2p/js-peer-id) strings that are subscribed to one topic. + +#### `pubsub.getSubscribers(topic)` + +##### Parameters + +| Name | Type | Description | +| ----- | -------- | ------------ | +| topic | `string` | pubsub topic | + +##### Returns + +| Type | Description | +| --------------- | ------------------------- | +| `Array` | Array of base-58 PeerId's | + +### Validate + +Validates a message according to the signature policy and topic-specific validation function. + +#### `pubsub.validate(message)` + +##### Parameters + +| Name | Type | Description | +| ------- | --------- | ---------------- | +| message | `Message` | a pubsub message | + +#### Returns + +| Type | Description | +| --------------- | -------------------------------- | +| `Promise` | resolves if the message is valid | + +## Test suite usage + +```js +'use strict' + +const tests = require('libp2p-interfaces-compliance-tests/pubsub') +const YourPubsubRouter = require('../src') + +describe('compliance', () => { + let peers + let pubsubNodes = [] + + tests({ + async setup (number = 1, options = {}) { + // Create number pubsub nodes with libp2p + peers = await createPeers({ number }) + + peers.forEach((peer) => { + const ps = new YourPubsubRouter(peer, options) + + pubsubNodes.push(ps) + }) + + return pubsubNodes + }, + async teardown () { + // Clean up any resources created by setup() + await Promise.all(pubsubNodes.map(ps => ps.stop())) + peers.length && await Promise.all(peers.map(peer => peer.stop())) + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-pubsub/package.json b/packages/interface-pubsub/package.json new file mode 100644 index 0000000000..f10d63a753 --- /dev/null +++ b/packages/interface-pubsub/package.json @@ -0,0 +1,143 @@ +{ + "name": "@libp2p/interface-pubsub", + "version": "4.0.1", + "description": "PubSub interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-pubsub#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interfaces": "^3.0.0", + "it-pushable": "^3.1.3", + "uint8arraylist": "^2.4.3" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-pubsub/src/index.ts b/packages/interface-pubsub/src/index.ts new file mode 100644 index 0000000000..575bebfb47 --- /dev/null +++ b/packages/interface-pubsub/src/index.ts @@ -0,0 +1,269 @@ +import type { Stream } from '@libp2p/interface-connection' +import type { PeerId } from '@libp2p/interface-peer-id' +import type { EventEmitter } from '@libp2p/interfaces/events' +import type { Pushable } from 'it-pushable' +import type { Uint8ArrayList } from 'uint8arraylist' + +/** + * On the producing side: + * * Build messages with the signature, key (from may be enough for certain inlineable public key types), from and seqno fields. + * + * On the consuming side: + * * Enforce the fields to be present, reject otherwise. + * * Propagate only if the fields are valid and signature can be verified, reject otherwise. + */ +export const StrictSign = 'StrictSign' + +/** + * On the producing side: + * * Build messages without the signature, key, from and seqno fields. + * * The corresponding protobuf key-value pairs are absent from the marshalled message, not just empty. + * + * On the consuming side: + * * Enforce the fields to be absent, reject otherwise. + * * Propagate only if the fields are absent, reject otherwise. + * * A message_id function will not be able to use the above fields, and should instead rely on the data field. A commonplace strategy is to calculate a hash. + */ +export const StrictNoSign = 'StrictNoSign' + +export type SignaturePolicy = typeof StrictSign | typeof StrictNoSign + +export interface SignedMessage { + type: 'signed' + from: PeerId + topic: string + data: Uint8Array + sequenceNumber: bigint + signature: Uint8Array + key: Uint8Array +} + +export interface UnsignedMessage { + type: 'unsigned' + topic: string + data: Uint8Array +} + +export type Message = SignedMessage | UnsignedMessage + +export interface PubSubRPCMessage { + from?: Uint8Array + topic?: string + data?: Uint8Array + sequenceNumber?: Uint8Array + signature?: Uint8Array + key?: Uint8Array +} + +export interface PubSubRPCSubscription { + subscribe?: boolean + topic?: string +} + +export interface PubSubRPC { + subscriptions: PubSubRPCSubscription[] + messages: PubSubRPCMessage[] +} + +export interface PeerStreams extends EventEmitter { + id: PeerId + protocol: string + outboundStream?: Pushable + inboundStream?: AsyncIterable + isWritable: boolean + + close: () => void + write: (buf: Uint8Array | Uint8ArrayList) => void + attachInboundStream: (stream: Stream) => AsyncIterable + attachOutboundStream: (stream: Stream) => Promise> +} + +export interface PubSubInit { + enabled?: boolean + + multicodecs?: string[] + + /** + * defines how signatures should be handled + */ + globalSignaturePolicy?: SignaturePolicy + + /** + * if can relay messages not subscribed + */ + canRelayMessage?: boolean + + /** + * if publish should emit to self, if subscribed + */ + emitSelf?: boolean + + /** + * handle this many incoming pubsub messages concurrently + */ + messageProcessingConcurrency?: number + + /** + * How many parallel incoming streams to allow on the pubsub protocol per-connection + */ + maxInboundStreams?: number + + /** + * How many parallel outgoing streams to allow on the pubsub protocol per-connection + */ + maxOutboundStreams?: number +} + +interface Subscription { + topic: string + subscribe: boolean +} + +export interface SubscriptionChangeData { + peerId: PeerId + subscriptions: Subscription[] +} + +export interface PubSubEvents { + 'subscription-change': CustomEvent + 'message': CustomEvent +} + +export interface PublishResult { + recipients: PeerId[] +} + +export enum TopicValidatorResult { + /** + * The message is considered valid, and it should be delivered and forwarded to the network + */ + Accept = 'accept', + /** + * The message is neither delivered nor forwarded to the network + */ + Ignore = 'ignore', + /** + * The message is considered invalid, and it should be rejected + */ + Reject = 'reject' +} + +export interface TopicValidatorFn { + (peer: PeerId, message: Message): TopicValidatorResult | Promise +} + +export interface PubSub = PubSubEvents> extends EventEmitter { + /** + * The global signature policy controls whether or not we sill send and receive + * signed or unsigned messages. + * + * Signed messages prevent spoofing message senders and should be preferred to + * using unsigned messages. + */ + globalSignaturePolicy: typeof StrictSign | typeof StrictNoSign + + /** + * A list of multicodecs that contain the pubsub protocol name. + */ + multicodecs: string[] + + /** + * Pubsub routers support message validators per topic, which will validate the message + * before its propagations. They are stored in a map where keys are the topic name and + * values are the validators. + * + * @example + * + * ```js + * const topic = 'topic' + * const validateMessage = (msgTopic, msg) => { + * const input = uint8ArrayToString(msg.data) + * const validInputs = ['a', 'b', 'c'] + * + * if (!validInputs.includes(input)) { + * throw new Error('no valid input received') + * } + * } + * libp2p.pubsub.topicValidators.set(topic, validateMessage) + * ``` + */ + topicValidators: Map + + getPeers: () => PeerId[] + + /** + * Gets a list of topics the node is subscribed to. + * + * ```js + * const topics = libp2p.pubsub.getTopics() + * ``` + */ + getTopics: () => string[] + + /** + * Subscribes to a pubsub topic. + * + * @example + * + * ```js + * const topic = 'topic' + * const handler = (msg) => { + * if (msg.topic === topic) { + * // msg.data - pubsub data received + * } + * } + * + * libp2p.pubsub.addEventListener('message', handler) + * libp2p.pubsub.subscribe(topic) + * ``` + */ + subscribe: (topic: string) => void + + /** + * Unsubscribes from a pubsub topic. + * + * @example + * + * ```js + * const topic = 'topic' + * const handler = (msg) => { + * // msg.data - pubsub data received + * } + * + * libp2p.pubsub.removeEventListener(topic handler) + * libp2p.pubsub.unsubscribe(topic) + * ``` + */ + unsubscribe: (topic: string) => void + + /** + * Gets a list of the PeerIds that are subscribed to one topic. + * + * @example + * + * ```js + * const peerIds = libp2p.pubsub.getSubscribers(topic) + * ``` + */ + getSubscribers: (topic: string) => PeerId[] + + /** + * Publishes messages to the given topic. + * + * @example + * + * ```js + * const topic = 'topic' + * const data = uint8ArrayFromString('data') + * + * await libp2p.pubsub.publish(topic, data) + * ``` + */ + publish: (topic: string, data: Uint8Array) => Promise +} + +export interface PeerStreamEvents { + 'stream:inbound': CustomEvent + 'stream:outbound': CustomEvent + 'close': CustomEvent +} diff --git a/packages/interface-pubsub/tsconfig.json b/packages/interface-pubsub/tsconfig.json new file mode 100644 index 0000000000..cbde3d05cb --- /dev/null +++ b/packages/interface-pubsub/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interface-peer-id" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-record-compliance-tests/CHANGELOG.md b/packages/interface-record-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..930998e607 --- /dev/null +++ b/packages/interface-record-compliance-tests/CHANGELOG.md @@ -0,0 +1,63 @@ +## [@libp2p/interface-record-compliance-tests-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-compliance-tests-v2.0.4...@libp2p/interface-record-compliance-tests-v2.0.5) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-record-compliance-tests-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-compliance-tests-v2.0.3...@libp2p/interface-record-compliance-tests-v2.0.4) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-record-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-compliance-tests-v2.0.2...@libp2p/interface-record-compliance-tests-v2.0.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-record-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-compliance-tests-v2.0.1...@libp2p/interface-record-compliance-tests-v2.0.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-record-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-compliance-tests-v2.0.0...@libp2p/interface-record-compliance-tests-v2.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-record-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-compliance-tests-v1.0.1...@libp2p/interface-record-compliance-tests-v2.0.0) (2022-08-03) + + +### ⚠ BREAKING CHANGES + +* return type of .marshal method and several properties have changed + +### Bug Fixes + +* make record property and return types lists ([#276](https://github.com/libp2p/js-libp2p-interfaces/issues/276)) ([4df31d0](https://github.com/libp2p/js-libp2p-interfaces/commit/4df31d0a1da48dcffd3644e817b0641dca7bd111)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) +* update sibling dependencies [skip ci] ([39eed35](https://github.com/libp2p/js-libp2p-interfaces/commit/39eed35c17920032ef821eede4d09fe14f8b30ab)) + +## [@libp2p/interface-record-compliance-tests-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-compliance-tests-v1.0.0...@libp2p/interface-record-compliance-tests-v1.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) diff --git a/packages/interface-record-compliance-tests/LICENSE b/packages/interface-record-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-record-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-record-compliance-tests/LICENSE-APACHE b/packages/interface-record-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-record-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-record-compliance-tests/LICENSE-MIT b/packages/interface-record-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-record-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-record-compliance-tests/README.md b/packages/interface-record-compliance-tests/README.md new file mode 100644 index 0000000000..d62d96cd89 --- /dev/null +++ b/packages/interface-record-compliance-tests/README.md @@ -0,0 +1,55 @@ +# @libp2p/interface-record-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for implementations of the libp2p Record interface + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-record-compliance-tests +``` + +## Usage + +```js +import tests from '@libp2p/interface-record-tests' + +describe('your record implementation', () => { + tests({ + // Options should be passed to your implementation + async setup (options) { + return new YourImplementation() + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-record-compliance-tests/package.json b/packages/interface-record-compliance-tests/package.json new file mode 100644 index 0000000000..cc9d9f6277 --- /dev/null +++ b/packages/interface-record-compliance-tests/package.json @@ -0,0 +1,138 @@ +{ + "name": "@libp2p/interface-record-compliance-tests", + "version": "2.0.5", + "description": "Compliance tests for implementations of the libp2p Record interface", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-record-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-record": "^2.0.0", + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-record-compliance-tests/src/index.ts b/packages/interface-record-compliance-tests/src/index.ts new file mode 100644 index 0000000000..a4d9e436c4 --- /dev/null +++ b/packages/interface-record-compliance-tests/src/index.ts @@ -0,0 +1,32 @@ +import { expect } from 'aegir/chai' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Record } from '@libp2p/interface-record' + +export default (test: TestSetup): void => { + describe('record', () => { + let record: Record + + beforeEach(async () => { + record = await test.setup() + }) + + afterEach(async () => { + await test.teardown() + }) + + it('has domain and codec', () => { + expect(record.domain).to.exist() + expect(record.codec).to.exist() + }) + + it('is able to marshal', () => { + const rawData = record.marshal() + expect(rawData).to.have.property('byteLength') + }) + + it('is able to compare two records', () => { + const equals = record.equals(record) + expect(equals).to.eql(true) + }) + }) +} diff --git a/packages/interface-record-compliance-tests/tsconfig.json b/packages/interface-record-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..6ca17f6cde --- /dev/null +++ b/packages/interface-record-compliance-tests/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-record" + } + ] +} diff --git a/packages/interface-record/CHANGELOG.md b/packages/interface-record/CHANGELOG.md new file mode 100644 index 0000000000..eab614002e --- /dev/null +++ b/packages/interface-record/CHANGELOG.md @@ -0,0 +1,95 @@ +## [@libp2p/interface-record-v2.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v2.0.6...@libp2p/interface-record-v2.0.7) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-record-v2.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v2.0.5...@libp2p/interface-record-v2.0.6) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-record-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v2.0.4...@libp2p/interface-record-v2.0.5) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-record-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v2.0.3...@libp2p/interface-record-v2.0.4) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-record-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v2.0.2...@libp2p/interface-record-v2.0.3) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-record-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v2.0.1...@libp2p/interface-record-v2.0.2) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-record-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v2.0.0...@libp2p/interface-record-v2.0.1) (2022-08-11) + + +### Bug Fixes + +* update marshal type ([#282](https://github.com/libp2p/js-libp2p-interfaces/issues/282)) ([2c04ff9](https://github.com/libp2p/js-libp2p-interfaces/commit/2c04ff98097ba33dc64878b788c6b9318d2ea98b)) + +## [@libp2p/interface-record-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v1.0.2...@libp2p/interface-record-v2.0.0) (2022-08-03) + + +### ⚠ BREAKING CHANGES + +* return type of .marshal method and several properties have changed + +### Bug Fixes + +* make record property and return types lists ([#276](https://github.com/libp2p/js-libp2p-interfaces/issues/276)) ([4df31d0](https://github.com/libp2p/js-libp2p-interfaces/commit/4df31d0a1da48dcffd3644e817b0641dca7bd111)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interface-record-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v1.0.1...@libp2p/interface-record-v1.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-record-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-record-v1.0.0...@libp2p/interface-record-v1.0.1) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## @libp2p/interface-record-v1.0.0 (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) diff --git a/packages/interface-record/LICENSE b/packages/interface-record/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-record/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-record/LICENSE-APACHE b/packages/interface-record/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-record/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-record/LICENSE-MIT b/packages/interface-record/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-record/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-record/README.md b/packages/interface-record/README.md new file mode 100644 index 0000000000..9e63dc40a7 --- /dev/null +++ b/packages/interface-record/README.md @@ -0,0 +1,132 @@ +# @libp2p/interface-record + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Record interface for libp2p + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [Create Record](#create-record) +- [API](#api) + - [marshal](#marshal) + - [equals](#equals) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-record +``` + +A libp2p node needs to store data in a public location (e.g. a DHT), or rely on potentially untrustworthy intermediaries to relay information. Libp2p provides an all-purpose data container called **envelope**, which includes a signature of the data, so that it its authenticity can be verified. + +The record represents the data that will be stored inside the **envelope** when distributing records across the network. The `interface-record` aims to guarantee that any type of record created is compliant with the libp2p **envelope**. + +Taking into account that a record might be used in different contexts, an **envelope** signature made for a specific purpose **must not** be considered valid for a different purpose. Accordingly, each record has a short and descriptive string representing the record use case, known as **domain**. The data to be signed will be prepended with the domain string, in order to create a domain signature. + +A record can also contain a Uint8Array codec (ideally registered as a [multicodec](https://github.com/multiformats/multicodec)). This codec will prefix the record data in the **envelope** , so that it can be deserialized deterministically. + +## Usage + +```js +const tests = require('libp2p-interfaces-compliance-tests/record') +describe('your record', () => { + tests({ + async setup () { + return YourRecord + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## Create Record + +```js +const multicodec = require('multicodec') +const Record = require('libp2p-interfaces/src/record') +const { fromString } = require('uint8arrays/from-string') +// const Protobuf = require('./record.proto') + +const ENVELOPE_DOMAIN_PEER_RECORD = 'libp2p-peer-record' +const ENVELOPE_PAYLOAD_TYPE_PEER_RECORD = fromString('0301', 'hex') + +/** + * @implements {import('libp2p-interfaces/src/record/types').Record} + */ +class PeerRecord { + constructor (peerId, multiaddrs, seqNumber) { + this.domain = ENVELOPE_DOMAIN_PEER_RECORD + this.codec = ENVELOPE_PAYLOAD_TYPE_PEER_RECORD + } + + /** + * Marshal a record to be used in an envelope. + * + * @returns {Uint8Array} + */ + marshal () { + // Implement and return using Protobuf + } + + /** + * Returns true if `this` record equals the `other`. + * + * @param {PeerRecord} other + * @returns {other is Record} + */ + equals (other) { + // Verify + } +} +``` + +## API + +### marshal + +- `record.marshal()` + +Marshal a record to be used in a libp2p envelope. + +**Returns** + +It returns a `Protobuf` containing the record data. + +### equals + +- `record.equals(other)` + +Verifies if the other Record is identical to this one. + +**Parameters** + +- other is a `Record` to compare with the current instance. + +**Returns** + +- `other is Record` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-record/package.json b/packages/interface-record/package.json new file mode 100644 index 0000000000..bec81eabc8 --- /dev/null +++ b/packages/interface-record/package.json @@ -0,0 +1,140 @@ +{ + "name": "@libp2p/interface-record", + "version": "2.0.7", + "description": "Record interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-record#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-peer-id": "^2.0.0", + "uint8arraylist": "^2.4.3" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-record/src/index.ts b/packages/interface-record/src/index.ts new file mode 100644 index 0000000000..6903f50588 --- /dev/null +++ b/packages/interface-record/src/index.ts @@ -0,0 +1,35 @@ +import type { PeerId } from '@libp2p/interface-peer-id' +import type { Uint8ArrayList } from 'uint8arraylist' + +/** + * Record is the base implementation of a record that can be used as the payload of a libp2p envelope. + */ +export interface Record { + /** + * signature domain. + */ + domain: string + /** + * identifier of the type of record + */ + codec: Uint8Array + /** + * Marshal a record to be used in an envelope. + */ + marshal: () => Uint8Array + /** + * Verifies if the other provided Record is identical to this one. + */ + equals: (other: Record) => boolean +} + +export interface Envelope { + peerId: PeerId + payloadType: Uint8Array | Uint8ArrayList + payload: Uint8Array + signature: Uint8Array | Uint8ArrayList + + marshal: () => Uint8Array + validate: (domain: string) => Promise + equals: (other: Envelope) => boolean +} diff --git a/packages/interface-record/tsconfig.json b/packages/interface-record/tsconfig.json new file mode 100644 index 0000000000..9da008198f --- /dev/null +++ b/packages/interface-record/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-registrar/CHANGELOG.md b/packages/interface-registrar/CHANGELOG.md new file mode 100644 index 0000000000..164110e7c7 --- /dev/null +++ b/packages/interface-registrar/CHANGELOG.md @@ -0,0 +1,116 @@ +## [@libp2p/interface-registrar-v2.0.12](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.11...@libp2p/interface-registrar-v2.0.12) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-registrar-v2.0.11](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.10...@libp2p/interface-registrar-v2.0.11) (2023-04-18) + + +### Dependencies + +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-registrar-v2.0.10](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.9...@libp2p/interface-registrar-v2.0.10) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-registrar-v2.0.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.8...@libp2p/interface-registrar-v2.0.9) (2023-03-09) + + +### Documentation + +* update comments on registrar interface ([#348](https://github.com/libp2p/js-libp2p-interfaces/issues/348)) ([54e3af9](https://github.com/libp2p/js-libp2p-interfaces/commit/54e3af9cfbdfd27d1c3797b957a97931153337c6)) + +## [@libp2p/interface-registrar-v2.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.7...@libp2p/interface-registrar-v2.0.8) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-registrar-v2.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.6...@libp2p/interface-registrar-v2.0.7) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([b50e621](https://github.com/libp2p/js-libp2p-interfaces/commit/b50e621d31a8b32affc3fadb9f97c4883d577f93)) + +## [@libp2p/interface-registrar-v2.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.5...@libp2p/interface-registrar-v2.0.6) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-registrar-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.4...@libp2p/interface-registrar-v2.0.5) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-registrar-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.3...@libp2p/interface-registrar-v2.0.4) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-registrar-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.2...@libp2p/interface-registrar-v2.0.3) (2022-08-07) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-registrar-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.1...@libp2p/interface-registrar-v2.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-registrar-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v2.0.0...@libp2p/interface-registrar-v2.0.1) (2022-06-17) + + +### Bug Fixes + +* update stream handler args ([#247](https://github.com/libp2p/js-libp2p-interfaces/issues/247)) ([d29e134](https://github.com/libp2p/js-libp2p-interfaces/commit/d29e134bd70295c725bfd627d5887954d1a278ae)) + +## [@libp2p/interface-registrar-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v1.1.0...@libp2p/interface-registrar-v2.0.0) (2022-06-16) + + +### ⚠ BREAKING CHANGES + +* The Connection and Stream APIs have been updated + +### Features + +* store stream data on the stream, track the stream direction ([#245](https://github.com/libp2p/js-libp2p-interfaces/issues/245)) ([6d74d2f](https://github.com/libp2p/js-libp2p-interfaces/commit/6d74d2f9f344fb4d6741ba0d35263ebe351a4c65)) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) + +## [@libp2p/interface-registrar-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-registrar-v1.0.0...@libp2p/interface-registrar-v1.1.0) (2022-06-16) + + +### Features + +* define stream limits as input/output ([#240](https://github.com/libp2p/js-libp2p-interfaces/issues/240)) ([554fe95](https://github.com/libp2p/js-libp2p-interfaces/commit/554fe95865c4851fcef3b311d80d44f82a613969)) diff --git a/packages/interface-registrar/LICENSE b/packages/interface-registrar/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-registrar/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-registrar/LICENSE-APACHE b/packages/interface-registrar/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-registrar/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-registrar/LICENSE-MIT b/packages/interface-registrar/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-registrar/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-registrar/README.md b/packages/interface-registrar/README.md new file mode 100644 index 0000000000..f1e1a6e598 --- /dev/null +++ b/packages/interface-registrar/README.md @@ -0,0 +1,36 @@ +# @libp2p/interface-registrar + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Registrar interface for libp2p + +## Table of contents + +- [Install](#install) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-registrar +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-registrar/package.json b/packages/interface-registrar/package.json new file mode 100644 index 0000000000..fc815feead --- /dev/null +++ b/packages/interface-registrar/package.json @@ -0,0 +1,140 @@ +{ + "name": "@libp2p/interface-registrar", + "version": "2.0.12", + "description": "Registrar interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-registrar#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-peer-id": "^2.0.0" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-registrar/src/index.ts b/packages/interface-registrar/src/index.ts new file mode 100644 index 0000000000..bac9a91c1b --- /dev/null +++ b/packages/interface-registrar/src/index.ts @@ -0,0 +1,118 @@ +import type { Connection, Stream } from '@libp2p/interface-connection' +import type { PeerId } from '@libp2p/interface-peer-id' + +export interface IncomingStreamData { + stream: Stream + connection: Connection +} + +export interface StreamHandler { + (data: IncomingStreamData): void +} + +export interface StreamHandlerOptions { + /** + * How many incoming streams can be open for this protocol at the same time on each connection (default: 32) + */ + maxInboundStreams?: number + + /** + * How many outgoing streams can be open for this protocol at the same time on each connection (default: 64) + */ + maxOutboundStreams?: number +} + +export interface StreamHandlerRecord { + handler: StreamHandler + options: StreamHandlerOptions +} + +export interface Registrar { + /** + * Return the list of protocols with registered handlers + */ + getProtocols: () => string[] + + /** + * Add a protocol handler + */ + handle: (protocol: string, handler: StreamHandler, options?: StreamHandlerOptions) => Promise + + /** + * Remove a protocol handler + */ + unhandle: (protocol: string) => Promise + + /** + * Return the handler for the passed protocol + */ + getHandler: (protocol: string) => StreamHandlerRecord + + /** + * Register a topology handler for a protocol - the topology will be + * invoked when peers are discovered on the network that support the + * passed protocol. + * + * An id will be returned that can later be used to unregister the + * topology. + */ + register: (protocol: string, topology: Topology) => Promise + + /** + * Remove the topology handler with the passed id. + */ + unregister: (id: string) => void + + /** + * Return all topology handlers that wish to be informed about peers + * that support the passed protocol. + */ + getTopologies: (protocol: string) => Topology[] +} + +export interface onConnectHandler { + (peerId: PeerId, conn: Connection): void +} + +export interface onDisconnectHandler { + (peerId: PeerId, conn?: Connection): void +} + +export interface TopologyInit { + /** + * minimum needed connections + */ + min?: number + + /** + * maximum needed connections + */ + max?: number + + /** + * Invoked when a new peer is connects that supports the configured + * protocol + */ + onConnect?: onConnectHandler + + /** + * Invoked when a peer that supports the configured protocol disconnects + */ + onDisconnect?: onDisconnectHandler +} + +export interface Topology { + min: number + max: number + peers: Set + + onConnect: (peerId: PeerId, conn: Connection) => void + onDisconnect: (peerId: PeerId) => void + setRegistrar: (registrar: Registrar) => Promise +} + +export const topologySymbol = Symbol.for('@libp2p/topology') + +export function isTopology (other: any): other is Topology { + return other != null && Boolean(other[topologySymbol]) +} diff --git a/packages/interface-registrar/tsconfig.json b/packages/interface-registrar/tsconfig.json new file mode 100644 index 0000000000..92a8421e08 --- /dev/null +++ b/packages/interface-registrar/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interface-peer-id" + } + ] +} diff --git a/packages/interface-stream-muxer-compliance-tests/CHANGELOG.md b/packages/interface-stream-muxer-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..926e438243 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/CHANGELOG.md @@ -0,0 +1,239 @@ +## [@libp2p/interface-stream-muxer-compliance-tests-v7.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v7.0.2...@libp2p/interface-stream-muxer-compliance-tests-v7.0.3) (2023-05-17) + + +### Bug Fixes + +* handle thrown errors ([#405](https://github.com/libp2p/js-libp2p-interfaces/issues/405)) ([57dfaec](https://github.com/libp2p/js-libp2p-interfaces/commit/57dfaec4c98f13a09fcfa2541c21b163a30c11d2)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v7.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v7.0.1...@libp2p/interface-stream-muxer-compliance-tests-v7.0.2) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v7.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v7.0.0...@libp2p/interface-stream-muxer-compliance-tests-v7.0.1) (2023-04-18) + + +### Dependencies + +* update abortable iterator to 5.x.x ([#379](https://github.com/libp2p/js-libp2p-interfaces/issues/379)) ([d405e5b](https://github.com/libp2p/js-libp2p-interfaces/commit/d405e5b5db624d97f47588ef55c379debccfd160)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v7.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.12...@libp2p/interface-stream-muxer-compliance-tests-v7.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) +* update sibling dependencies ([e95dcc2](https://github.com/libp2p/js-libp2p-interfaces/commit/e95dcc28f0a8b42457a44155eb0dfb3d813b03c8)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.12](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.11...@libp2p/interface-stream-muxer-compliance-tests-v6.0.12) (2023-04-14) + + +### Dependencies + +* bump it-drain from 2.0.1 to 3.0.1 ([#358](https://github.com/libp2p/js-libp2p-interfaces/issues/358)) ([ec050fa](https://github.com/libp2p/js-libp2p-interfaces/commit/ec050fa215a2ee845366c95d763ff009b247e986)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.11](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.10...@libp2p/interface-stream-muxer-compliance-tests-v6.0.11) (2023-04-13) + + +### Dependencies + +* bump it-all from 2.0.1 to 3.0.1 ([#360](https://github.com/libp2p/js-libp2p-interfaces/issues/360)) ([1b439eb](https://github.com/libp2p/js-libp2p-interfaces/commit/1b439eb7503ed7e31e77f17ce0a685ea78d94442)) +* bump it-map from 2.0.1 to 3.0.2 ([#361](https://github.com/libp2p/js-libp2p-interfaces/issues/361)) ([c016269](https://github.com/libp2p/js-libp2p-interfaces/commit/c01626912eae85969bf2b1027b68a5242a4ae4d4)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.10](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.9...@libp2p/interface-stream-muxer-compliance-tests-v6.0.10) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.8...@libp2p/interface-stream-muxer-compliance-tests-v6.0.9) (2023-04-04) + + +### Dependencies + +* bump it-pipe from 2.0.5 to 3.0.1 ([#363](https://github.com/libp2p/js-libp2p-interfaces/issues/363)) ([625817b](https://github.com/libp2p/js-libp2p-interfaces/commit/625817b0bbbee276983c40a0604c8810a25abe8f)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.7...@libp2p/interface-stream-muxer-compliance-tests-v6.0.8) (2023-03-07) + + +### Bug Fixes + +* dispatch connection event from mock upgrader ([#345](https://github.com/libp2p/js-libp2p-interfaces/issues/345)) ([b691b1f](https://github.com/libp2p/js-libp2p-interfaces/commit/b691b1fa28e23b549c32e89d6b7c98d6a50c7b8f)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.6...@libp2p/interface-stream-muxer-compliance-tests-v6.0.7) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.5...@libp2p/interface-stream-muxer-compliance-tests-v6.0.6) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.4...@libp2p/interface-stream-muxer-compliance-tests-v6.0.5) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.3...@libp2p/interface-stream-muxer-compliance-tests-v6.0.4) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.2...@libp2p/interface-stream-muxer-compliance-tests-v6.0.3) (2022-10-18) + + +### Dependencies + +* bump lerna from 5.6.2 to 6.0.1 ([#307](https://github.com/libp2p/js-libp2p-interfaces/issues/307)) ([d203019](https://github.com/libp2p/js-libp2p-interfaces/commit/d2030195b9689c504c148a722027d93af4fdc26d)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.1...@libp2p/interface-stream-muxer-compliance-tests-v6.0.2) (2022-10-17) + + +### Dependencies + +* bump it-drain from 1.0.5 to 2.0.0 ([#305](https://github.com/libp2p/js-libp2p-interfaces/issues/305)) ([67e418c](https://github.com/libp2p/js-libp2p-interfaces/commit/67e418c2abeccfc06e715c1373485f012df06fdb)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v6.0.0...@libp2p/interface-stream-muxer-compliance-tests-v6.0.1) (2022-10-17) + + +### Dependencies + +* bump it-all from 1.0.6 to 2.0.0 ([#306](https://github.com/libp2p/js-libp2p-interfaces/issues/306)) ([7c7b388](https://github.com/libp2p/js-libp2p-interfaces/commit/7c7b3882e33a064b8e5588d6befd823360347464)) +* bump it-map from 1.0.6 to 2.0.0 ([#304](https://github.com/libp2p/js-libp2p-interfaces/issues/304)) ([8a1f7f4](https://github.com/libp2p/js-libp2p-interfaces/commit/8a1f7f4241d3acf250ee81a2265a00f58e80e6ed)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v6.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v5.0.0...@libp2p/interface-stream-muxer-compliance-tests-v6.0.0) (2022-10-12) + + +### ⚠ BREAKING CHANGES + +* modules no longer implement `Initializable` instead switching to constructor injection + +### Bug Fixes + +* remove @libp2p/components ([#301](https://github.com/libp2p/js-libp2p-interfaces/issues/301)) ([1d37dc6](https://github.com/libp2p/js-libp2p-interfaces/commit/1d37dc6d3197838a71895d5769ad8bba6eb38fd3)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v5.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v4.0.0...@libp2p/interface-stream-muxer-compliance-tests-v5.0.0) (2022-10-06) + + +### ⚠ BREAKING CHANGES + +* the return type of StreamMuxer.newStream can now return a promise + +Co-authored-by: Marco Munizaga + +### Features + +* add upgrader options ([#290](https://github.com/libp2p/js-libp2p-interfaces/issues/290)) ([c502b66](https://github.com/libp2p/js-libp2p-interfaces/commit/c502b66d87020eb8e2768c49be17392c55503f69)) + + +### Dependencies + +* update sibling dependencies ([66b4993](https://github.com/libp2p/js-libp2p-interfaces/commit/66b49938a09eeb12bf8ec8d78938d5cffd6ec134)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v3.0.1...@libp2p/interface-stream-muxer-compliance-tests-v4.0.0) (2022-08-07) + + +### ⚠ BREAKING CHANGES + +* change stream muxer interface (#279) + +### Features + +* change stream muxer interface ([#279](https://github.com/libp2p/js-libp2p-interfaces/issues/279)) ([1ebe269](https://github.com/libp2p/js-libp2p-interfaces/commit/1ebe26988b6a286f36a4fc5177f502cfb60368a1)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v3.0.0...@libp2p/interface-stream-muxer-compliance-tests-v3.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v2.1.0...@libp2p/interface-stream-muxer-compliance-tests-v3.0.0) (2022-06-24) + + +### ⚠ BREAKING CHANGES + +* StreamMuxer now has a `close` method + +### Features + +* add stream muxer close ([#254](https://github.com/libp2p/js-libp2p-interfaces/issues/254)) ([d1f511e](https://github.com/libp2p/js-libp2p-interfaces/commit/d1f511e4b5857769c4eddf902288dc69fcb667b4)) + + +### Trivial Changes + +* update sibling dependencies [skip ci] ([c522241](https://github.com/libp2p/js-libp2p-interfaces/commit/c522241b08cfef3995efb5415104f46521dcd3b7)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v2.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v2.0.0...@libp2p/interface-stream-muxer-compliance-tests-v2.1.0) (2022-06-21) + + +### Features + +* add direction to StreamMuxerInit ([#253](https://github.com/libp2p/js-libp2p-interfaces/issues/253)) ([6d34d75](https://github.com/libp2p/js-libp2p-interfaces/commit/6d34d755ff4e798d52945f1f099052bdd6a83f2b)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v1.0.2...@libp2p/interface-stream-muxer-compliance-tests-v2.0.0) (2022-06-16) + + +### ⚠ BREAKING CHANGES + +* The Connection and Stream APIs have been updated + +### Features + +* store stream data on the stream, track the stream direction ([#245](https://github.com/libp2p/js-libp2p-interfaces/issues/245)) ([6d74d2f](https://github.com/libp2p/js-libp2p-interfaces/commit/6d74d2f9f344fb4d6741ba0d35263ebe351a4c65)) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v1.0.1...@libp2p/interface-stream-muxer-compliance-tests-v1.0.2) (2022-06-15) + + +### Bug Fixes + +* increase timeout for firefox ([#239](https://github.com/libp2p/js-libp2p-interfaces/issues/239)) ([e7a62b4](https://github.com/libp2p/js-libp2p-interfaces/commit/e7a62b4457ff96788ef4c445ed1549ce5d832b4e)) + +## [@libp2p/interface-stream-muxer-compliance-tests-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-compliance-tests-v1.0.0...@libp2p/interface-stream-muxer-compliance-tests-v1.0.1) (2022-06-14) + + +### Bug Fixes + +* remove components from muxer factory function ([#238](https://github.com/libp2p/js-libp2p-interfaces/issues/238)) ([e4dab30](https://github.com/libp2p/js-libp2p-interfaces/commit/e4dab306d9bf406b9bb3cb92644e28cf81f7bda6)) + + +### Trivial Changes + +* update components module ([#235](https://github.com/libp2p/js-libp2p-interfaces/issues/235)) ([5844207](https://github.com/libp2p/js-libp2p-interfaces/commit/58442070af59aa852c83ec3aecdbd1d2c646b018)) diff --git a/packages/interface-stream-muxer-compliance-tests/LICENSE b/packages/interface-stream-muxer-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-stream-muxer-compliance-tests/LICENSE-APACHE b/packages/interface-stream-muxer-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-stream-muxer-compliance-tests/LICENSE-MIT b/packages/interface-stream-muxer-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-stream-muxer-compliance-tests/README.md b/packages/interface-stream-muxer-compliance-tests/README.md new file mode 100644 index 0000000000..0d11fa9cc9 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/README.md @@ -0,0 +1,55 @@ +# @libp2p/interface-stream-muxer-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for implementations of the libp2p Stream Muxer interface + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-stream-muxer-compliance-tests +``` + +## Usage + +```js +import tests from '@libp2p/interface-stream-muxer-compliance-tests' + +describe('your stream muxer implementation', () => { + tests({ + // Options should be passed to your implementation + async setup (options) { + return new YourImplementation() + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-stream-muxer-compliance-tests/package.json b/packages/interface-stream-muxer-compliance-tests/package.json new file mode 100644 index 0000000000..cfaf97a400 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/package.json @@ -0,0 +1,151 @@ +{ + "name": "@libp2p/interface-stream-muxer-compliance-tests", + "version": "7.0.3", + "description": "Compliance tests for implementations of the libp2p Stream Muxer interface", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-stream-muxer-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-stream-muxer": "^4.0.0", + "abortable-iterator": "^5.0.1", + "aegir": "^39.0.5", + "delay": "^6.0.0", + "it-all": "^3.0.1", + "it-drain": "^3.0.1", + "it-map": "^3.0.2", + "it-pair": "^2.0.2", + "it-pipe": "^3.0.1", + "it-stream-types": "^2.0.1", + "p-defer": "^4.0.0", + "p-limit": "^4.0.0", + "uint8arraylist": "^2.4.3", + "uint8arrays": "^4.0.2" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-stream-muxer-compliance-tests/src/base-test.ts b/packages/interface-stream-muxer-compliance-tests/src/base-test.ts new file mode 100644 index 0000000000..5cda0d5451 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/src/base-test.ts @@ -0,0 +1,196 @@ +import { isValidTick } from '@libp2p/interface-compliance-tests/is-valid-tick' +import { expect } from 'aegir/chai' +import all from 'it-all' +import drain from 'it-drain' +import map from 'it-map' +import { duplexPair } from 'it-pair/duplex' +import { pipe } from 'it-pipe' +import defer from 'p-defer' +import { Uint8ArrayList } from 'uint8arraylist' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { toString as uint8ArrayToString } from 'uint8arrays/to-string' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Stream } from '@libp2p/interface-connection' +import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer' +import type { Source, Duplex } from 'it-stream-types' +import type { DeferredPromise } from 'p-defer' + +async function drainAndClose (stream: Duplex): Promise { + await pipe([], stream, drain) +} + +export default (common: TestSetup): void => { + describe('base', () => { + it('Open a stream from the dialer', async () => { + const p = duplexPair() + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + const onStreamPromise: DeferredPromise = defer() + const onStreamEndPromise: DeferredPromise = defer() + + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + onStreamPromise.resolve(stream) + }, + onStreamEnd: (stream) => { + onStreamEndPromise.resolve(stream) + } + }) + + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const conn = await dialer.newStream() + expect(dialer.streams).to.include(conn) + expect(isValidTick(conn.stat.timeline.open)).to.equal(true) + + void drainAndClose(conn) + + const stream = await onStreamPromise.promise + expect(isValidTick(stream.stat.timeline.open)).to.equal(true) + // Make sure the stream is being tracked + expect(listener.streams).to.include(stream) + + void drainAndClose(stream) + + // Make sure stream is closed properly + const endedStream = await onStreamEndPromise.promise + expect(listener.streams).to.not.include(endedStream) + + if (endedStream.stat.timeline.close == null) { + throw new Error('timeline had no close time') + } + + // Make sure the stream is removed from tracking + expect(isValidTick(endedStream.stat.timeline.close)).to.equal(true) + + await drainAndClose(dialer) + await drainAndClose(listener) + + // ensure we have no streams left + expect(dialer.streams).to.have.length(0) + expect(listener.streams).to.have.length(0) + }) + + it('Open a stream from the listener', async () => { + const p = duplexPair() + const onStreamPromise: DeferredPromise = defer() + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ + direction: 'outbound', + onIncomingStream: (stream: Stream) => { + onStreamPromise.resolve(stream) + } + }) + + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ direction: 'inbound' }) + + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const conn = await listener.newStream() + + void drainAndClose(conn) + + const stream = await onStreamPromise.promise + expect(isValidTick(stream.stat.timeline.open)).to.equal(true) + expect(listener.streams).to.include(conn) + expect(isValidTick(conn.stat.timeline.open)).to.equal(true) + void drainAndClose(stream) + + await drainAndClose(dialer) + await drainAndClose(listener) + }) + + it('Open a stream on both sides', async () => { + const p = duplexPair() + const onDialerStreamPromise: DeferredPromise = defer() + const onListenerStreamPromise: DeferredPromise = defer() + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ + direction: 'outbound', + onIncomingStream: (stream) => { + onDialerStreamPromise.resolve(stream) + } + }) + + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + onListenerStreamPromise.resolve(stream) + } + }) + + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const dialerInitiatorStream = await dialer.newStream() + const listenerInitiatorStream = await listener.newStream() + + await Promise.all([ + drainAndClose(dialerInitiatorStream), + drainAndClose(listenerInitiatorStream), + onDialerStreamPromise.promise.then(async stream => { await drainAndClose(stream) }), + onListenerStreamPromise.promise.then(async stream => { await drainAndClose(stream) }) + ]) + + await Promise.all([ + drainAndClose(dialer), + drainAndClose(listener) + ]) + }) + + it('Open a stream on one side, write, open a stream on the other side', async () => { + const toString = (source: Source): AsyncGenerator => map(source, (u) => uint8ArrayToString(u.subarray())) + const p = duplexPair() + const onDialerStreamPromise: DeferredPromise = defer() + const onListenerStreamPromise: DeferredPromise = defer() + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ + direction: 'outbound', + onIncomingStream: (stream) => { + onDialerStreamPromise.resolve(stream) + } + }) + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + onListenerStreamPromise.resolve(stream) + } + }) + + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const dialerConn = await dialer.newStream() + const listenerConn = await listener.newStream() + + void pipe([new Uint8ArrayList(uint8ArrayFromString('hey'))], dialerConn) + void pipe([new Uint8ArrayList(uint8ArrayFromString('hello'))], listenerConn) + + const [ + dialerStream, + listenerStream + ] = await Promise.all([ + onDialerStreamPromise.promise, + onListenerStreamPromise.promise + ]) + + const [ + listenerChunks, + dialerChunks + ] = await Promise.all([ + pipe(listenerStream, toString, async (source) => all(source)), + pipe(dialerStream, toString, async (source) => all(source)) + ]) + + expect(listenerChunks).to.be.eql(['hey']) + expect(dialerChunks).to.be.eql(['hello']) + }) + }) +} diff --git a/packages/interface-stream-muxer-compliance-tests/src/close-test.ts b/packages/interface-stream-muxer-compliance-tests/src/close-test.ts new file mode 100644 index 0000000000..e75d047e9d --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/src/close-test.ts @@ -0,0 +1,346 @@ +/* eslint max-nested-callbacks: ["error", 8] */ +import { abortableSource } from 'abortable-iterator' +import { expect } from 'aegir/chai' +import delay from 'delay' +import all from 'it-all' +import drain from 'it-drain' +import { duplexPair } from 'it-pair/duplex' +import { pipe } from 'it-pipe' +import pDefer from 'p-defer' +import { Uint8ArrayList } from 'uint8arraylist' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer' + +function randomBuffer (): Uint8Array { + return uint8ArrayFromString(Math.random().toString()) +} + +const infiniteRandom = { + [Symbol.asyncIterator]: async function * () { + while (true) { + yield new Uint8ArrayList(randomBuffer()) + await delay(50) + } + } +} + +export default (common: TestSetup): void => { + describe('close', () => { + it('closing underlying socket closes streams', async () => { + let openedStreams = 0 + const expectedStreams = 5 + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + + // Listener is echo server :) + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + openedStreams++ + void pipe(stream, stream) + } + }) + + const p = duplexPair() + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const streams = await Promise.all(Array(expectedStreams).fill(0).map(async () => dialer.newStream())) + + void Promise.all( + streams.map(async stream => { + await pipe( + infiniteRandom, + stream, + drain + ) + }) + ) + + expect(dialer.streams).to.have.lengthOf(expectedStreams) + + // Pause, and then send some data and close the dialer + await delay(50) + await pipe([randomBuffer()], dialer, drain) + + expect(openedStreams).to.have.equal(expectedStreams) + expect(dialer.streams).to.have.lengthOf(0) + }) + + it('calling close closes streams', async () => { + let openedStreams = 0 + const expectedStreams = 5 + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + + // Listener is echo server :) + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + openedStreams++ + void pipe(stream, stream).catch(() => {}) + } + }) + + const p = duplexPair() + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const streams = await Promise.all(Array(expectedStreams).fill(0).map(async () => dialer.newStream())) + + void Promise.all( + streams.map(async stream => { + await pipe( + infiniteRandom, + stream, + drain + ) + }) + ) + + expect(dialer.streams, 'dialer - number of opened streams should match number of calls to newStream').to.have.lengthOf(expectedStreams) + + // Pause, and then close the dialer + await delay(50) + + dialer.close() + + expect(openedStreams, 'listener - number of opened streams should match number of calls to newStream').to.have.equal(expectedStreams) + expect(dialer.streams, 'all tracked streams should be deleted after the muxer has called close').to.have.lengthOf(0) + }) + + it('calling close with an error aborts streams', async () => { + let openedStreams = 0 + const expectedStreams = 5 + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + + // Listener is echo server :) + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + openedStreams++ + void pipe(stream, stream).catch(() => {}) + } + }) + + const p = duplexPair() + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const streams = await Promise.all(Array(expectedStreams).fill(0).map(async () => dialer.newStream())) + + const streamPipes = streams.map(async stream => { + await pipe( + infiniteRandom, + stream, + drain + ) + }) + + expect(dialer.streams, 'dialer - number of opened streams should match number of calls to newStream').to.have.lengthOf(expectedStreams) + + // Pause, and then close the dialer + await delay(50) + + // close _with an error_ + dialer.close(new Error()) + + const timeoutError = new Error('timeout') + for (const pipe of streamPipes) { + try { + await Promise.race([ + pipe, + new Promise((_resolve, reject) => setTimeout(() => { reject(timeoutError) }, 20)) + ]) + expect.fail('stream pipe with infinite source should never return') + } catch (e) { + if (e === timeoutError) { + expect.fail('expected stream pipe to throw an error after muxer closed with error') + } + } + } + + expect(openedStreams, 'listener - number of opened streams should match number of calls to newStream').to.have.equal(expectedStreams) + expect(dialer.streams, 'all tracked streams should be deleted after the muxer has called close').to.have.lengthOf(0) + }) + + it('calling newStream after close throws an error', async () => { + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + + dialer.close() + + try { + await dialer.newStream() + expect.fail('newStream should throw if called after close') + } catch (e) { + expect(dialer.streams, 'closed muxer should have no streams').to.have.lengthOf(0) + } + }) + + it('closing one of the muxed streams doesn\'t close others', async () => { + const p = duplexPair() + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + + // Listener is echo server :) + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + void pipe(stream, stream).catch(() => {}) + } + }) + + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const stream = await dialer.newStream() + const streams = await Promise.all(Array.from(Array(5), async () => dialer.newStream())) + let closed = false + const controllers: AbortController[] = [] + + const streamResults = streams.map(async stream => { + const controller = new AbortController() + controllers.push(controller) + + try { + const abortableRand = abortableSource(infiniteRandom, controller.signal, { abortCode: 'ERR_TEST_ABORT' }) + await pipe(abortableRand, stream, drain) + } catch (err: any) { + if (err.code !== 'ERR_TEST_ABORT') throw err + } + + if (!closed) throw new Error('stream should not have ended yet!') + }) + + // Pause, and then send some data and close the first stream + await delay(50) + await pipe([new Uint8ArrayList(randomBuffer())], stream, drain) + closed = true + + // Abort all the other streams later + await delay(50) + controllers.forEach(c => { c.abort() }) + + // These should now all resolve without error + await Promise.all(streamResults) + }) + + it('can close a stream for writing', async () => { + const deferred = pDefer() + + const p = duplexPair() + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + const data = [randomBuffer(), randomBuffer()] + + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + void Promise.resolve().then(async () => { + // Immediate close for write + stream.closeWrite() + + const results = await pipe(stream, async (source) => { + const data = [] + for await (const chunk of source) { + data.push(chunk.slice()) + } + return data + }) + expect(results).to.eql(data) + + try { + await stream.sink([new Uint8ArrayList(randomBuffer())]) + } catch (err: any) { + deferred.resolve(err) + } + + deferred.reject(new Error('should not support writing to closed writer')) + }) + } + }) + + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const stream = await dialer.newStream() + await stream.sink(data) + + const err = await deferred.promise + expect(err).to.have.property('message').that.matches(/stream closed for writing/) + }) + + it('can close a stream for reading', async () => { + const deferred = pDefer() + + const p = duplexPair() + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ direction: 'outbound' }) + const data = [randomBuffer(), randomBuffer()].map(d => new Uint8ArrayList(d)) + + const listenerFactory = await common.setup() + const listener = listenerFactory.createStreamMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + void all(stream.source).then(deferred.resolve, deferred.reject) + } + }) + + void pipe(p[0], dialer, p[0]) + void pipe(p[1], listener, p[1]) + + const stream = await dialer.newStream() + stream.closeRead() + + // Source should be done + void Promise.resolve().then(async () => { + expect(await stream.source.next()).to.have.property('done', true) + await stream.sink(data) + }) + + const results = await deferred.promise + expect(results).to.eql(data) + }) + + it('calls onStreamEnd for closed streams not previously written', async () => { + const deferred = pDefer() + + const onStreamEnd = (): void => { deferred.resolve() } + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ + direction: 'outbound', + onStreamEnd + }) + + const stream = await dialer.newStream() + + stream.close() + await deferred.promise + }) + + it('calls onStreamEnd for read and write closed streams not previously written', async () => { + const deferred = pDefer() + + const onStreamEnd = (): void => { deferred.resolve() } + const dialerFactory = await common.setup() + const dialer = dialerFactory.createStreamMuxer({ + direction: 'outbound', + onStreamEnd + }) + + const stream = await dialer.newStream() + + stream.closeWrite() + stream.closeRead() + await deferred.promise + }) + }) +} diff --git a/packages/interface-stream-muxer-compliance-tests/src/index.ts b/packages/interface-stream-muxer-compliance-tests/src/index.ts new file mode 100644 index 0000000000..016637421b --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/src/index.ts @@ -0,0 +1,15 @@ +import baseTest from './base-test.js' +import closeTest from './close-test.js' +import megaStressTest from './mega-stress-test.js' +import stressTest from './stress-test.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer' + +export default (common: TestSetup): void => { + describe('interface-stream-muxer', () => { + baseTest(common) + closeTest(common) + stressTest(common) + megaStressTest(common) + }) +} diff --git a/packages/interface-stream-muxer-compliance-tests/src/mega-stress-test.ts b/packages/interface-stream-muxer-compliance-tests/src/mega-stress-test.ts new file mode 100644 index 0000000000..1d86075b53 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/src/mega-stress-test.ts @@ -0,0 +1,14 @@ +import spawn from './spawner.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { StreamMuxer, StreamMuxerFactory, StreamMuxerInit } from '@libp2p/interface-stream-muxer' + +export default (common: TestSetup): void => { + const createMuxer = async (init?: StreamMuxerInit): Promise => { + const factory = await common.setup() + return factory.createStreamMuxer(init) + } + + describe.skip('mega stress test', function () { + it('10,000 streams with 10,000 msg', async () => { await spawn(createMuxer, 10000, 10000, 5000) }) + }) +} diff --git a/packages/interface-stream-muxer-compliance-tests/src/spawner.ts b/packages/interface-stream-muxer-compliance-tests/src/spawner.ts new file mode 100644 index 0000000000..da16361867 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/src/spawner.ts @@ -0,0 +1,54 @@ +import { expect } from 'aegir/chai' +import all from 'it-all' +import drain from 'it-drain' +import { duplexPair } from 'it-pair/duplex' +import { pipe } from 'it-pipe' +import pLimit from 'p-limit' +import { Uint8ArrayList } from 'uint8arraylist' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import type { StreamMuxer, StreamMuxerInit } from '@libp2p/interface-stream-muxer' + +export default async (createMuxer: (init?: StreamMuxerInit) => Promise, nStreams: number, nMsg: number, limit?: number): Promise => { + const [dialerSocket, listenerSocket] = duplexPair() + + const msg = new Uint8ArrayList(uint8ArrayFromString('simple msg')) + + const listener = await createMuxer({ + direction: 'inbound', + onIncomingStream: (stream) => { + void pipe( + stream, + drain + ).then(() => { + stream.close() + }) + } + }) + const dialer = await createMuxer({ direction: 'outbound' }) + + void pipe(listenerSocket, listener, listenerSocket) + void pipe(dialerSocket, dialer, dialerSocket) + + const spawnStream = async (): Promise => { + const stream = await dialer.newStream() + expect(stream).to.exist // eslint-disable-line + + const res = await pipe( + (async function * () { + for (let i = 0; i < nMsg; i++) { + yield msg + } + }()), + stream, + async (source) => all(source) + ) + + expect(res).to.be.eql([]) + } + + const limiter = pLimit(limit ?? Infinity) + + await Promise.all( + Array.from(Array(nStreams), async () => { await limiter(async () => { await spawnStream() }) }) + ) +} diff --git a/packages/interface-stream-muxer-compliance-tests/src/stress-test.ts b/packages/interface-stream-muxer-compliance-tests/src/stress-test.ts new file mode 100644 index 0000000000..c3b3ca4aa8 --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/src/stress-test.ts @@ -0,0 +1,27 @@ +import spawn from './spawner.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { StreamMuxerFactory, StreamMuxerInit, StreamMuxer } from '@libp2p/interface-stream-muxer' + +export default (common: TestSetup): void => { + const createMuxer = async (init?: StreamMuxerInit): Promise => { + const factory = await common.setup() + return factory.createStreamMuxer(init) + } + + describe('stress test', function () { + this.timeout(800000) + + it('1 stream with 1 msg', async () => { await spawn(createMuxer, 1, 1) }) + it('1 stream with 10 msg', async () => { await spawn(createMuxer, 1, 10) }) + it('1 stream with 100 msg', async () => { await spawn(createMuxer, 1, 100) }) + it('10 streams with 1 msg', async () => { await spawn(createMuxer, 10, 1) }) + it('10 streams with 10 msg', async () => { await spawn(createMuxer, 10, 10) }) + it('10 streams with 100 msg', async () => { await spawn(createMuxer, 10, 100) }) + it('100 streams with 1 msg', async () => { await spawn(createMuxer, 100, 1) }) + it('100 streams with 10 msg', async () => { await spawn(createMuxer, 100, 10) }) + it('100 streams with 100 msg', async () => { await spawn(createMuxer, 100, 100) }) + it('1000 streams with 1 msg', async () => { await spawn(createMuxer, 1000, 1) }) + it('1000 streams with 10 msg', async () => { await spawn(createMuxer, 1000, 10) }) + it('1000 streams with 100 msg', async () => { await spawn(createMuxer, 1000, 100) }) + }) +} diff --git a/packages/interface-stream-muxer-compliance-tests/tsconfig.json b/packages/interface-stream-muxer-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..467d95314b --- /dev/null +++ b/packages/interface-stream-muxer-compliance-tests/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-connection" + }, + { + "path": "../interface-stream-muxer" + } + ] +} diff --git a/packages/interface-stream-muxer/CHANGELOG.md b/packages/interface-stream-muxer/CHANGELOG.md new file mode 100644 index 0000000000..d6f777d84a --- /dev/null +++ b/packages/interface-stream-muxer/CHANGELOG.md @@ -0,0 +1,155 @@ +## [@libp2p/interface-stream-muxer-v4.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v4.1.1...@libp2p/interface-stream-muxer-v4.1.2) (2023-05-17) + + +### Bug Fixes + +* allow stream methods to be async ([#404](https://github.com/libp2p/js-libp2p-interfaces/issues/404)) ([cfcd6d7](https://github.com/libp2p/js-libp2p-interfaces/commit/cfcd6d751990990746ee7ae7c199b938667df4d8)) + +## [@libp2p/interface-stream-muxer-v4.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v4.1.0...@libp2p/interface-stream-muxer-v4.1.1) (2023-05-17) + + +### Bug Fixes + +* update interface stream muxer config ([#403](https://github.com/libp2p/js-libp2p-interfaces/issues/403)) ([12633e2](https://github.com/libp2p/js-libp2p-interfaces/commit/12633e28eae8e9e26429c29e6d0ecb8df8933a25)) + +## [@libp2p/interface-stream-muxer-v4.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v4.0.1...@libp2p/interface-stream-muxer-v4.1.0) (2023-05-16) + + +### Features + +* add abstract stream class ([#402](https://github.com/libp2p/js-libp2p-interfaces/issues/402)) ([920aa9e](https://github.com/libp2p/js-libp2p-interfaces/commit/920aa9ec2e44ce0bafbfa1f61864079313837020)) + +## [@libp2p/interface-stream-muxer-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v4.0.0...@libp2p/interface-stream-muxer-v4.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-stream-muxer-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v3.0.6...@libp2p/interface-stream-muxer-v4.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-stream-muxer-v3.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v3.0.5...@libp2p/interface-stream-muxer-v3.0.6) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-stream-muxer-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v3.0.4...@libp2p/interface-stream-muxer-v3.0.5) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-stream-muxer-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v3.0.3...@libp2p/interface-stream-muxer-v3.0.4) (2022-12-19) + + +### Documentation + +* add interface docs ([#324](https://github.com/libp2p/js-libp2p-interfaces/issues/324)) ([2789445](https://github.com/libp2p/js-libp2p-interfaces/commit/278944594c24e1a3c4b3624a35680d69166546d7)) + +## [@libp2p/interface-stream-muxer-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v3.0.2...@libp2p/interface-stream-muxer-v3.0.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-stream-muxer-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v3.0.1...@libp2p/interface-stream-muxer-v3.0.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-stream-muxer-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v3.0.0...@libp2p/interface-stream-muxer-v3.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-stream-muxer-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v2.0.2...@libp2p/interface-stream-muxer-v3.0.0) (2022-10-06) + + +### ⚠ BREAKING CHANGES + +* the return type of StreamMuxer.newStream can now return a promise + +Co-authored-by: Marco Munizaga + +### Features + +* add upgrader options ([#290](https://github.com/libp2p/js-libp2p-interfaces/issues/290)) ([c502b66](https://github.com/libp2p/js-libp2p-interfaces/commit/c502b66d87020eb8e2768c49be17392c55503f69)) + +## [@libp2p/interface-stream-muxer-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v2.0.1...@libp2p/interface-stream-muxer-v2.0.2) (2022-08-07) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-stream-muxer-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v2.0.0...@libp2p/interface-stream-muxer-v2.0.1) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-stream-muxer-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v1.1.0...@libp2p/interface-stream-muxer-v2.0.0) (2022-06-22) + + +### ⚠ BREAKING CHANGES + +* StreamMuxer now has a `close` method + +### Features + +* add stream muxer close ([#254](https://github.com/libp2p/js-libp2p-interfaces/issues/254)) ([d1f511e](https://github.com/libp2p/js-libp2p-interfaces/commit/d1f511e4b5857769c4eddf902288dc69fcb667b4)) + +## [@libp2p/interface-stream-muxer-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v1.0.2...@libp2p/interface-stream-muxer-v1.1.0) (2022-06-21) + + +### Features + +* add direction to StreamMuxerInit ([#253](https://github.com/libp2p/js-libp2p-interfaces/issues/253)) ([6d34d75](https://github.com/libp2p/js-libp2p-interfaces/commit/6d34d755ff4e798d52945f1f099052bdd6a83f2b)) + +## [@libp2p/interface-stream-muxer-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v1.0.1...@libp2p/interface-stream-muxer-v1.0.2) (2022-06-16) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) + +## [@libp2p/interface-stream-muxer-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-stream-muxer-v1.0.0...@libp2p/interface-stream-muxer-v1.0.1) (2022-06-14) + + +### Bug Fixes + +* remove components from muxer factory function ([#238](https://github.com/libp2p/js-libp2p-interfaces/issues/238)) ([e4dab30](https://github.com/libp2p/js-libp2p-interfaces/commit/e4dab306d9bf406b9bb3cb92644e28cf81f7bda6)) + + +### Trivial Changes + +* update components module ([#235](https://github.com/libp2p/js-libp2p-interfaces/issues/235)) ([5844207](https://github.com/libp2p/js-libp2p-interfaces/commit/58442070af59aa852c83ec3aecdbd1d2c646b018)) diff --git a/packages/interface-stream-muxer/LICENSE b/packages/interface-stream-muxer/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-stream-muxer/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-stream-muxer/LICENSE-APACHE b/packages/interface-stream-muxer/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-stream-muxer/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-stream-muxer/LICENSE-MIT b/packages/interface-stream-muxer/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-stream-muxer/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-stream-muxer/README.md b/packages/interface-stream-muxer/README.md new file mode 100644 index 0000000000..fa58c9f692 --- /dev/null +++ b/packages/interface-stream-muxer/README.md @@ -0,0 +1,191 @@ +# @libp2p/interface-stream-muxer + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Stream Muxer interface for libp2p + +## Table of contents + +- [Install](#install) +- [Modules that implement the interface](#modules-that-implement-the-interface) +- [Badge](#badge) +- [Usage](#usage) +- [API](#api) + - [`const muxer = new Muxer([options])`](#const-muxer--new-muxeroptions) + - [`muxer.onStream`](#muxeronstream) + - [`muxer.onStreamEnd`](#muxeronstreamend) + - [`const stream = await muxer.newStream([options])`](#const-stream--await-muxernewstreamoptions) + - [`const streams = muxer.streams`](#const-streams--muxerstreams) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-stream-muxer +``` + +The primary goal of this module is to enable developers to pick and swap their stream muxing module as they see fit for their application, without having to go through shims or compatibility issues. This module and test suite was heavily inspired by [abstract-blob-store](https://github.com/maxogden/abstract-blob-store). + +Publishing a test suite as a module lets multiple modules all ensure compatibility since they use the same test suite. + +The API is presented with both Node.js and Go primitives, however, there is no actual limitations for it to be extended for any other language, pushing forward the cross compatibility and interop through different stacks. + +## Modules that implement the interface + +- [js-libp2p-spdy](https://github.com/libp2p/js-libp2p-spdy) +- [js-libp2p-mplex](https://github.com/libp2p/js-libp2p-mplex) + +Send a PR to add a new one if you happen to find or write one. + +## Badge + +Include this badge in your readme if you make a new module that uses interface-stream-muxer API. + +![](img/badge.png) + +## Usage + +Install `interface-stream-muxer` as one of the dependencies of your project and as a test file. Then, using `mocha` (for JavaScript) or a test runner with compatible API, do: + +```js +const test = require('libp2p-interfaces-compliance-tests/stream-muxer') + +const common = { + async setup () { + return yourMuxer + }, + async teardown () { + // cleanup + } +} + +// use all of the test suits +test(common) +``` + +## API + +A valid (one that follows this abstraction) stream muxer, must implement the following API: + +### `const muxer = new Muxer([options])` + +Create a new *duplex* stream that can be piped together with a connection in order to allow multiplexed communications. + +e.g. + +```js +const Muxer = require('your-muxer-module') +import { pipe } from 'it-pipe' + +// Create a duplex muxer +const muxer = new Muxer() + +// Use the muxer in a pipeline +pipe(conn, muxer, conn) // conn is duplex connection to another peer +``` + +`options` is an optional `Object` that may have the following properties: + +- `onStream` - A function called when receiving a new stream from the remote. e.g. + ```js + // Receive a new stream on the muxed connection + const onStream = stream => { + // Read from this stream and write back to it (echo server) + pipe( + stream, + source => (async function * () { + for await (const data of source) yield data + })() + stream + ) + } + const muxer = new Muxer({ onStream }) + // ... + ``` + **Note:** The `onStream` function can be passed in place of the `options` object. i.e. + ```js + new Mplex(stream => { /* ... */ }) + ``` +- `onStreamEnd` - A function called when a stream ends. + ```js + // Get notified when a stream has ended + const onStreamEnd = stream => { + // Manage any tracking changes, etc + } + const muxer = new Muxer({ onStreamEnd, ... }) + ``` +- `signal` - An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) which can be used to abort the muxer, *including* all of it's multiplexed connections. e.g. + ```js + const controller = new AbortController() + const muxer = new Muxer({ signal: controller.signal }) + + pipe(conn, muxer, conn) + + controller.abort() + ``` +- `maxMsgSize` - The maximum size in bytes the data field of multiplexed messages may contain (default 1MB) + +### `muxer.onStream` + +Use this property as an alternative to passing `onStream` as an option to the `Muxer` constructor. + +```js +const muxer = new Muxer() +// ...later +muxer.onStream = stream => { /* ... */ } +``` + +### `muxer.onStreamEnd` + +Use this property as an alternative to passing `onStreamEnd` as an option to the `Muxer` constructor. + +```js +const muxer = new Muxer() +// ...later +muxer.onStreamEnd = stream => { /* ... */ } +``` + +### `const stream = await muxer.newStream([options])` + +Initiate a new stream with the remote. Returns a [duplex stream](https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9#duplex-it). + +e.g. + +```js +// Create a new stream on the muxed connection +const stream = await muxer.newStream() + +// Use this new stream like any other duplex stream: +pipe([1, 2, 3], stream, consume) +``` + +### `const streams = muxer.streams` + +The streams property returns an array of streams the muxer currently has open. Closed streams will not be returned. + +```js +muxer.streams.map(stream => { + // Log out the stream's id + console.log(stream.id) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-stream-muxer/img/badge.png b/packages/interface-stream-muxer/img/badge.png new file mode 100644 index 0000000000..738bcf4a2f Binary files /dev/null and b/packages/interface-stream-muxer/img/badge.png differ diff --git a/packages/interface-stream-muxer/img/badge.sketch b/packages/interface-stream-muxer/img/badge.sketch new file mode 100644 index 0000000000..990ad1c5bf Binary files /dev/null and b/packages/interface-stream-muxer/img/badge.sketch differ diff --git a/packages/interface-stream-muxer/img/badge.svg b/packages/interface-stream-muxer/img/badge.svg new file mode 100644 index 0000000000..d7215962df --- /dev/null +++ b/packages/interface-stream-muxer/img/badge.svg @@ -0,0 +1,18 @@ + + + + badge + Created with Sketch. + + + + + + Stream Muxer + + + Compatibl + e + + + \ No newline at end of file diff --git a/packages/interface-stream-muxer/package.json b/packages/interface-stream-muxer/package.json new file mode 100644 index 0000000000..e90f1e19ab --- /dev/null +++ b/packages/interface-stream-muxer/package.json @@ -0,0 +1,166 @@ +{ + "name": "@libp2p/interface-stream-muxer", + "version": "4.1.2", + "description": "Stream Muxer interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-stream-muxer#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ], + "src/*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ] + } + }, + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./stream": { + "types": "./dist/src/stream.d.ts", + "import": "./dist/src/stream.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interfaces": "^3.0.0", + "@libp2p/logger": "^2.1.1", + "abortable-iterator": "^5.0.1", + "any-signal": "^4.1.1", + "it-pushable": "^3.1.3", + "it-stream-types": "^2.0.1", + "uint8arraylist": "^2.4.3" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-stream-muxer/src/index.ts b/packages/interface-stream-muxer/src/index.ts new file mode 100644 index 0000000000..da782d5314 --- /dev/null +++ b/packages/interface-stream-muxer/src/index.ts @@ -0,0 +1,58 @@ +import type { Direction, Stream } from '@libp2p/interface-connection' +import type { AbortOptions } from '@libp2p/interfaces' +import type { Duplex, Source } from 'it-stream-types' +import type { Uint8ArrayList } from 'uint8arraylist' + +export interface StreamMuxerFactory { + /** + * The protocol used to select this muxer during connection opening + */ + protocol: string + + /** + * Creates a new stream muxer to be used with a new connection + */ + createStreamMuxer: (init?: StreamMuxerInit) => StreamMuxer +} + +/** + * A libp2p stream muxer + */ +export interface StreamMuxer extends Duplex, Source, Promise> { + /** + * The protocol used to select this muxer during connection opening + */ + protocol: string + + /** + * A list of streams that are currently open. Closed streams will not be returned. + */ + readonly streams: Stream[] + /** + * Initiate a new stream with the given name. If no name is + * provided, the id of the stream will be used. + */ + newStream: (name?: string) => Stream | Promise + + /** + * Close or abort all tracked streams and stop the muxer + */ + close: (err?: Error) => void +} + +export interface StreamMuxerInit extends AbortOptions { + /** + * A callback function invoked every time an incoming stream is opened + */ + onIncomingStream?: (stream: Stream) => void + + /** + * A callback function invoke every time a stream ends + */ + onStreamEnd?: (stream: Stream) => void + + /** + * Outbound stream muxers are opened by the local node, inbound stream muxers are opened by the remote + */ + direction?: Direction +} diff --git a/packages/interface-stream-muxer/src/stream.ts b/packages/interface-stream-muxer/src/stream.ts new file mode 100644 index 0000000000..08d08ed517 --- /dev/null +++ b/packages/interface-stream-muxer/src/stream.ts @@ -0,0 +1,361 @@ +import { CodeError } from '@libp2p/interfaces/errors' +import { logger } from '@libp2p/logger' +import { abortableSource } from 'abortable-iterator' +import { anySignal } from 'any-signal' +import { type Pushable, pushable } from 'it-pushable' +import { Uint8ArrayList } from 'uint8arraylist' +import type { Direction, Stream, StreamStat } from '@libp2p/interface-connection' +import type { Source } from 'it-stream-types' + +const log = logger('libp2p:stream') + +const ERR_STREAM_RESET = 'ERR_STREAM_RESET' +const ERR_STREAM_ABORT = 'ERR_STREAM_ABORT' +const ERR_SINK_ENDED = 'ERR_SINK_ENDED' +const ERR_DOUBLE_SINK = 'ERR_DOUBLE_SINK' + +export interface AbstractStreamInit { + /** + * A unique identifier for this stream + */ + id: string + + /** + * The stream direction + */ + direction: Direction + + /** + * The maximum allowable data size, any data larger than this will be + * chunked and sent in multiple data messages + */ + maxDataSize: number + + /** + * User specific stream metadata + */ + metadata?: Record + + /** + * Invoked when the stream ends + */ + onEnd?: (err?: Error | undefined) => void +} + +function isPromise (res?: any): res is Promise { + return res != null && typeof res.then === 'function' +} + +export abstract class AbstractStream implements Stream { + public id: string + public stat: StreamStat + public metadata: Record + public source: AsyncGenerator + + private readonly abortController: AbortController + private readonly resetController: AbortController + private readonly closeController: AbortController + private sourceEnded: boolean + private sinkEnded: boolean + private sinkSunk: boolean + private endErr: Error | undefined + private readonly streamSource: Pushable + private readonly onEnd?: (err?: Error | undefined) => void + private readonly maxDataSize: number + + constructor (init: AbstractStreamInit) { + this.abortController = new AbortController() + this.resetController = new AbortController() + this.closeController = new AbortController() + this.sourceEnded = false + this.sinkEnded = false + this.sinkSunk = false + + this.id = init.id + this.metadata = init.metadata ?? {} + this.stat = { + direction: init.direction, + timeline: { + open: Date.now() + } + } + this.maxDataSize = init.maxDataSize + this.onEnd = init.onEnd + + this.source = this.streamSource = pushable({ + onEnd: () => { + // already sent a reset message + if (this.stat.timeline.reset !== null) { + const res = this.sendCloseRead() + + if (isPromise(res)) { + res.catch(err => { + log.error('error while sending close read', err) + }) + } + } + + this.onSourceEnd() + } + }) + + // necessary because the libp2p upgrader wraps the sink function + this.sink = this.sink.bind(this) + } + + protected onSourceEnd (err?: Error): void { + if (this.sourceEnded) { + return + } + + this.stat.timeline.closeRead = Date.now() + this.sourceEnded = true + log.trace('%s stream %s source end - err: %o', this.stat.direction, this.id, err) + + if (err != null && this.endErr == null) { + this.endErr = err + } + + if (this.sinkEnded) { + this.stat.timeline.close = Date.now() + + if (this.onEnd != null) { + this.onEnd(this.endErr) + } + } + } + + protected onSinkEnd (err?: Error): void { + if (this.sinkEnded) { + return + } + + this.stat.timeline.closeWrite = Date.now() + this.sinkEnded = true + log.trace('%s stream %s sink end - err: %o', this.stat.direction, this.id, err) + + if (err != null && this.endErr == null) { + this.endErr = err + } + + if (this.sourceEnded) { + this.stat.timeline.close = Date.now() + + if (this.onEnd != null) { + this.onEnd(this.endErr) + } + } + } + + // Close for both Reading and Writing + close (): void { + log.trace('%s stream %s close', this.stat.direction, this.id) + + this.closeRead() + this.closeWrite() + } + + // Close for reading + closeRead (): void { + log.trace('%s stream %s closeRead', this.stat.direction, this.id) + + if (this.sourceEnded) { + return + } + + this.streamSource.end() + } + + // Close for writing + closeWrite (): void { + log.trace('%s stream %s closeWrite', this.stat.direction, this.id) + + if (this.sinkEnded) { + return + } + + this.closeController.abort() + + try { + // need to call this here as the sink method returns in the catch block + // when the close controller is aborted + const res = this.sendCloseWrite() + + if (isPromise(res)) { + res.catch(err => { + log.error('error while sending close write', err) + }) + } + } catch (err) { + log.trace('%s stream %s error sending close', this.stat.direction, this.id, err) + } + + this.onSinkEnd() + } + + // Close for reading and writing (local error) + abort (err: Error): void { + log.trace('%s stream %s abort', this.stat.direction, this.id, err) + // End the source with the passed error + this.streamSource.end(err) + this.abortController.abort() + this.onSinkEnd(err) + } + + // Close immediately for reading and writing (remote error) + reset (): void { + const err = new CodeError('stream reset', ERR_STREAM_RESET) + this.resetController.abort() + this.streamSource.end(err) + this.onSinkEnd(err) + } + + async sink (source: Source): Promise { + if (this.sinkSunk) { + throw new CodeError('sink already called on stream', ERR_DOUBLE_SINK) + } + + this.sinkSunk = true + + if (this.sinkEnded) { + throw new CodeError('stream closed for writing', ERR_SINK_ENDED) + } + + const signal = anySignal([ + this.abortController.signal, + this.resetController.signal, + this.closeController.signal + ]) + + try { + source = abortableSource(source, signal) + + if (this.stat.direction === 'outbound') { // If initiator, open a new stream + const res = this.sendNewStream() + + if (isPromise(res)) { + await res + } + } + + for await (let data of source) { + while (data.length > 0) { + if (data.length <= this.maxDataSize) { + const res = this.sendData(data instanceof Uint8Array ? new Uint8ArrayList(data) : data) + + if (isPromise(res)) { // eslint-disable-line max-depth + await res + } + + break + } + data = data instanceof Uint8Array ? new Uint8ArrayList(data) : data + const res = this.sendData(data.sublist(0, this.maxDataSize)) + + if (isPromise(res)) { + await res + } + + data.consume(this.maxDataSize) + } + } + } catch (err: any) { + if (err.type === 'aborted' && err.message === 'The operation was aborted') { + if (this.closeController.signal.aborted) { + return + } + + if (this.resetController.signal.aborted) { + err.message = 'stream reset' + err.code = ERR_STREAM_RESET + } + + if (this.abortController.signal.aborted) { + err.message = 'stream aborted' + err.code = ERR_STREAM_ABORT + } + } + + // Send no more data if this stream was remotely reset + if (err.code === ERR_STREAM_RESET) { + log.trace('%s stream %s reset', this.stat.direction, this.id) + } else { + log.trace('%s stream %s error', this.stat.direction, this.id, err) + try { + const res = this.sendReset() + + if (isPromise(res)) { + await res + } + + this.stat.timeline.reset = Date.now() + } catch (err) { + log.trace('%s stream %s error sending reset', this.stat.direction, this.id, err) + } + } + + this.streamSource.end(err) + this.onSinkEnd(err) + + throw err + } finally { + signal.clear() + } + + try { + const res = this.sendCloseWrite() + + if (isPromise(res)) { + await res + } + } catch (err) { + log.trace('%s stream %s error sending close', this.stat.direction, this.id, err) + } + + this.onSinkEnd() + } + + /** + * When an extending class reads data from it's implementation-specific source, + * call this method to allow the stream consumer to read the data. + */ + sourcePush (data: Uint8ArrayList): void { + this.streamSource.push(data) + } + + /** + * Returns the amount of unread data - can be used to prevent large amounts of + * data building up when the stream consumer is too slow. + */ + sourceReadableLength (): number { + return this.streamSource.readableLength + } + + /** + * Send a message to the remote muxer informing them a new stream is being + * opened + */ + abstract sendNewStream (): void | Promise + + /** + * Send a data message to the remote muxer + */ + abstract sendData (buf: Uint8ArrayList): void | Promise + + /** + * Send a reset message to the remote muxer + */ + abstract sendReset (): void | Promise + + /** + * Send a message to the remote muxer, informing them no more data messages + * will be sent by this end of the stream + */ + abstract sendCloseWrite (): void | Promise + + /** + * Send a message to the remote muxer, informing them no more data messages + * will be read by this end of the stream + */ + abstract sendCloseRead (): void | Promise +} diff --git a/packages/interface-stream-muxer/tsconfig.json b/packages/interface-stream-muxer/tsconfig.json new file mode 100644 index 0000000000..181d553f61 --- /dev/null +++ b/packages/interface-stream-muxer/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-transport-compliance-tests/CHANGELOG.md b/packages/interface-transport-compliance-tests/CHANGELOG.md new file mode 100644 index 0000000000..ae8cbd794f --- /dev/null +++ b/packages/interface-transport-compliance-tests/CHANGELOG.md @@ -0,0 +1,235 @@ +## [@libp2p/interface-transport-compliance-tests-v4.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v4.0.1...@libp2p/interface-transport-compliance-tests-v4.0.2) (2023-05-04) + + +### Dependencies + +* update sibling dependencies ([eae5fe0](https://github.com/libp2p/js-libp2p-interfaces/commit/eae5fe02ea11c2930242a8d91ee4bc22f9bebc5c)) + +## [@libp2p/interface-transport-compliance-tests-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v4.0.0...@libp2p/interface-transport-compliance-tests-v4.0.1) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-transport-compliance-tests-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.13...@libp2p/interface-transport-compliance-tests-v4.0.0) (2023-04-21) + + +### ⚠ BREAKING CHANGES + +* add libp2p events (#373) + +### Features + +* add libp2p events ([#373](https://github.com/libp2p/js-libp2p-interfaces/issues/373)) ([071c718](https://github.com/libp2p/js-libp2p-interfaces/commit/071c718808902858818ca86167b51b242b67a5a5)) + + +### Dependencies + +* update sibling dependencies ([74f82d5](https://github.com/libp2p/js-libp2p-interfaces/commit/74f82d53fc89740f4bafa22721a59ab70c3c92a8)) +* update sibling dependencies ([17ed429](https://github.com/libp2p/js-libp2p-interfaces/commit/17ed429d57e83cb38484ac52a0e0975a7d8af963)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.13](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.12...@libp2p/interface-transport-compliance-tests-v3.0.13) (2023-04-18) + + +### Dependencies + +* update sibling dependencies ([294d970](https://github.com/libp2p/js-libp2p-interfaces/commit/294d970d6e4fbbf6a3f0944394c4c8dea06d1265)) +* update sibling dependencies ([99a862b](https://github.com/libp2p/js-libp2p-interfaces/commit/99a862baed66d4e83ba006a70c33561855c9682e)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.12](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.11...@libp2p/interface-transport-compliance-tests-v3.0.12) (2023-04-14) + + +### Dependencies + +* bump it-drain from 2.0.1 to 3.0.1 ([#358](https://github.com/libp2p/js-libp2p-interfaces/issues/358)) ([ec050fa](https://github.com/libp2p/js-libp2p-interfaces/commit/ec050fa215a2ee845366c95d763ff009b247e986)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.11](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.10...@libp2p/interface-transport-compliance-tests-v3.0.11) (2023-04-13) + + +### Dependencies + +* bump it-all from 2.0.1 to 3.0.1 ([#360](https://github.com/libp2p/js-libp2p-interfaces/issues/360)) ([1b439eb](https://github.com/libp2p/js-libp2p-interfaces/commit/1b439eb7503ed7e31e77f17ce0a685ea78d94442)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.10](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.9...@libp2p/interface-transport-compliance-tests-v3.0.10) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.8...@libp2p/interface-transport-compliance-tests-v3.0.9) (2023-04-04) + + +### Dependencies + +* bump it-pipe from 2.0.5 to 3.0.1 ([#363](https://github.com/libp2p/js-libp2p-interfaces/issues/363)) ([625817b](https://github.com/libp2p/js-libp2p-interfaces/commit/625817b0bbbee276983c40a0604c8810a25abe8f)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.7...@libp2p/interface-transport-compliance-tests-v3.0.8) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.6...@libp2p/interface-transport-compliance-tests-v3.0.7) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.5...@libp2p/interface-transport-compliance-tests-v3.0.6) (2023-01-06) + + +### Dependencies + +* update sibling dependencies ([1442ad3](https://github.com/libp2p/js-libp2p-interfaces/commit/1442ad37e44f886a423e7a09e53e0b1796327fde)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.4...@libp2p/interface-transport-compliance-tests-v3.0.5) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.3...@libp2p/interface-transport-compliance-tests-v3.0.4) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + + +### Dependencies + +* bump sinon from 14.0.2 to 15.0.0 ([#316](https://github.com/libp2p/js-libp2p-interfaces/issues/316)) ([d37721c](https://github.com/libp2p/js-libp2p-interfaces/commit/d37721c9143cd3eeafb5f8249b07d9f2fbce0f54)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.2...@libp2p/interface-transport-compliance-tests-v3.0.3) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Dependencies + +* update sibling dependencies ([45af2ca](https://github.com/libp2p/js-libp2p-interfaces/commit/45af2cadd55ad58d0c5ee2d11a0b8a39f6300454)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.1...@libp2p/interface-transport-compliance-tests-v3.0.2) (2022-10-17) + + +### Dependencies + +* bump it-drain from 1.0.5 to 2.0.0 ([#305](https://github.com/libp2p/js-libp2p-interfaces/issues/305)) ([67e418c](https://github.com/libp2p/js-libp2p-interfaces/commit/67e418c2abeccfc06e715c1373485f012df06fdb)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v3.0.0...@libp2p/interface-transport-compliance-tests-v3.0.1) (2022-10-17) + + +### Dependencies + +* bump it-all from 1.0.6 to 2.0.0 ([#306](https://github.com/libp2p/js-libp2p-interfaces/issues/306)) ([7c7b388](https://github.com/libp2p/js-libp2p-interfaces/commit/7c7b3882e33a064b8e5588d6befd823360347464)) + +## [@libp2p/interface-transport-compliance-tests-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.8...@libp2p/interface-transport-compliance-tests-v3.0.0) (2022-10-12) + + +### ⚠ BREAKING CHANGES + +* modules no longer implement `Initializable` instead switching to constructor injection + +### Bug Fixes + +* remove @libp2p/components ([#301](https://github.com/libp2p/js-libp2p-interfaces/issues/301)) ([1d37dc6](https://github.com/libp2p/js-libp2p-interfaces/commit/1d37dc6d3197838a71895d5769ad8bba6eb38fd3)) + + +### Dependencies + +* update sibling dependencies ([d3226f7](https://github.com/libp2p/js-libp2p-interfaces/commit/d3226f7383de85cae2b4771c22eea22c4bb5bbeb)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.7...@libp2p/interface-transport-compliance-tests-v2.0.8) (2022-10-06) + + +### Dependencies + +* update sibling dependencies ([2f46d7f](https://github.com/libp2p/js-libp2p-interfaces/commit/2f46d7ff4189c29a63bac93b0b5b73de0a75922f)) +* update sibling dependencies ([0fae3ee](https://github.com/libp2p/js-libp2p-interfaces/commit/0fae3ee43fab43293fb290654a927b5c5c5759fc)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.6...@libp2p/interface-transport-compliance-tests-v2.0.7) (2022-10-04) + + +### Dependencies + +* update sibling dependencies ([1b11e8e](https://github.com/libp2p/js-libp2p-interfaces/commit/1b11e8e9cc2ea1d4d26233f9c11a57e185ea23ed)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.5...@libp2p/interface-transport-compliance-tests-v2.0.6) (2022-09-21) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.4...@libp2p/interface-transport-compliance-tests-v2.0.5) (2022-08-10) + + +### Bug Fixes + +* compare bytes in transport test ([#281](https://github.com/libp2p/js-libp2p-interfaces/issues/281)) ([b7d9ef6](https://github.com/libp2p/js-libp2p-interfaces/commit/b7d9ef6f5a43b569997bf9e7c908beb2b861d01d)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.3...@libp2p/interface-transport-compliance-tests-v2.0.4) (2022-08-10) + + +### Dependencies + +* update sibling dependencies ([fc4c49c](https://github.com/libp2p/js-libp2p-interfaces/commit/fc4c49c22334b9f2059b08e13ba94f3e8938482e)) +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.2...@libp2p/interface-transport-compliance-tests-v2.0.3) (2022-07-31) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update uint8arraylist and p-wait-for deps ([#274](https://github.com/libp2p/js-libp2p-interfaces/issues/274)) ([c55f12e](https://github.com/libp2p/js-libp2p-interfaces/commit/c55f12e47be0a10e41709b0d6a60dd8bc1209ee5)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.1...@libp2p/interface-transport-compliance-tests-v2.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v2.0.0...@libp2p/interface-transport-compliance-tests-v2.0.1) (2022-06-24) + + +### Trivial Changes + +* update sibling dependencies [skip ci] ([c5c41c5](https://github.com/libp2p/js-libp2p-interfaces/commit/c5c41c521cf970addc1840d8519cdaa542a0db16)) + +## [@libp2p/interface-transport-compliance-tests-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-compliance-tests-v1.0.0...@libp2p/interface-transport-compliance-tests-v2.0.0) (2022-06-16) + + +### ⚠ BREAKING CHANGES + +* The Connection and Stream APIs have been updated + +### Features + +* store stream data on the stream, track the stream direction ([#245](https://github.com/libp2p/js-libp2p-interfaces/issues/245)) ([6d74d2f](https://github.com/libp2p/js-libp2p-interfaces/commit/6d74d2f9f344fb4d6741ba0d35263ebe351a4c65)) + + +### Trivial Changes + +* update deps ([54fbb37](https://github.com/libp2p/js-libp2p-interfaces/commit/54fbb37c8644a3fd6833c12550a57bf1a9292902)) +* update deps ([219e60e](https://github.com/libp2p/js-libp2p-interfaces/commit/219e60ec6f886b95803457fe48dfcdb4ed57e34c)) +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) diff --git a/packages/interface-transport-compliance-tests/LICENSE b/packages/interface-transport-compliance-tests/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-transport-compliance-tests/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-transport-compliance-tests/LICENSE-APACHE b/packages/interface-transport-compliance-tests/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-transport-compliance-tests/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-transport-compliance-tests/LICENSE-MIT b/packages/interface-transport-compliance-tests/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-transport-compliance-tests/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-transport-compliance-tests/README.md b/packages/interface-transport-compliance-tests/README.md new file mode 100644 index 0000000000..c76d20dc94 --- /dev/null +++ b/packages/interface-transport-compliance-tests/README.md @@ -0,0 +1,55 @@ +# @libp2p/interface-transport-compliance-tests + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Compliance tests for implementations of the libp2p Transport interface + +## Table of contents + +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-transport-compliance-tests +``` + +## Usage + +```js +import tests from '@libp2p/interface-transport-compliance-tests' + +describe('your transport implementation', () => { + tests({ + // Options should be passed to your implementation + async setup (options) { + return new YourImplementation() + }, + async teardown () { + // cleanup resources created by setup() + } + }) +}) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-transport-compliance-tests/package.json b/packages/interface-transport-compliance-tests/package.json new file mode 100644 index 0000000000..30744136dd --- /dev/null +++ b/packages/interface-transport-compliance-tests/package.json @@ -0,0 +1,150 @@ +{ + "name": "@libp2p/interface-transport-compliance-tests", + "version": "4.0.2", + "description": "Compliance tests for implementations of the libp2p Transport interface", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-transport-compliance-tests#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-mocks": "^12.0.0", + "@libp2p/interface-registrar": "^2.0.0", + "@libp2p/interface-transport": "^4.0.0", + "@libp2p/interfaces": "^3.0.0", + "@multiformats/multiaddr": "^12.0.0", + "aegir": "^39.0.5", + "it-all": "^3.0.1", + "it-drain": "^3.0.1", + "it-pipe": "^3.0.1", + "p-defer": "^4.0.0", + "p-wait-for": "^5.0.0", + "sinon": "^15.0.0", + "uint8arrays": "^4.0.2" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-transport-compliance-tests/src/dial-test.ts b/packages/interface-transport-compliance-tests/src/dial-test.ts new file mode 100644 index 0000000000..855d911f78 --- /dev/null +++ b/packages/interface-transport-compliance-tests/src/dial-test.ts @@ -0,0 +1,124 @@ +import { isValidTick } from '@libp2p/interface-compliance-tests/is-valid-tick' +import { mockUpgrader, mockRegistrar } from '@libp2p/interface-mocks' +import { AbortError } from '@libp2p/interfaces/errors' +import { EventEmitter } from '@libp2p/interfaces/events' +import { expect } from 'aegir/chai' +import all from 'it-all' +import drain from 'it-drain' +import { pipe } from 'it-pipe' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import type { TransportTestFixtures, Connector } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Registrar } from '@libp2p/interface-registrar' +import type { Transport, Listener, Upgrader } from '@libp2p/interface-transport' +import type { Multiaddr } from '@multiformats/multiaddr' + +export default (common: TestSetup): void => { + describe('dial', () => { + let upgrader: Upgrader + let registrar: Registrar + let addrs: Multiaddr[] + let transport: Transport + let connector: Connector + let listener: Listener + + before(async () => { + registrar = mockRegistrar() + upgrader = mockUpgrader({ + registrar, + events: new EventEmitter() + }); + + ({ addrs, transport, connector } = await common.setup()) + }) + + after(async () => { + await common.teardown() + }) + + beforeEach(async () => { + listener = transport.createListener({ + upgrader + }) + await listener.listen(addrs[0]) + }) + + afterEach(async () => { + sinon.restore() + connector.restore() + await listener.close() + }) + + it('simple', async () => { + const protocol = '/hello/1.0.0' + void registrar.handle(protocol, (data) => { + void pipe([ + uint8ArrayFromString('hey') + ], + data.stream, + drain + ) + }) + + const upgradeSpy = sinon.spy(upgrader, 'upgradeOutbound') + const conn = await transport.dial(addrs[0], { + upgrader + }) + + const stream = await conn.newStream([protocol]) + const result = await all(stream.source) + + expect(upgradeSpy.callCount).to.equal(1) + await expect(upgradeSpy.getCall(0).returnValue).to.eventually.equal(conn) + expect(result.length).to.equal(1) + expect(result[0].subarray()).to.equalBytes(uint8ArrayFromString('hey')) + await conn.close() + }) + + it('can close connections', async () => { + const upgradeSpy = sinon.spy(upgrader, 'upgradeOutbound') + const conn = await transport.dial(addrs[0], { + upgrader + }) + + expect(upgradeSpy.callCount).to.equal(1) + await expect(upgradeSpy.getCall(0).returnValue).to.eventually.equal(conn) + await conn.close() + expect(isValidTick(conn.stat.timeline.close)).to.equal(true) + }) + + it('to non existent listener', async () => { + const upgradeSpy = sinon.spy(upgrader, 'upgradeOutbound') + + await expect(transport.dial(addrs[1], { + upgrader + })).to.eventually.be.rejected() + expect(upgradeSpy.callCount).to.equal(0) + }) + + it('abort before dialing throws AbortError', async () => { + const upgradeSpy = sinon.spy(upgrader, 'upgradeOutbound') + const controller = new AbortController() + controller.abort() + const conn = transport.dial(addrs[0], { signal: controller.signal, upgrader }) + + await expect(conn).to.eventually.be.rejected().with.property('code', AbortError.code) + expect(upgradeSpy.callCount).to.equal(0) + }) + + it('abort while dialing throws AbortError', async () => { + const upgradeSpy = sinon.spy(upgrader, 'upgradeOutbound') + // Add a delay to connect() so that we can abort while the dial is in + // progress + connector.delay(100) + + const controller = new AbortController() + const conn = transport.dial(addrs[0], { signal: controller.signal, upgrader }) + setTimeout(() => { controller.abort() }, 50) + + await expect(conn).to.eventually.be.rejected().with.property('code', AbortError.code) + expect(upgradeSpy.callCount).to.equal(0) + }) + }) +} diff --git a/packages/interface-transport-compliance-tests/src/filter-test.ts b/packages/interface-transport-compliance-tests/src/filter-test.ts new file mode 100644 index 0000000000..713f86f00d --- /dev/null +++ b/packages/interface-transport-compliance-tests/src/filter-test.ts @@ -0,0 +1,25 @@ +import { expect } from 'aegir/chai' +import type { TransportTestFixtures } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Transport } from '@libp2p/interface-transport' +import type { Multiaddr } from '@multiformats/multiaddr' + +export default (common: TestSetup): void => { + describe('filter', () => { + let addrs: Multiaddr[] + let transport: Transport + + before(async () => { + ({ addrs, transport } = await common.setup()) + }) + + after(async () => { + await common.teardown() + }) + + it('filters addresses', () => { + const filteredAddrs = transport.filter(addrs) + expect(filteredAddrs).to.eql(addrs) + }) + }) +} diff --git a/packages/interface-transport-compliance-tests/src/index.ts b/packages/interface-transport-compliance-tests/src/index.ts new file mode 100644 index 0000000000..59ff8b02c1 --- /dev/null +++ b/packages/interface-transport-compliance-tests/src/index.ts @@ -0,0 +1,25 @@ +import dial from './dial-test.js' +import filter from './filter-test.js' +import listen from './listen-test.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Transport } from '@libp2p/interface-transport' +import type { Multiaddr } from '@multiformats/multiaddr' + +export interface Connector { + delay: (ms: number) => void + restore: () => void +} + +export interface TransportTestFixtures { + addrs: Multiaddr[] + transport: Transport + connector: Connector +} + +export default (common: TestSetup): void => { + describe('interface-transport', () => { + dial(common) + listen(common) + filter(common) + }) +} diff --git a/packages/interface-transport-compliance-tests/src/listen-test.ts b/packages/interface-transport-compliance-tests/src/listen-test.ts new file mode 100644 index 0000000000..d507e2ca0d --- /dev/null +++ b/packages/interface-transport-compliance-tests/src/listen-test.ts @@ -0,0 +1,191 @@ +/* eslint max-nested-callbacks: ["error", 8] */ +import { isValidTick } from '@libp2p/interface-compliance-tests/is-valid-tick' +import { mockUpgrader, mockRegistrar } from '@libp2p/interface-mocks' +import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events' +import { expect } from 'aegir/chai' +import drain from 'it-drain' +import { pipe } from 'it-pipe' +import defer from 'p-defer' +import pWaitFor from 'p-wait-for' +import sinon from 'sinon' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import type { TransportTestFixtures } from './index.js' +import type { TestSetup } from '@libp2p/interface-compliance-tests' +import type { Connection } from '@libp2p/interface-connection' +import type { Registrar } from '@libp2p/interface-registrar' +import type { Transport, Upgrader } from '@libp2p/interface-transport' +import type { Multiaddr } from '@multiformats/multiaddr' + +export default (common: TestSetup): void => { + describe('listen', () => { + let upgrader: Upgrader + let addrs: Multiaddr[] + let transport: Transport + let registrar: Registrar + + before(async () => { + registrar = mockRegistrar() + upgrader = mockUpgrader({ + registrar, + events: new EventEmitter() + }); + + ({ transport, addrs } = await common.setup()) + }) + + after(async () => { + await common.teardown() + }) + + afterEach(() => { + sinon.restore() + }) + + it('simple', async () => { + const listener = transport.createListener({ + upgrader + }) + await listener.listen(addrs[0]) + await listener.close() + }) + + it('close listener with connections, through timeout', async () => { + const upgradeSpy = sinon.spy(upgrader, 'upgradeInbound') + const listenerConns: Connection[] = [] + + const protocol = '/test/protocol' + void registrar.handle(protocol, (data) => { + void drain(data.stream.source) + }) + + const listener = transport.createListener({ + upgrader, + handler: (conn) => { + listenerConns.push(conn) + } + }) + + // Listen + await listener.listen(addrs[0]) + + // Create two connections to the listener + const [conn1] = await Promise.all([ + transport.dial(addrs[0], { + upgrader + }), + transport.dial(addrs[0], { + upgrader + }) + ]) + + // Give the listener a chance to finish its upgrade + await pWaitFor(() => listenerConns.length === 2) + + const stream1 = await conn1.newStream([protocol]) + + // Wait for the data send and close to finish + await Promise.all([ + pipe( + [uint8ArrayFromString('Some data that is never handled')], + stream1 + ), + // Closer the listener (will take a couple of seconds to time out) + listener.close() + ]) + + stream1.close() + await conn1.close() + + expect(isValidTick(conn1.stat.timeline.close)).to.equal(true) + listenerConns.forEach(conn => { + expect(isValidTick(conn.stat.timeline.close)).to.equal(true) + }) + + // 2 dials = 2 connections upgraded + expect(upgradeSpy.callCount).to.equal(2) + }) + + it('should not handle connection if upgradeInbound throws', async () => { + sinon.stub(upgrader, 'upgradeInbound').throws() + + const listener = transport.createListener({ + upgrader + }) + + // Listen + await listener.listen(addrs[0]) + + // Create a connection to the listener + const conn = await transport.dial(addrs[0], { + upgrader + }) + + await pWaitFor(() => typeof conn.stat.timeline.close === 'number') + await listener.close() + }) + + describe('events', () => { + it('connection', async () => { + const upgradeSpy = sinon.spy(upgrader, 'upgradeInbound') + const listener = transport.createListener({ + upgrader + }) + const deferred = defer() + let conn + + listener.addEventListener('connection', (evt) => { + conn = evt.detail + deferred.resolve() + }) + + void (async () => { + await listener.listen(addrs[0]) + await transport.dial(addrs[0], { + upgrader + }) + })() + + await deferred.promise + + await expect(upgradeSpy.getCall(0).returnValue).to.eventually.equal(conn) + expect(upgradeSpy.callCount).to.equal(1) + await listener.close() + }) + + it('listening', (done) => { + const listener = transport.createListener({ + upgrader + }) + listener.addEventListener('listening', () => { + listener.close().then(done, done) + }) + void listener.listen(addrs[0]) + }) + + it('error', (done) => { + const listener = transport.createListener({ + upgrader + }) + listener.addEventListener('error', (evt) => { + expect(evt.detail).to.be.an.instanceOf(Error) + listener.close().then(done, done) + }) + listener.dispatchEvent(new CustomEvent('error', { + detail: new Error('my err') + })) + }) + + it('close', (done) => { + const listener = transport.createListener({ + upgrader + }) + listener.addEventListener('close', () => { done() }) + + void (async () => { + await listener.listen(addrs[0]) + await listener.close() + })() + }) + }) + }) +} diff --git a/packages/interface-transport-compliance-tests/tsconfig.json b/packages/interface-transport-compliance-tests/tsconfig.json new file mode 100644 index 0000000000..0ac9c08543 --- /dev/null +++ b/packages/interface-transport-compliance-tests/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-connection" + }, + { + "path": "../interface-mocks" + }, + { + "path": "../interface-registrar" + }, + { + "path": "../interface-transport" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interface-transport/CHANGELOG.md b/packages/interface-transport/CHANGELOG.md new file mode 100644 index 0000000000..2b1562a774 --- /dev/null +++ b/packages/interface-transport/CHANGELOG.md @@ -0,0 +1,150 @@ +## [@libp2p/interface-transport-v4.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v4.0.2...@libp2p/interface-transport-v4.0.3) (2023-05-15) + + +### Bug Fixes + +* expose getListeners method from the transport manager ([#400](https://github.com/libp2p/js-libp2p-interfaces/issues/400)) ([94dc4ed](https://github.com/libp2p/js-libp2p-interfaces/commit/94dc4ed0320473b160618d19dddc6e038f5050e6)) + +## [@libp2p/interface-transport-v4.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v4.0.1...@libp2p/interface-transport-v4.0.2) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interface-transport-v4.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v4.0.0...@libp2p/interface-transport-v4.0.1) (2023-04-25) + + +### Documentation + +* fix typos in docs ([#386](https://github.com/libp2p/js-libp2p-interfaces/issues/386)) ([8ec2cdc](https://github.com/libp2p/js-libp2p-interfaces/commit/8ec2cdcc5deed76e0c673a75c27bf7a2e931eea1)) + +## [@libp2p/interface-transport-v4.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v3.0.0...@libp2p/interface-transport-v4.0.0) (2023-04-21) + + +### ⚠ BREAKING CHANGES + +* add libp2p events (#373) + +### Features + +* add libp2p events ([#373](https://github.com/libp2p/js-libp2p-interfaces/issues/373)) ([071c718](https://github.com/libp2p/js-libp2p-interfaces/commit/071c718808902858818ca86167b51b242b67a5a5)) + +## [@libp2p/interface-transport-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.1.3...@libp2p/interface-transport-v3.0.0) (2023-04-18) + + +### ⚠ BREAKING CHANGES + +* bump it-stream-types from 1.0.5 to 2.0.1 (#362) + +### Dependencies + +* bump it-stream-types from 1.0.5 to 2.0.1 ([#362](https://github.com/libp2p/js-libp2p-interfaces/issues/362)) ([cdc7747](https://github.com/libp2p/js-libp2p-interfaces/commit/cdc774792beead63e0ded96bd6c23de0335a49e3)) +* update sibling dependencies ([e95dcc2](https://github.com/libp2p/js-libp2p-interfaces/commit/e95dcc28f0a8b42457a44155eb0dfb3d813b03c8)) +* update sibling dependencies ([2f52a28](https://github.com/libp2p/js-libp2p-interfaces/commit/2f52a284b59c0a88b040f86da1f5d3f044727f2c)) + +## [@libp2p/interface-transport-v2.1.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.1.2...@libp2p/interface-transport-v2.1.3) (2023-04-11) + + +### Dependencies + +* update sibling dependencies ([b034810](https://github.com/libp2p/js-libp2p-interfaces/commit/b0348102e41dc18166e70063f4708a2b3544f4b6)) + +## [@libp2p/interface-transport-v2.1.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.1.1...@libp2p/interface-transport-v2.1.2) (2023-03-17) + + +### Dependencies + +* update @multiformats/multiaddr to 12.0.0 ([#354](https://github.com/libp2p/js-libp2p-interfaces/issues/354)) ([e0f327b](https://github.com/libp2p/js-libp2p-interfaces/commit/e0f327b5d54e240feabadce21a841629d633ec5e)) + +## [@libp2p/interface-transport-v2.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.1.0...@libp2p/interface-transport-v2.1.1) (2023-01-18) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interface-transport-v2.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.0.3...@libp2p/interface-transport-v2.1.0) (2022-12-21) + + +### Features + +* add fault tolerance enum ([#327](https://github.com/libp2p/js-libp2p-interfaces/issues/327)) ([85f8d60](https://github.com/libp2p/js-libp2p-interfaces/commit/85f8d60b147e1f0af61179137fbcdab500933e70)) + +## [@libp2p/interface-transport-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.0.2...@libp2p/interface-transport-v2.0.3) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interface-transport-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.0.1...@libp2p/interface-transport-v2.0.2) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interface-transport-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v2.0.0...@libp2p/interface-transport-v2.0.1) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + +## [@libp2p/interface-transport-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v1.0.4...@libp2p/interface-transport-v2.0.0) (2022-10-06) + + +### ⚠ BREAKING CHANGES + +* the return type of StreamMuxer.newStream can now return a promise + +Co-authored-by: Marco Munizaga + +### Features + +* add upgrader options ([#290](https://github.com/libp2p/js-libp2p-interfaces/issues/290)) ([c502b66](https://github.com/libp2p/js-libp2p-interfaces/commit/c502b66d87020eb8e2768c49be17392c55503f69)) + + +### Dependencies + +* update sibling dependencies ([66b4993](https://github.com/libp2p/js-libp2p-interfaces/commit/66b49938a09eeb12bf8ec8d78938d5cffd6ec134)) +* update sibling dependencies ([5de9728](https://github.com/libp2p/js-libp2p-interfaces/commit/5de97284827de6c63182b704c1be12c5f8cf7af5)) + +## [@libp2p/interface-transport-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v1.0.3...@libp2p/interface-transport-v1.0.4) (2022-09-21) + + +### Dependencies + +* update @multiformats/multiaddr to 11.0.0 ([#288](https://github.com/libp2p/js-libp2p-interfaces/issues/288)) ([57b2ad8](https://github.com/libp2p/js-libp2p-interfaces/commit/57b2ad88edfc7807311143791bc49270b1a81eaf)) + +## [@libp2p/interface-transport-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v1.0.2...@libp2p/interface-transport-v1.0.3) (2022-08-07) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + + +### Dependencies + +* update sibling dependencies ([f859920](https://github.com/libp2p/js-libp2p-interfaces/commit/f859920423587ae797ac90ccaa3af8bdf60ae549)) + +## [@libp2p/interface-transport-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v1.0.1...@libp2p/interface-transport-v1.0.2) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interface-transport-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interface-transport-v1.0.0...@libp2p/interface-transport-v1.0.1) (2022-06-16) + + +### Trivial Changes + +* update deps ([545264f](https://github.com/libp2p/js-libp2p-interfaces/commit/545264f87a58394d2a7da77e93f3a596e889238f)) diff --git a/packages/interface-transport/LICENSE b/packages/interface-transport/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interface-transport/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interface-transport/LICENSE-APACHE b/packages/interface-transport/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interface-transport/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interface-transport/LICENSE-MIT b/packages/interface-transport/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interface-transport/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interface-transport/README.md b/packages/interface-transport/README.md new file mode 100644 index 0000000000..9d8faa0b47 --- /dev/null +++ b/packages/interface-transport/README.md @@ -0,0 +1,264 @@ +# @libp2p/interface-transport + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Transport interface for libp2p + +## Table of contents + +- [Install](#install) +- [Modules that implement the interface](#modules-that-implement-the-interface) +- [Badge](#badge) +- [How to use the battery of tests](#how-to-use-the-battery-of-tests) +- [Node.js](#nodejs) +- [API](#api) + - [Types](#types) + - [Upgrader](#upgrader) + - [MultiaddrConnection](#multiaddrconnection) + - [Creating a transport instance](#creating-a-transport-instance) + - [Dial to another peer](#dial-to-another-peer) + - [Canceling a dial](#canceling-a-dial) + - [Filtering Addresses](#filtering-addresses) + - [Create a listener](#create-a-listener) + - [Start a listener](#start-a-listener) + - [Get listener addrs](#get-listener-addrs) + - [Stop a listener](#stop-a-listener) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interface-transport +``` + +The primary goal of this module is to enable developers to pick and swap their transport module as they see fit for their libp2p installation, without having to go through shims or compatibility issues. This module and test suite were heavily inspired by abstract-blob-store, interface-stream-muxer and others. + +Publishing a test suite as a module lets multiple modules all ensure compatibility since they use the same test suite. + +The purpose of this interface is not to reinvent any wheels when it comes to dialing and listening to transports. Instead, it tries to provide a uniform API for several transports through a shimmed interface. + +## Modules that implement the interface + +- [js-libp2p-tcp](https://github.com/libp2p/js-libp2p-tcp) +- [js-libp2p-webrtc-star](https://github.com/libp2p/js-libp2p-webrtc-star) +- [js-libp2p-webrtc-direct](https://github.com/libp2p/js-libp2p-webrtc-direct) +- [js-libp2p-websocket-star](https://github.com/libp2p/js-libp2p-websocket-star) +- [js-libp2p-websockets](https://github.com/libp2p/js-libp2p-websockets) +- [js-libp2p-utp](https://github.com/libp2p/js-libp2p-utp) +- [webrtc-explorer](https://github.com/diasdavid/webrtc-explorer) + +## Badge + +Include this badge in your readme if you make a module that is compatible with the interface-transport API. You can validate this by running the tests. + +![](img/badge.png) + +## How to use the battery of tests + +## Node.js + +```js +/* eslint-env mocha */ +'use strict' + +const tests = require('libp2p-interfaces-compliance-tests/transport') +const multiaddr = require('@multiformats/multiaddr') +const YourTransport = require('../src') + +describe('compliance', () => { + tests({ + setup (init) { + let transport = new YourTransport(init) + + const addrs = [ + multiaddr('valid-multiaddr-for-your-transport'), + multiaddr('valid-multiaddr2-for-your-transport') + ] + + const network = require('my-network-lib') + const connect = network.connect + const connector = { + delay (delayMs) { + // Add a delay in the connection mechanism for the transport + // (this is used by the dial tests) + network.connect = (...args) => setTimeout(() => connect(...args), delayMs) + }, + restore () { + // Restore the connection mechanism to normal + network.connect = connect + } + } + + return { transport, addrs, connector } + }, + teardown () { + // Clean up any resources created by setup() + } + }) +}) +``` + +## API + +A valid transport (one that follows the interface defined) must implement the following API: + +**Table of contents:** + +- type: `Transport` + - `new Transport({ upgrader, ...[options] })` + - ` transport.dial(multiaddr, [options])` + - ` transport.filter(multiaddrs)` + - `transport.createListener([options], handlerFunction)` + - type: `transport.Listener` + - event: 'listening' + - event: 'close' + - event: 'connection' + - event: 'error' + - ` listener.listen(multiaddr)` + - `listener.getAddrs()` + - ` listener.close([options])` + +### Types + +#### Upgrader + +Upgraders have 2 methods: `upgradeOutbound` and `upgradeInbound`. + +- `upgradeOutbound` must be called and returned by `transport.dial`. +- `upgradeInbound` must be called and the results must be passed to the `createListener` `handlerFunction` and the `connection` event handler, any time a new connection is created. + +```js +const connection = await upgrader.upgradeOutbound(multiaddrConnection) +const connection = await upgrader.upgradeInbound(multiaddrConnection) +``` + +The `Upgrader` methods take a [MultiaddrConnection](#multiaddrconnection) and will return an `interface-connection` instance. + +#### MultiaddrConnection + +- `MultiaddrConnection` + - `sink`: A [streaming iterable sink](https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9#sink-it) + - `source`: A [streaming iterable source](https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9#source-it) + - `close`: A method for closing the connection + - `conn`: The raw connection of the transport, such as a TCP socket. + - `remoteAddr`: The remote `Multiaddr` of the connection. + - `[localAddr]`: An optional local `Multiaddr` of the connection. + - `timeline`: A hash map of connection time events + - `open`: The time in ticks the connection was opened + - `close`: The time in ticks the connection was closed + +### Creating a transport instance + +- `const transport = new Transport({ upgrader, ...[options] })` + +Creates a new Transport instance. `options` is an JavaScript object that should include the necessary parameters for the transport instance. Options **MUST** include an `Upgrader` instance, as Transports will use this to return `interface-connection` instances from `transport.dial` and the listener `handlerFunction`. + +**Note: Why is it important to instantiate a transport -** Some transports have state that can be shared between the dialing and listening parts. For example with libp2p-webrtc-star, in order to dial a peer, the peer must be part of some signaling network that is shared with the listener. + +### Dial to another peer + +- `const connection = await transport.dial(multiaddr, [options])` + +This method uses a transport to dial a Peer listening on `multiaddr`. + +`multiaddr` must be of the type [`multiaddr`](https://www.npmjs.com/multiaddr). + +`[options]` the options that may be passed to the dial. Must support the `signal` option (see below) + +Dial **MUST** call and return `upgrader.upgradeOutbound(multiaddrConnection)`. The upgrader will return an [interface-connection](../connection) instance. + +The dial may throw an `Error` instance if there was a problem connecting to the `multiaddr`. + +### Canceling a dial + +Dials may be cancelled using an `AbortController`: + +```Javascript +const { AbortError } = require('libp2p-interfaces/src/transport/errors') +const controller = new AbortController() +try { + const conn = await mytransport.dial(ma, { signal: controller.signal }) + // Do stuff with conn here ... +} catch (err: any) { + if(err.code === AbortError.code) { + // Dial was aborted, just bail out + return + } + throw err +} + +// ---- +// In some other part of the code: + controller.abort() +// ---- +``` + +### Filtering Addresses + +- `const supportedAddrs = await transport.filter(multiaddrs)` + +When using a transport its important to be able to filter out `multiaddr`s that the transport doesn't support. A transport instance provides a filter method to return only the valid addresses it supports. + +`multiaddrs` must be an array of type [`multiaddr`](https://www.npmjs.com/multiaddr). +Filter returns an array of `multiaddr`. + +### Create a listener + +- `const listener = transport.createListener([options], handlerFunction)` + +This method creates a listener on the transport. Implementations **MUST** call `upgrader.upgradeInbound(multiaddrConnection)` and pass its results to the `handlerFunction` and any emitted `connection` events. + +`options` is an optional object that contains the properties the listener must have, in order to properly listen on a given transport/socket. + +`handlerFunction` is a function called each time a new connection is received. It must follow the following signature: `function (conn) {}`, where `conn` is a connection that follows the [`interface-connection`](../connection). + +The listener object created may emit the following events: + +- `listening` - when the listener is ready for incoming connections +- `close` - when the listener is closed +- `connection` - (`conn`) each time an incoming connection is received +- `error` - (`err`) each time there is an error on the connection + +### Start a listener + +- `await listener.listen(multiaddr)` + +This method puts the listener in `listening` mode, waiting for incoming connections. + +`multiaddr` is the address that the listener should bind to. + +### Get listener addrs + +- `listener.getAddrs()` + +This method returns the addresses on which this listener is listening. Useful when listening on port 0 or any interface (0.0.0.0). + +### Stop a listener + +- `await listener.close([options])` + +This method closes the listener so that no more connections can be opened on this transport instance. + +`options` is an optional object that may contain the following properties: + +- `timeout` - A timeout value (in ms) after which all connections on this transport will be destroyed if the transport is not able to close gracefully. (e.g `{ timeout: 1000 }`) + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interface-transport/img/badge.png b/packages/interface-transport/img/badge.png new file mode 100644 index 0000000000..1c8fe6972b Binary files /dev/null and b/packages/interface-transport/img/badge.png differ diff --git a/packages/interface-transport/img/badge.sketch b/packages/interface-transport/img/badge.sketch new file mode 100644 index 0000000000..d36e0af1fe Binary files /dev/null and b/packages/interface-transport/img/badge.sketch differ diff --git a/packages/interface-transport/img/badge.svg b/packages/interface-transport/img/badge.svg new file mode 100644 index 0000000000..aa56dacd5e --- /dev/null +++ b/packages/interface-transport/img/badge.svg @@ -0,0 +1,19 @@ + + + + badge + Created with Sketch. + + + + + + Transpor + t + + + Compatibl + e + + + \ No newline at end of file diff --git a/packages/interface-transport/package.json b/packages/interface-transport/package.json new file mode 100644 index 0000000000..235a2154b6 --- /dev/null +++ b/packages/interface-transport/package.json @@ -0,0 +1,143 @@ +{ + "name": "@libp2p/interface-transport", + "version": "4.0.3", + "description": "Transport interface for libp2p", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-transport#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "dependencies": { + "@libp2p/interface-connection": "^5.0.0", + "@libp2p/interface-stream-muxer": "^4.0.0", + "@libp2p/interfaces": "^3.0.0", + "@multiformats/multiaddr": "^12.0.0", + "it-stream-types": "^2.0.1" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interface-transport/src/index.ts b/packages/interface-transport/src/index.ts new file mode 100644 index 0000000000..4b14bd2d3e --- /dev/null +++ b/packages/interface-transport/src/index.ts @@ -0,0 +1,128 @@ +import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection' +import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer' +import type { AbortOptions } from '@libp2p/interfaces' +import type { EventEmitter } from '@libp2p/interfaces/events' +import type { Multiaddr } from '@multiformats/multiaddr' +import type { Duplex } from 'it-stream-types' + +export const symbol = Symbol.for('@libp2p/transport') + +export interface ConnectionHandler { (connection: Connection): void } + +export interface MultiaddrFilter { (multiaddrs: Multiaddr[]): Multiaddr[] } + +export interface CreateListenerOptions { + handler?: ConnectionHandler + upgrader: Upgrader +} + +export interface DialOptions extends AbortOptions { + upgrader: Upgrader +} + +/** + * A libp2p transport is understood as something that offers a dial and listen interface to establish connections. + */ +export interface Transport { + /** + * Used to identify the transport + */ + [Symbol.toStringTag]: string + + /** + * Used by the isTransport function + */ + [symbol]: true + + /** + * Dial a given multiaddr. + */ + dial: (ma: Multiaddr, options: DialOptions) => Promise + + /** + * Create transport listeners. + */ + createListener: (options: CreateListenerOptions) => Listener + + /** + * Takes a list of `Multiaddr`s and returns only valid addresses for the transport + */ + filter: MultiaddrFilter +} + +export interface ListenerEvents { + 'connection': CustomEvent + 'listening': CustomEvent + 'error': CustomEvent + 'close': CustomEvent +} + +export interface Listener extends EventEmitter { + /** + * Start a listener + */ + listen: (multiaddr: Multiaddr) => Promise + /** + * Get listen addresses + */ + getAddrs: () => Multiaddr[] + /** + * Close listener + * + * @returns {Promise} + */ + close: () => Promise +} + +export interface UpgraderOptions { + skipEncryption?: boolean + skipProtection?: boolean + muxerFactory?: StreamMuxerFactory +} + +export interface Upgrader { + /** + * Upgrades an outbound connection on `transport.dial`. + */ + upgradeOutbound: (maConn: MultiaddrConnection, opts?: UpgraderOptions) => Promise + + /** + * Upgrades an inbound connection on transport listener. + */ + upgradeInbound: (maConn: MultiaddrConnection, opts?: UpgraderOptions) => Promise +} + +export interface ProtocolHandler { + (stream: Duplex, connection: Connection): void +} + +export function isTransport (other: any): other is Transport { + return other != null && Boolean(other[symbol]) +} + +export interface TransportManager { + add: (transport: Transport) => void + dial: (ma: Multiaddr, options?: any) => Promise + getAddrs: () => Multiaddr[] + getTransports: () => Transport[] + getListeners: () => Listener[] + transportForMultiaddr: (ma: Multiaddr) => Transport | undefined + listen: (addrs: Multiaddr[]) => Promise + remove: (key: string) => Promise + removeAll: () => Promise +} + +/** + * Enum Transport Manager Fault Tolerance values + */ +export enum FaultTolerance { + /** + * should be used for failing in any listen circumstance + */ + FATAL_ALL = 0, + + /** + * should be used for not failing when not listening + */ + NO_FATAL +} diff --git a/packages/interface-transport/tsconfig.json b/packages/interface-transport/tsconfig.json new file mode 100644 index 0000000000..28ed110a13 --- /dev/null +++ b/packages/interface-transport/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ], + "references": [ + { + "path": "../interface-connection" + }, + { + "path": "../interface-stream-muxer" + }, + { + "path": "../interfaces" + } + ] +} diff --git a/packages/interfaces/CHANGELOG.md b/packages/interfaces/CHANGELOG.md new file mode 100644 index 0000000000..c9960901e2 --- /dev/null +++ b/packages/interfaces/CHANGELOG.md @@ -0,0 +1,1120 @@ +## [@libp2p/interfaces-v3.3.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.3.1...@libp2p/interfaces-v3.3.2) (2023-05-04) + + +### Dependencies + +* bump aegir from 38.1.8 to 39.0.5 ([#393](https://github.com/libp2p/js-libp2p-interfaces/issues/393)) ([31f3797](https://github.com/libp2p/js-libp2p-interfaces/commit/31f3797b24f7c23f3f16e9db3a230bd5f7cd5175)) + +## [@libp2p/interfaces-v3.3.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.3.0...@libp2p/interfaces-v3.3.1) (2023-01-18) + + +### Dependencies + +* bump aegir from 37.12.1 to 38.1.0 ([#335](https://github.com/libp2p/js-libp2p-interfaces/issues/335)) ([7368a36](https://github.com/libp2p/js-libp2p-interfaces/commit/7368a363423a08e8fa247dcb76ea13e4cf030d65)) + +## [@libp2p/interfaces-v3.3.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.2.0...@libp2p/interfaces-v3.3.0) (2023-01-17) + + +### Features + +* safe dispatch event ([#319](https://github.com/libp2p/js-libp2p-interfaces/issues/319)) ([8caeee8](https://github.com/libp2p/js-libp2p-interfaces/commit/8caeee8221e78c2412d8aeb9a7db7cc43abfdf1b)), closes [#317](https://github.com/libp2p/js-libp2p-interfaces/issues/317) + + +### Trivial Changes + +* remove lerna ([#330](https://github.com/libp2p/js-libp2p-interfaces/issues/330)) ([6678592](https://github.com/libp2p/js-libp2p-interfaces/commit/6678592dd0cf601a2671852f9d2a0aff5dee2b18)) + +## [@libp2p/interfaces-v3.2.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.1.0...@libp2p/interfaces-v3.2.0) (2023-01-03) + + +### Features + +* add CodeError ([#314](https://github.com/libp2p/js-libp2p-interfaces/issues/314)) ([59aa8f7](https://github.com/libp2p/js-libp2p-interfaces/commit/59aa8f7fd2a8e80fc28e76fef320c531884e7e00)), closes [/github.com/libp2p/js-libp2p-crypto/pull/284#issuecomment-1324005434](https://github.com/libp2p//github.com/libp2p/js-libp2p-crypto/pull/284/issues/issuecomment-1324005434) + +## [@libp2p/interfaces-v3.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.0.6...@libp2p/interfaces-v3.1.0) (2022-12-19) + + +### Features + +* add libp2p interface ([#325](https://github.com/libp2p/js-libp2p-interfaces/issues/325)) ([79a474d](https://github.com/libp2p/js-libp2p-interfaces/commit/79a474d8eda95ad3ff3bcdb2a15bfcf778f51772)) + +## [@libp2p/interfaces-v3.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.0.5...@libp2p/interfaces-v3.0.6) (2022-12-16) + + +### Documentation + +* update project config ([#323](https://github.com/libp2p/js-libp2p-interfaces/issues/323)) ([0fc6a08](https://github.com/libp2p/js-libp2p-interfaces/commit/0fc6a08e9cdcefe361fe325281a3a2a03759ff59)) + +## [@libp2p/interfaces-v3.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.0.4...@libp2p/interfaces-v3.0.5) (2022-12-14) + + +### Bug Fixes + +* generate docs for all packages ([#321](https://github.com/libp2p/js-libp2p-interfaces/issues/321)) ([b6f8b32](https://github.com/libp2p/js-libp2p-interfaces/commit/b6f8b32a920c15a28fe021e6050e31aaae89d518)) + +## [@libp2p/interfaces-v3.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.0.3...@libp2p/interfaces-v3.0.4) (2022-11-05) + + +### Bug Fixes + +* update project config ([#311](https://github.com/libp2p/js-libp2p-interfaces/issues/311)) ([27dd0ce](https://github.com/libp2p/js-libp2p-interfaces/commit/27dd0ce3c249892ac69cbb24ddaf0b9f32385e37)) + + +### Trivial Changes + +* update project config ([#271](https://github.com/libp2p/js-libp2p-interfaces/issues/271)) ([59c0bf5](https://github.com/libp2p/js-libp2p-interfaces/commit/59c0bf5e0b05496fca2e4902632b61bb41fad9e9)) + +## [@libp2p/interfaces-v3.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.0.2...@libp2p/interfaces-v3.0.3) (2022-06-27) + + +### Trivial Changes + +* update deps ([#262](https://github.com/libp2p/js-libp2p-interfaces/issues/262)) ([51edf7d](https://github.com/libp2p/js-libp2p-interfaces/commit/51edf7d9b3765a6f75c915b1483ea345d0133a41)) + +## [@libp2p/interfaces-v3.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.0.1...@libp2p/interfaces-v3.0.2) (2022-06-14) + + +### Trivial Changes + +* update aegir ([#234](https://github.com/libp2p/js-libp2p-interfaces/issues/234)) ([3e03895](https://github.com/libp2p/js-libp2p-interfaces/commit/3e038959ecab6cfa3585df9ee179c0af7a61eda5)) + +## [@libp2p/interfaces-v3.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v3.0.0...@libp2p/interfaces-v3.0.1) (2022-06-14) + + +### Trivial Changes + +* update readmes ([#233](https://github.com/libp2p/js-libp2p-interfaces/issues/233)) ([ee7da38](https://github.com/libp2p/js-libp2p-interfaces/commit/ee7da38dccc08160d26c8436df8739ce7e0b340e)) + +## [@libp2p/interfaces-v3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v2.0.4...@libp2p/interfaces-v3.0.0) (2022-06-14) + + +### ⚠ BREAKING CHANGES + +* most modules have been split out of the `@libp2p/interfaces` and `@libp2p/interface-compliance-tests` packages + +### Trivial Changes + +* break modules apart ([#232](https://github.com/libp2p/js-libp2p-interfaces/issues/232)) ([385614e](https://github.com/libp2p/js-libp2p-interfaces/commit/385614e772329052ab17415c8bd421f65b01a61b)), closes [#226](https://github.com/libp2p/js-libp2p-interfaces/issues/226) + +## [@libp2p/interfaces-v2.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v2.0.3...@libp2p/interfaces-v2.0.4) (2022-06-14) + + +### Bug Fixes + +* event emitter types ([#230](https://github.com/libp2p/js-libp2p-interfaces/issues/230)) ([f16f74f](https://github.com/libp2p/js-libp2p-interfaces/commit/f16f74fc972e537698884c1910854e9630058c36)), closes [#227](https://github.com/libp2p/js-libp2p-interfaces/issues/227) + + +### Trivial Changes + +* add missing deps ([#229](https://github.com/libp2p/js-libp2p-interfaces/issues/229)) ([cc3cece](https://github.com/libp2p/js-libp2p-interfaces/commit/cc3cece290108302fb84501e2500fb18cd99f90f)) + +## [@libp2p/interfaces-v2.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v2.0.2...@libp2p/interfaces-v2.0.3) (2022-05-31) + + +### Bug Fixes + +* dead badge ([#221](https://github.com/libp2p/js-libp2p-interfaces/issues/221)) ([2b7fa07](https://github.com/libp2p/js-libp2p-interfaces/commit/2b7fa07935f800b2438b054b9678e9b16694bf45)) + +## [@libp2p/interfaces-v2.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v2.0.1...@libp2p/interfaces-v2.0.2) (2022-05-24) + + +### Bug Fixes + +* accept abort options in connection.newStream ([#219](https://github.com/libp2p/js-libp2p-interfaces/issues/219)) ([8bfcbc9](https://github.com/libp2p/js-libp2p-interfaces/commit/8bfcbc9ee883336f213cdfc83e477549ca368df5)) + +## [@libp2p/interfaces-v2.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v2.0.0...@libp2p/interfaces-v2.0.1) (2022-05-23) + + +### Bug Fixes + +* make stream return types synchronous ([#217](https://github.com/libp2p/js-libp2p-interfaces/issues/217)) ([2fe61b7](https://github.com/libp2p/js-libp2p-interfaces/commit/2fe61b7fbeda2e549edf095a927d623aa8eb476b)) + +## [@libp2p/interfaces-v2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.32...@libp2p/interfaces-v2.0.0) (2022-05-20) + + +### ⚠ BREAKING CHANGES + +* This adds closeWrite and closeRead checks in the tests, which will cause test failures for muxers that don't implement those + +### Bug Fixes + +* close streams when connection is closed ([#214](https://github.com/libp2p/js-libp2p-interfaces/issues/214)) ([88fcd58](https://github.com/libp2p/js-libp2p-interfaces/commit/88fcd586276e03dd740c7095f05e21754ac1f3b5)), closes [#90](https://github.com/libp2p/js-libp2p-interfaces/issues/90) + +## [@libp2p/interfaces-v1.3.32](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.31...@libp2p/interfaces-v1.3.32) (2022-05-06) + + +### Bug Fixes + +* add tag to peer discovery interface ([#210](https://github.com/libp2p/js-libp2p-interfaces/issues/210)) ([f99c833](https://github.com/libp2p/js-libp2p-interfaces/commit/f99c833c8436f8434f380d890ec5d267279312d7)) + +## [@libp2p/interfaces-v1.3.31](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.30...@libp2p/interfaces-v1.3.31) (2022-05-04) + + +### Bug Fixes + +* move startable and events interfaces ([#209](https://github.com/libp2p/js-libp2p-interfaces/issues/209)) ([8ce8a08](https://github.com/libp2p/js-libp2p-interfaces/commit/8ce8a08c94b0738aa32da516558977b195ddd8ed)) + +## [@libp2p/interfaces-v1.3.30](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.29...@libp2p/interfaces-v1.3.30) (2022-05-04) + + +### Bug Fixes + +* remove connection manager options ([#208](https://github.com/libp2p/js-libp2p-interfaces/issues/208)) ([b93d051](https://github.com/libp2p/js-libp2p-interfaces/commit/b93d051cb889b175f324f589546033d6723b1298)) + +## [@libp2p/interfaces-v1.3.29](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.28...@libp2p/interfaces-v1.3.29) (2022-05-03) + + +### Bug Fixes + +* only send handled protocols ([#207](https://github.com/libp2p/js-libp2p-interfaces/issues/207)) ([1f7afc2](https://github.com/libp2p/js-libp2p-interfaces/commit/1f7afc29d72fde708064ec6479011dbc0a225962)) + +## [@libp2p/interfaces-v1.3.28](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.27...@libp2p/interfaces-v1.3.28) (2022-05-01) + + +### Bug Fixes + +* add abort options to open connection ([#206](https://github.com/libp2p/js-libp2p-interfaces/issues/206)) ([b32234f](https://github.com/libp2p/js-libp2p-interfaces/commit/b32234f97b6e5cf93ea103b9650bea2119ce6025)) + +## [@libp2p/interfaces-v1.3.27](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.26...@libp2p/interfaces-v1.3.27) (2022-05-01) + + +### Bug Fixes + +* move connection manager mock to connection manager module ([#205](https://github.com/libp2p/js-libp2p-interfaces/issues/205)) ([a367375](https://github.com/libp2p/js-libp2p-interfaces/commit/a367375accc690d7b4608c9a3313f91df700efd8)) + +## [@libp2p/interfaces-v1.3.26](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.25...@libp2p/interfaces-v1.3.26) (2022-04-28) + + +### Bug Fixes + +* pubsub should not be startable ([#204](https://github.com/libp2p/js-libp2p-interfaces/issues/204)) ([59bd924](https://github.com/libp2p/js-libp2p-interfaces/commit/59bd9245a207268525bdd26a05c5306fe436fcc4)) + +## [@libp2p/interfaces-v1.3.25](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.24...@libp2p/interfaces-v1.3.25) (2022-04-28) + + +### Bug Fixes + +* pubsub and dht are always set ([#203](https://github.com/libp2p/js-libp2p-interfaces/issues/203)) ([86860c1](https://github.com/libp2p/js-libp2p-interfaces/commit/86860c1836a2464b2ad380b09542e3f3271ae287)) + +## [@libp2p/interfaces-v1.3.24](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.23...@libp2p/interfaces-v1.3.24) (2022-04-22) + + +### Bug Fixes + +* update pubsub interface in line with gossipsub ([#199](https://github.com/libp2p/js-libp2p-interfaces/issues/199)) ([3f55596](https://github.com/libp2p/js-libp2p-interfaces/commit/3f555965cddea3ef03e7217b755c82aa4107e093)) + +## [@libp2p/interfaces-v1.3.23](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.22...@libp2p/interfaces-v1.3.23) (2022-04-21) + + +### Bug Fixes + +* test PubSub interface and not PubSubBaseProtocol ([#198](https://github.com/libp2p/js-libp2p-interfaces/issues/198)) ([96c15c9](https://github.com/libp2p/js-libp2p-interfaces/commit/96c15c9780821a3cb763e48854d64377bf562692)) + +## [@libp2p/interfaces-v1.3.22](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.21...@libp2p/interfaces-v1.3.22) (2022-04-20) + + +### Bug Fixes + +* emit pubsub messages using 'message' event ([#197](https://github.com/libp2p/js-libp2p-interfaces/issues/197)) ([df9b685](https://github.com/libp2p/js-libp2p-interfaces/commit/df9b685cea30653109f2fa2cb5583a3bca7b09bb)) + +## [@libp2p/interfaces-v1.3.21](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.20...@libp2p/interfaces-v1.3.21) (2022-04-13) + + +### Bug Fixes + +* add keychain types, fix bigint types ([#193](https://github.com/libp2p/js-libp2p-interfaces/issues/193)) ([9ceadf9](https://github.com/libp2p/js-libp2p-interfaces/commit/9ceadf9d5c42a12d88d74ddd9140e34f7fa63537)) + +## [@libp2p/interfaces-v1.3.20](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.19...@libp2p/interfaces-v1.3.20) (2022-04-08) + + +### Trivial Changes + +* update aegir ([#192](https://github.com/libp2p/js-libp2p-interfaces/issues/192)) ([41c1494](https://github.com/libp2p/js-libp2p-interfaces/commit/41c14941e8b67d6601a90b4d48a2776573d55e60)) + +## [@libp2p/interfaces-v1.3.19](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.18...@libp2p/interfaces-v1.3.19) (2022-04-08) + + +### Bug Fixes + +* swap protobufjs for protons ([#191](https://github.com/libp2p/js-libp2p-interfaces/issues/191)) ([d72b30c](https://github.com/libp2p/js-libp2p-interfaces/commit/d72b30cfca4b9145e0b31db28e8fa3329a180e83)) + +## [@libp2p/interfaces-v1.3.18](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.17...@libp2p/interfaces-v1.3.18) (2022-03-24) + + +### Bug Fixes + +* rename peer data to peer info ([#187](https://github.com/libp2p/js-libp2p-interfaces/issues/187)) ([dfea342](https://github.com/libp2p/js-libp2p-interfaces/commit/dfea3429bad57abde040397e4e7a58539829e9c2)) + +## [@libp2p/interfaces-v1.3.17](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.16...@libp2p/interfaces-v1.3.17) (2022-03-21) + + +### Bug Fixes + +* expand startable interface ([#184](https://github.com/libp2p/js-libp2p-interfaces/issues/184)) ([b8e1a0c](https://github.com/libp2p/js-libp2p-interfaces/commit/b8e1a0c77316265cc08eaaf9fcab6cfa05d59ae1)) + +## [@libp2p/interfaces-v1.3.16](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.15...@libp2p/interfaces-v1.3.16) (2022-03-20) + + +### Bug Fixes + +* update pubsub types ([#183](https://github.com/libp2p/js-libp2p-interfaces/issues/183)) ([7ef4baa](https://github.com/libp2p/js-libp2p-interfaces/commit/7ef4baad0fe30f783f3eecd5199ef92af08b7f57)) + +## [@libp2p/interfaces-v1.3.15](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.14...@libp2p/interfaces-v1.3.15) (2022-03-16) + + +### Bug Fixes + +* update content routing get return type ([#182](https://github.com/libp2p/js-libp2p-interfaces/issues/182)) ([49da9d5](https://github.com/libp2p/js-libp2p-interfaces/commit/49da9d5883618a672d64542eee13972e603a5b3d)) + +## [@libp2p/interfaces-v1.3.14](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.13...@libp2p/interfaces-v1.3.14) (2022-03-15) + + +### Bug Fixes + +* simplify transport interface, update interfaces for use with libp2p ([#180](https://github.com/libp2p/js-libp2p-interfaces/issues/180)) ([ec81622](https://github.com/libp2p/js-libp2p-interfaces/commit/ec81622e5b7c6d256e0f8aed6d3695642473293b)) + +## [@libp2p/interfaces-v1.3.13](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.12...@libp2p/interfaces-v1.3.13) (2022-02-27) + + +### Bug Fixes + +* rename crypto to connection-encrypter ([#179](https://github.com/libp2p/js-libp2p-interfaces/issues/179)) ([d197f55](https://github.com/libp2p/js-libp2p-interfaces/commit/d197f554d7cdadb3b05ed2d6c69fda2c4362b1eb)) + +## [@libp2p/interfaces-v1.3.12](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.11...@libp2p/interfaces-v1.3.12) (2022-02-27) + + +### Bug Fixes + +* update package config and add connection gater interface ([#178](https://github.com/libp2p/js-libp2p-interfaces/issues/178)) ([c6079a6](https://github.com/libp2p/js-libp2p-interfaces/commit/c6079a6367f004788062df3e30ad2e26330d947b)) + +## [@libp2p/interfaces-v1.3.11](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.10...@libp2p/interfaces-v1.3.11) (2022-02-21) + + +### Bug Fixes + +* remove unused dht query option ([#176](https://github.com/libp2p/js-libp2p-interfaces/issues/176)) ([e0ce46d](https://github.com/libp2p/js-libp2p-interfaces/commit/e0ce46d371a92a7063f02e7a1729a39def80e15e)) + +## [@libp2p/interfaces-v1.3.10](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.9...@libp2p/interfaces-v1.3.10) (2022-02-21) + + +### Bug Fixes + +* update muxer to pass transport tests ([#174](https://github.com/libp2p/js-libp2p-interfaces/issues/174)) ([466ed53](https://github.com/libp2p/js-libp2p-interfaces/commit/466ed53192aa196ac2dbdb83df3c8db9cd5b1e07)) + +## [@libp2p/interfaces-v1.3.9](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.8...@libp2p/interfaces-v1.3.9) (2022-02-18) + + +### Bug Fixes + +* remove delays from pubsub tests ([#173](https://github.com/libp2p/js-libp2p-interfaces/issues/173)) ([5c8fe09](https://github.com/libp2p/js-libp2p-interfaces/commit/5c8fe09294f0cbd8add1406a61fa7dbc5b4e788b)) + +## [@libp2p/interfaces-v1.3.8](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.7...@libp2p/interfaces-v1.3.8) (2022-02-18) + + +### Bug Fixes + +* simpler pubsub ([#172](https://github.com/libp2p/js-libp2p-interfaces/issues/172)) ([98715ed](https://github.com/libp2p/js-libp2p-interfaces/commit/98715ed73183b32e4fda3d878a462389548358d9)) + +## [@libp2p/interfaces-v1.3.7](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.6...@libp2p/interfaces-v1.3.7) (2022-02-17) + + +### Bug Fixes + +* add multistream-select and update pubsub types ([#170](https://github.com/libp2p/js-libp2p-interfaces/issues/170)) ([b9ecb2b](https://github.com/libp2p/js-libp2p-interfaces/commit/b9ecb2bee8f2abc0c41bfcf7bf2025894e37ddc2)) + +## [@libp2p/interfaces-v1.3.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.5...@libp2p/interfaces-v1.3.6) (2022-02-12) + + +### Bug Fixes + +* hide implementations behind factory methods ([#167](https://github.com/libp2p/js-libp2p-interfaces/issues/167)) ([2fba080](https://github.com/libp2p/js-libp2p-interfaces/commit/2fba0800c9896af6dcc49da4fa904bb4a3e3e40d)) + +## [@libp2p/interfaces-v1.3.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.4...@libp2p/interfaces-v1.3.5) (2022-02-11) + + +### Bug Fixes + +* add .js to import paths ([#166](https://github.com/libp2p/js-libp2p-interfaces/issues/166)) ([dbf6688](https://github.com/libp2p/js-libp2p-interfaces/commit/dbf6688cc7295c821b473b05d211239616ad2ae1)) + +## [@libp2p/interfaces-v1.3.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.3...@libp2p/interfaces-v1.3.4) (2022-02-11) + + +### Bug Fixes + +* simpler topologies ([#164](https://github.com/libp2p/js-libp2p-interfaces/issues/164)) ([45fcaa1](https://github.com/libp2p/js-libp2p-interfaces/commit/45fcaa10a6a3215089340ff2eff117d7fd1100e7)) + +## [@libp2p/interfaces-v1.3.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.2...@libp2p/interfaces-v1.3.3) (2022-02-10) + + +### Bug Fixes + +* make registrar simpler ([#163](https://github.com/libp2p/js-libp2p-interfaces/issues/163)) ([d122f3d](https://github.com/libp2p/js-libp2p-interfaces/commit/d122f3daaccc04039d90814960da92b513265644)) + +## [@libp2p/interfaces-v1.3.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.1...@libp2p/interfaces-v1.3.2) (2022-02-10) + + +### Bug Fixes + +* remove args from listener events ([#162](https://github.com/libp2p/js-libp2p-interfaces/issues/162)) ([011ac89](https://github.com/libp2p/js-libp2p-interfaces/commit/011ac891ec7d44625cb4342f068bcd9f241a5b45)) + +## [@libp2p/interfaces-v1.3.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.3.0...@libp2p/interfaces-v1.3.1) (2022-02-10) + + +### Bug Fixes + +* remove node event emitters ([#161](https://github.com/libp2p/js-libp2p-interfaces/issues/161)) ([221fb6a](https://github.com/libp2p/js-libp2p-interfaces/commit/221fb6a024430dc56288d73d8b8ce1aa88427701)) + +## [@libp2p/interfaces-v1.3.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.2.0...@libp2p/interfaces-v1.3.0) (2022-02-09) + + +### Features + +* add peer store/records, and streams are just streams ([#160](https://github.com/libp2p/js-libp2p-interfaces/issues/160)) ([8860a0c](https://github.com/libp2p/js-libp2p-interfaces/commit/8860a0cd46b359a5648402d83870f7ff957222fe)) + +## [@libp2p/interfaces-v1.2.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.1.1...@libp2p/interfaces-v1.2.0) (2022-02-07) + + +### Features + +* add logger package ([#158](https://github.com/libp2p/js-libp2p-interfaces/issues/158)) ([f327cd2](https://github.com/libp2p/js-libp2p-interfaces/commit/f327cd24825d9ce2f45a02fdb9b47c9735c847e0)) + +## [@libp2p/interfaces-v1.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.1.0...@libp2p/interfaces-v1.1.1) (2022-02-05) + + +### Bug Fixes + +* fix muxer tests ([#157](https://github.com/libp2p/js-libp2p-interfaces/issues/157)) ([7233c44](https://github.com/libp2p/js-libp2p-interfaces/commit/7233c4438479dff56a682f45209ef7a938d63857)) + +## [@libp2p/interfaces-v1.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.0.6...@libp2p/interfaces-v1.1.0) (2022-02-05) + + +### Features + +* add tracked-map ([#156](https://github.com/libp2p/js-libp2p-interfaces/issues/156)) ([c17730f](https://github.com/libp2p/js-libp2p-interfaces/commit/c17730f8bca172db85507740eaba81b3cf514d04)) + +## [@libp2p/interfaces-v1.0.6](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.0.5...@libp2p/interfaces-v1.0.6) (2022-02-02) + + +### Bug Fixes + +* make discovery startable ([#155](https://github.com/libp2p/js-libp2p-interfaces/issues/155)) ([c7db291](https://github.com/libp2p/js-libp2p-interfaces/commit/c7db2918f5c4e00b45bcbd69541224403e5451e1)) + +## [@libp2p/interfaces-v1.0.5](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.0.4...@libp2p/interfaces-v1.0.5) (2022-01-29) + + +### Bug Fixes + +* remove extra fields ([#153](https://github.com/libp2p/js-libp2p-interfaces/issues/153)) ([ccd7cf3](https://github.com/libp2p/js-libp2p-interfaces/commit/ccd7cf3f5ac71337baf516d3b0f6fc724ee0d3b4)) + +## [@libp2p/interfaces-v1.0.4](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.0.3...@libp2p/interfaces-v1.0.4) (2022-01-15) + + +### Bug Fixes + +* remove abort controller dep ([#151](https://github.com/libp2p/js-libp2p-interfaces/issues/151)) ([518bce1](https://github.com/libp2p/js-libp2p-interfaces/commit/518bce1f9bd1f8b2922338e0c65c9934af7da3af)) + +## [@libp2p/interfaces-v1.0.3](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.0.2...@libp2p/interfaces-v1.0.3) (2022-01-15) + + +### Trivial Changes + +* update project config ([#149](https://github.com/libp2p/js-libp2p-interfaces/issues/149)) ([6eb8556](https://github.com/libp2p/js-libp2p-interfaces/commit/6eb85562c0da167d222808da10a7914daf12970b)) + +## [@libp2p/interfaces-v1.0.2](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.0.1...@libp2p/interfaces-v1.0.2) (2022-01-14) + + +### Bug Fixes + +* update it-* deps to ts versions ([#148](https://github.com/libp2p/js-libp2p-interfaces/issues/148)) ([7a6fdd7](https://github.com/libp2p/js-libp2p-interfaces/commit/7a6fdd7622ce2870b89dbb849ab421d0dd714b43)) + +## [@libp2p/interfaces-v1.0.1](https://github.com/libp2p/js-libp2p-interfaces/compare/@libp2p/interfaces-v1.0.0...@libp2p/interfaces-v1.0.1) (2022-01-08) + + +### Trivial Changes + +* add semantic release config ([#141](https://github.com/libp2p/js-libp2p-interfaces/issues/141)) ([5f0de59](https://github.com/libp2p/js-libp2p-interfaces/commit/5f0de59136b6343d2411abb2d6a4dd2cd0b7efe4)) +* update package versions ([#140](https://github.com/libp2p/js-libp2p-interfaces/issues/140)) ([cd844f6](https://github.com/libp2p/js-libp2p-interfaces/commit/cd844f6e39f4ee50d006e86eac8dadf696900eb5)) + +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.2.0 (2022-01-04) + + +### Bug Fixes + +* make connection upgrade and encryption abortable ([#121](https://github.com/libp2p/js-libp2p-interfaces/issues/121)) ([d31583d](https://github.com/libp2p/js-libp2p-interfaces/commit/d31583d204c5fa07df0479f37bd0d4a925cc812b)) +* move errors ([#132](https://github.com/libp2p/js-libp2p-interfaces/issues/132)) ([21d282a](https://github.com/libp2p/js-libp2p-interfaces/commit/21d282a6d77bd7d1a12daa1cc8b3a3fed8635dad)) +* update dialer tests ([#116](https://github.com/libp2p/js-libp2p-interfaces/issues/116)) ([c679729](https://github.com/libp2p/js-libp2p-interfaces/commit/c679729113feb963ff27815fcafd7af51f722df7)) + + +### Features + +* add auto-publish ([7aede5d](https://github.com/libp2p/js-libp2p-interfaces/commit/7aede5df39ea6b5f243348ec9a212b3e33c16a81)) +* remove getPublicKey method from dht ([603c818](https://github.com/libp2p/js-libp2p-interfaces/commit/603c818d0694652346bc552525f2379b1dfa0107)) +* simpler peer id ([#117](https://github.com/libp2p/js-libp2p-interfaces/issues/117)) ([fa2c4f5](https://github.com/libp2p/js-libp2p-interfaces/commit/fa2c4f5be74a5cfc11489771881e57b4e53bf174)) +* split out code, convert to typescript ([#111](https://github.com/libp2p/js-libp2p-interfaces/issues/111)) ([e174bba](https://github.com/libp2p/js-libp2p-interfaces/commit/e174bba889388269b806643c79a6b53c8d6a0f8c)), closes [#110](https://github.com/libp2p/js-libp2p-interfaces/issues/110) [#101](https://github.com/libp2p/js-libp2p-interfaces/issues/101) +* update package names ([#133](https://github.com/libp2p/js-libp2p-interfaces/issues/133)) ([337adc9](https://github.com/libp2p/js-libp2p-interfaces/commit/337adc9a9bc0278bdae8cbce9c57d07a83c8b5c2)) + + +### BREAKING CHANGES + +* the dht.getPublicKey method has been removed +* not all fields from concrete classes have been added to the interfaces, some adjustment may be necessary as this gets rolled out + + + + + +## [3.1.1](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces@3.1.0...libp2p-interfaces@3.1.1) (2022-01-02) + + +### Bug Fixes + +* move errors ([#132](https://github.com/libp2p/js-libp2p-interfaces/issues/132)) ([21d282a](https://github.com/libp2p/js-libp2p-interfaces/commit/21d282a6d77bd7d1a12daa1cc8b3a3fed8635dad)) + + + + + +# [3.1.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces@3.0.0...libp2p-interfaces@3.1.0) (2022-01-02) + + +### Bug Fixes + +* make connection upgrade and encryption abortable ([#121](https://github.com/libp2p/js-libp2p-interfaces/issues/121)) ([d31583d](https://github.com/libp2p/js-libp2p-interfaces/commit/d31583d204c5fa07df0479f37bd0d4a925cc812b)) +* update dialer tests ([#116](https://github.com/libp2p/js-libp2p-interfaces/issues/116)) ([c679729](https://github.com/libp2p/js-libp2p-interfaces/commit/c679729113feb963ff27815fcafd7af51f722df7)) + + +### Features + +* simpler peer id ([#117](https://github.com/libp2p/js-libp2p-interfaces/issues/117)) ([fa2c4f5](https://github.com/libp2p/js-libp2p-interfaces/commit/fa2c4f5be74a5cfc11489771881e57b4e53bf174)) + + + + + +# [3.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces@2.0.0...libp2p-interfaces@3.0.0) (2021-12-02) + + +### Features + +* remove getPublicKey method from dht ([603c818](https://github.com/libp2p/js-libp2p-interfaces/commit/603c818d0694652346bc552525f2379b1dfa0107)) + + +### BREAKING CHANGES + +* the dht.getPublicKey method has been removed + + + + + +# [2.0.0](https://github.com/libp2p/js-libp2p-interfaces/compare/libp2p-interfaces@1.2.0...libp2p-interfaces@2.0.0) (2021-11-22) + + +### Features + +* split out code, convert to typescript ([#111](https://github.com/libp2p/js-libp2p-interfaces/issues/111)) ([e174bba](https://github.com/libp2p/js-libp2p-interfaces/commit/e174bba889388269b806643c79a6b53c8d6a0f8c)), closes [#110](https://github.com/libp2p/js-libp2p-interfaces/issues/110) [#101](https://github.com/libp2p/js-libp2p-interfaces/issues/101) + + +### BREAKING CHANGES + +* not all fields from concrete classes have been added to the interfaces, some adjustment may be necessary as this gets rolled out + + + + + +# [1.2.0](https://github.com/libp2p/js-interfaces/compare/libp2p-interfaces@1.1.1...libp2p-interfaces@1.2.0) (2021-10-18) + + +### Features + +* add ValueStore interface ([#108](https://github.com/libp2p/js-interfaces/issues/108)) ([09c6e10](https://github.com/libp2p/js-interfaces/commit/09c6e10353c1d8842a5522d28d5cd38ae47d892f)) + + + + + +## [1.1.1](https://github.com/libp2p/js-interfaces/compare/libp2p-interfaces@1.1.0...libp2p-interfaces@1.1.1) (2021-09-20) + + +### Bug Fixes + +* allow pubsub rpc to be processed concurrently ([#106](https://github.com/libp2p/js-interfaces/issues/106)) ([52f96b3](https://github.com/libp2p/js-interfaces/commit/52f96b3eb867b844a9c4a0d1fd632baa300052a2)) + + + + + +# [1.1.0](https://github.com/libp2p/js-interfaces/compare/libp2p-interfaces@1.0.1...libp2p-interfaces@1.1.0) (2021-08-20) + + +### Features + +* update uint8arrays ([#105](https://github.com/libp2p/js-interfaces/issues/105)) ([9297a9c](https://github.com/libp2p/js-interfaces/commit/9297a9c379276d03c8da849af6108b38e581b4a6)) + + + + + +## [1.0.1](https://github.com/libp2p/js-interfaces/compare/libp2p-interfaces@1.0.0...libp2p-interfaces@1.0.1) (2021-07-08) + + +### Bug Fixes + +* make tests more reliable ([#103](https://github.com/libp2p/js-interfaces/issues/103)) ([cd4c409](https://github.com/libp2p/js-interfaces/commit/cd4c40908efe2e9ffc14aa61aace5176a43fd70a)) +* remove timeouts ([#104](https://github.com/libp2p/js-interfaces/issues/104)) ([3699c17](https://github.com/libp2p/js-interfaces/commit/3699c17f022da40a87ab24adc3b2081df7a0ddcd)) + + + + + +# 1.0.0 (2021-07-07) + + +### chore + +* monorepo separating interfaces and compliance tests ([#97](https://github.com/libp2p/js-interfaces/issues/97)) ([946348f](https://github.com/libp2p/js-interfaces/commit/946348f7f8acc1ff7bc9cd0ab4c2602d41106f76)) + + +### BREAKING CHANGES + +* the tests now live in the libp2p-interfaces-compliance-tests module + + + + + +## [0.12.1](https://github.com/libp2p/js-interfaces/compare/v0.12.0...v0.12.1) (2021-07-07) + + + +# [0.12.0](https://github.com/libp2p/js-interfaces/compare/v0.11.0...v0.12.0) (2021-07-06) + + +### chore + +* update to new multiformats ([#98](https://github.com/libp2p/js-interfaces/issues/98)) ([242027c](https://github.com/libp2p/js-interfaces/commit/242027cdfd08004f20d0148f4905381d34942dc6)) + + +### BREAKING CHANGES + +* uses the CID class from the new multiformats module and pubsub.getMsgId became async + +Co-authored-by: Vasco Santos + + + +# [0.11.0](https://github.com/libp2p/js-interfaces/compare/v0.10.4...v0.11.0) (2021-05-27) + + + +## [0.10.4](https://github.com/libp2p/js-interfaces/compare/v0.10.3...v0.10.4) (2021-04-30) + + +### Bug Fixes + +* event emitter and discovery and routing interfaces ([#95](https://github.com/libp2p/js-interfaces/issues/95)) ([93ddaa4](https://github.com/libp2p/js-interfaces/commit/93ddaa4860ff743b312268b6a859b5e6365fff74)) + + + +## [0.10.3](https://github.com/libp2p/js-interfaces/compare/v0.10.2...v0.10.3) (2021-04-22) + + + +## [0.10.2](https://github.com/libp2p/js-interfaces/compare/v0.10.1...v0.10.2) (2021-04-20) + + +### Bug Fixes + +* specify pbjs root ([#93](https://github.com/libp2p/js-interfaces/issues/93)) ([70ae573](https://github.com/libp2p/js-interfaces/commit/70ae573a4ea2ac074f7cda2a732ed5be283e48c4)) + + + +## [0.10.1](https://github.com/libp2p/js-interfaces/compare/v0.10.0...v0.10.1) (2021-04-19) + + +### Features + +* export type for new stream muxer function ([#91](https://github.com/libp2p/js-interfaces/issues/91)) ([6467fdd](https://github.com/libp2p/js-interfaces/commit/6467fdd6ce1d13cfa3b34e3aaa73a64a669d2033)) + + + +# [0.10.0](https://github.com/libp2p/js-interfaces/compare/v0.9.0...v0.10.0) (2021-04-12) + + + +# [0.9.0](https://github.com/libp2p/js-interfaces/compare/v0.8.4...v0.9.0) (2021-04-07) + + + +## [0.8.4](https://github.com/libp2p/js-interfaces/compare/v0.8.3...v0.8.4) (2021-03-22) + + +### Bug Fixes + +* specify connection direction ([#86](https://github.com/libp2p/js-interfaces/issues/86)) ([3b960d5](https://github.com/libp2p/js-interfaces/commit/3b960d516f70f7e198574a736cb09000ddd7a94c)) + + + +## [0.8.3](https://github.com/libp2p/js-interfaces/compare/v0.8.2...v0.8.3) (2021-01-26) + + + +## [0.8.2](https://github.com/libp2p/js-interfaces/compare/v0.8.1...v0.8.2) (2021-01-20) + + +### Bug Fixes + +* event emitter types with local types ([#80](https://github.com/libp2p/js-interfaces/issues/80)) ([ca52077](https://github.com/libp2p/js-interfaces/commit/ca520775eb26f5ed501375fdb24ba698c9a8c8c8)) + + + +## [0.8.1](https://github.com/libp2p/js-interfaces/compare/v0.8.0...v0.8.1) (2020-12-11) + + +### Bug Fixes + +* pubsub publish message should be uint8array ([#77](https://github.com/libp2p/js-interfaces/issues/77)) ([5b99e6b](https://github.com/libp2p/js-interfaces/commit/5b99e6b56b10439a82ee88fb4e31fb95c182264f)) + + + +# [0.8.0](https://github.com/libp2p/js-interfaces/compare/v0.7.2...v0.8.0) (2020-12-10) + + +### Features + +* add types ([#74](https://github.com/libp2p/js-interfaces/issues/74)) ([e2419ea](https://github.com/libp2p/js-interfaces/commit/e2419ea308b5db38966850ba6349602c93ce3b0e)) + + + + +## [0.7.2](https://github.com/libp2p/js-interfaces/compare/v0.7.1...v0.7.2) (2020-11-11) + + + + +## [0.7.1](https://github.com/libp2p/js-interfaces/compare/v0.7.0...v0.7.1) (2020-11-03) + + +### Bug Fixes + +* typescript types ([#69](https://github.com/libp2p/js-interfaces/issues/69)) ([269a6f5](https://github.com/libp2p/js-interfaces/commit/269a6f5)) + + + + +# [0.7.0](https://github.com/libp2p/js-interfaces/compare/v0.5.2...v0.7.0) (2020-11-03) + + +### Features + +* pubsub: add global signature policy ([#66](https://github.com/libp2p/js-interfaces/issues/66)) ([946b046](https://github.com/libp2p/js-interfaces/commit/946b046)) +* update pubsub getMsgId return type to Uint8Array ([#65](https://github.com/libp2p/js-interfaces/issues/65)) ([e148443](https://github.com/libp2p/js-interfaces/commit/e148443)) + + +### BREAKING CHANGES + +* `signMessages` and `strictSigning` pubsub configuration options replaced +with a `globalSignaturePolicy` option +* new getMsgId return type is not backwards compatible with prior `string` +return type. + + + + +# [0.6.0](https://github.com/libp2p/js-interfaces/compare/v0.5.2...v0.6.0) (2020-10-05) + + +### Features + +* update pubsub getMsgId return type to Uint8Array ([#65](https://github.com/libp2p/js-interfaces/issues/65)) ([e148443](https://github.com/libp2p/js-interfaces/commit/e148443)) + + +### BREAKING CHANGES + +* new getMsgId return type is not backwards compatible with prior `string` +return type. + + + + +## [0.5.2](https://github.com/libp2p/js-interfaces/compare/v0.3.1...v0.5.2) (2020-09-30) + + +### Bug Fixes + +* replace remaining Buffer usage with Uint8Array ([#62](https://github.com/libp2p/js-interfaces/issues/62)) ([4130e7f](https://github.com/libp2p/js-interfaces/commit/4130e7f)) + + +### Chores + +* update deps ([#57](https://github.com/libp2p/js-interfaces/issues/57)) ([75f6777](https://github.com/libp2p/js-interfaces/commit/75f6777)) + + +### Features + +* interface pubsub ([#60](https://github.com/libp2p/js-interfaces/issues/60)) ([ba15a48](https://github.com/libp2p/js-interfaces/commit/ba15a48)) +* record interface ([#52](https://github.com/libp2p/js-interfaces/issues/52)) ([1cc943e](https://github.com/libp2p/js-interfaces/commit/1cc943e)) + + +### BREAKING CHANGES + +* records now marshal as Uint8Array instead of Buffer + +* fix: refactor remaining Buffer usage to Uint8Array +* - The peer id dep of this module has replaced node Buffers with Uint8Arrays + +* chore: update gh deps + + + + +## [0.5.1](https://github.com/libp2p/js-interfaces/compare/v0.5.0...v0.5.1) (2020-08-25) + + +### Features + +* interface pubsub ([#60](https://github.com/libp2p/js-interfaces/issues/60)) ([ba15a48](https://github.com/libp2p/js-interfaces/commit/ba15a48)) + + + + +# [0.5.0](https://github.com/libp2p/js-interfaces/compare/v0.4.1...v0.5.0) (2020-08-24) + + +### Bug Fixes + +* replace remaining Buffer usage with Uint8Array ([#62](https://github.com/libp2p/js-interfaces/issues/62)) ([4130e7f](https://github.com/libp2p/js-interfaces/commit/4130e7f)) + + +### BREAKING CHANGES + +* records now marshal as Uint8Array instead of Buffer + +* fix: refactor remaining Buffer usage to Uint8Array + + + + +## [0.4.1](https://github.com/libp2p/js-interfaces/compare/v0.4.0...v0.4.1) (2020-08-11) + + + + +# [0.4.0](https://github.com/libp2p/js-interfaces/compare/v0.3.2...v0.4.0) (2020-08-10) + + +### Chores + +* update deps ([#57](https://github.com/libp2p/js-interfaces/issues/57)) ([75f6777](https://github.com/libp2p/js-interfaces/commit/75f6777)) + + +### BREAKING CHANGES + +* - The peer id dep of this module has replaced node Buffers with Uint8Arrays + +* chore: update gh deps + + + + +## [0.3.2](https://github.com/libp2p/js-interfaces/compare/v0.3.1...v0.3.2) (2020-07-15) + + +### Features + +* record interface ([#52](https://github.com/libp2p/js-interfaces/issues/52)) ([1cc943e](https://github.com/libp2p/js-interfaces/commit/1cc943e)) + + + + +## [0.3.1](https://github.com/libp2p/js-interfaces/compare/v0.2.8...v0.3.1) (2020-07-03) + + +### Bug Fixes + +* content and peer routing multiaddrs property ([#49](https://github.com/libp2p/js-interfaces/issues/49)) ([9fbf9d0](https://github.com/libp2p/js-interfaces/commit/9fbf9d0)) +* peer-routing typo ([#47](https://github.com/libp2p/js-interfaces/issues/47)) ([9a8f375](https://github.com/libp2p/js-interfaces/commit/9a8f375)) +* reconnect should trigger topology on connect if protocol stored ([#54](https://github.com/libp2p/js-interfaces/issues/54)) ([e10a154](https://github.com/libp2p/js-interfaces/commit/e10a154)) + + +### Chores + +* remove peer-info usage on topology ([#42](https://github.com/libp2p/js-interfaces/issues/42)) ([a55c7c4](https://github.com/libp2p/js-interfaces/commit/a55c7c4)) +* update content and peer routing interfaces removing peer-info ([#43](https://github.com/libp2p/js-interfaces/issues/43)) ([87e2e89](https://github.com/libp2p/js-interfaces/commit/87e2e89)) + + +### Features + +* peer-discovery not using peer-info ([bdd2502](https://github.com/libp2p/js-interfaces/commit/bdd2502)) + + +### BREAKING CHANGES + +* topology api now uses peer-id instead of peer-info +* content-routing and peer-routing APIs return an object with relevant properties instead of peer-info +* peer-discovery emits object with id and multiaddrs properties + + + + +# [0.3.0](https://github.com/libp2p/js-interfaces/compare/v0.2.8...v0.3.0) (2020-04-21) + + +### Chores + +* remove peer-info usage on topology ([#42](https://github.com/libp2p/js-interfaces/issues/42)) ([79a7843](https://github.com/libp2p/js-interfaces/commit/79a7843)) +* update content and peer routing interfaces removing peer-info ([#43](https://github.com/libp2p/js-interfaces/issues/43)) ([d2032e6](https://github.com/libp2p/js-interfaces/commit/d2032e6)) + + +### Features + +* peer-discovery not using peer-info ([5792b13](https://github.com/libp2p/js-interfaces/commit/5792b13)) + + +### BREAKING CHANGES + +* topology api now uses peer-id instead of peer-info +* content-routing and peer-routing APIs return an object with relevant properties instead of peer-info +* peer-discovery emits object with id and multiaddrs properties + + + + +## [0.2.8](https://github.com/libp2p/js-interfaces/compare/v0.2.7...v0.2.8) (2020-04-21) + + + + +## [0.2.7](https://github.com/libp2p/js-interfaces/compare/v0.2.6...v0.2.7) (2020-03-20) + + +### Bug Fixes + +* add buffer ([#39](https://github.com/libp2p/js-interfaces/issues/39)) ([78e015c](https://github.com/libp2p/js-interfaces/commit/78e015c)) + + + + +## [0.2.6](https://github.com/libp2p/js-interfaces/compare/v0.2.5...v0.2.6) (2020-02-17) + + +### Bug Fixes + +* remove use of assert module ([#34](https://github.com/libp2p/js-interfaces/issues/34)) ([c77d8de](https://github.com/libp2p/js-interfaces/commit/c77d8de)) + + + + +## [0.2.5](https://github.com/libp2p/js-interfaces/compare/v0.2.4...v0.2.5) (2020-02-04) + + +### Bug Fixes + +* **connection:** tracks streams properly ([#25](https://github.com/libp2p/js-interfaces/issues/25)) ([5c88d77](https://github.com/libp2p/js-interfaces/commit/5c88d77)) + + + + +## [0.2.4](https://github.com/libp2p/js-interfaces/compare/v0.2.3...v0.2.4) (2020-02-04) + + +### Bug Fixes + +* dependencies for tests should not be needed by who requires the tests ([#18](https://github.com/libp2p/js-interfaces/issues/18)) ([c5b724a](https://github.com/libp2p/js-interfaces/commit/c5b724a)) + + + + +## [0.2.3](https://github.com/libp2p/js-interfaces/compare/v0.2.2...v0.2.3) (2020-01-21) + + +### Bug Fixes + +* **transport:** make close listener test more resilient ([#21](https://github.com/libp2p/js-interfaces/issues/21)) ([2de533e](https://github.com/libp2p/js-interfaces/commit/2de533e)) + + + + +## [0.2.2](https://github.com/libp2p/js-interfaces/compare/v0.2.1...v0.2.2) (2020-01-17) + + +### Bug Fixes + +* **connection:** dont require remoteAddr on creation ([#20](https://github.com/libp2p/js-interfaces/issues/20)) ([5967834](https://github.com/libp2p/js-interfaces/commit/5967834)) + + + + +## [0.2.1](https://github.com/libp2p/js-interfaces/compare/v0.2.0...v0.2.1) (2019-12-28) + + +### Features + +* add crypto transmission error ([#17](https://github.com/libp2p/js-interfaces/issues/17)) ([d98bb23](https://github.com/libp2p/js-interfaces/commit/d98bb23)) + + + + +# [0.2.0](https://github.com/libp2p/js-interfaces/compare/v0.1.7...v0.2.0) (2019-12-20) + + +### Bug Fixes + +* transport should not handle connection if upgradeInbound throws ([#16](https://github.com/libp2p/js-interfaces/issues/16)) ([ff03137](https://github.com/libp2p/js-interfaces/commit/ff03137)) + + + + +## [0.1.7](https://github.com/libp2p/js-interfaces/compare/v0.1.6...v0.1.7) (2019-12-15) + + +### Features + +* export connection status' ([#15](https://github.com/libp2p/js-interfaces/issues/15)) ([bdbd58e](https://github.com/libp2p/js-interfaces/commit/bdbd58e)) + + + + +## [0.1.6](https://github.com/libp2p/js-interfaces/compare/v0.1.5...v0.1.6) (2019-12-02) + + +### Bug Fixes + +* multicodec topology disconnect with peer param ([#12](https://github.com/libp2p/js-interfaces/issues/12)) ([d5dd256](https://github.com/libp2p/js-interfaces/commit/d5dd256)) + + + + +## [0.1.5](https://github.com/libp2p/js-interfaces/compare/v0.1.4...v0.1.5) (2019-11-15) + + +### Bug Fixes + +* multicodec topology update peers with multicodec ([#10](https://github.com/libp2p/js-interfaces/issues/10)) ([21d8ae6](https://github.com/libp2p/js-interfaces/commit/21d8ae6)) + + +### Features + +* add class-is to topology ([#11](https://github.com/libp2p/js-interfaces/issues/11)) ([a67abcc](https://github.com/libp2p/js-interfaces/commit/a67abcc)) + + + + +## [0.1.4](https://github.com/libp2p/js-interfaces/compare/v0.1.3...v0.1.4) (2019-11-14) + + +### Features + +* add topology interfaces ([#7](https://github.com/libp2p/js-interfaces/issues/7)) ([8bee747](https://github.com/libp2p/js-interfaces/commit/8bee747)) + + + + +## [0.1.3](https://github.com/libp2p/js-interfaces/compare/v0.1.2...v0.1.3) (2019-10-30) + + +### Bug Fixes + +* localAddr should be optional ([#6](https://github.com/libp2p/js-interfaces/issues/6)) ([749a8d0](https://github.com/libp2p/js-interfaces/commit/749a8d0)) + + + + +## [0.1.2](https://github.com/libp2p/js-interfaces/compare/v0.1.1...v0.1.2) (2019-10-29) + + +### Features + +* crypto errors ([#4](https://github.com/libp2p/js-interfaces/issues/4)) ([d2fe2d1](https://github.com/libp2p/js-interfaces/commit/d2fe2d1)) + + + + +## [0.1.1](https://github.com/libp2p/js-interfaces/compare/v0.1.0...v0.1.1) (2019-10-21) + + +### Features + +* crypto interface ([#2](https://github.com/libp2p/js-interfaces/issues/2)) ([5a5c44a](https://github.com/libp2p/js-interfaces/commit/5a5c44a)) + + + + +# 0.1.0 (2019-10-20) + + +### Bug Fixes + +* add async support to setup ([#11](https://github.com/libp2p/js-interfaces/issues/11)) ([2814c76](https://github.com/libp2p/js-interfaces/commit/2814c76)) +* **test:** close with timeout ([#54](https://github.com/libp2p/js-interfaces/issues/54)) ([583f02d](https://github.com/libp2p/js-interfaces/commit/583f02d)) +* avoid making webpacky funky by not trying to inject tcp ([6695b80](https://github.com/libp2p/js-interfaces/commit/6695b80)) +* improve the close test ([d9c8681](https://github.com/libp2p/js-interfaces/commit/d9c8681)) +* move dirty-chai to dependencies ([#52](https://github.com/libp2p/js-interfaces/issues/52)) ([f9a7908](https://github.com/libp2p/js-interfaces/commit/f9a7908)) +* some fixes for incorrect tests ([23a75d1](https://github.com/libp2p/js-interfaces/commit/23a75d1)) +* when things are in the same process, there is a order to them :) ([1635977](https://github.com/libp2p/js-interfaces/commit/1635977)) +* wrong main path in package.json ([54b83a7](https://github.com/libp2p/js-interfaces/commit/54b83a7)) +* **deps:** fix package.json ([e0f7db3](https://github.com/libp2p/js-interfaces/commit/e0f7db3)) +* **dial-test:** ensure goodbye works over tcp ([e1346da](https://github.com/libp2p/js-interfaces/commit/e1346da)) +* **package.json:** point to right main ([ace6150](https://github.com/libp2p/js-interfaces/commit/ace6150)) +* **package.json:** point to right main ([84cd2ca](https://github.com/libp2p/js-interfaces/commit/84cd2ca)) +* **tests:** add place holder test script for releases ([8e9f7cf](https://github.com/libp2p/js-interfaces/commit/8e9f7cf)) + + +### Code Refactoring + +* API changes and switch to async await ([#55](https://github.com/libp2p/js-interfaces/issues/55)) ([dd837ba](https://github.com/libp2p/js-interfaces/commit/dd837ba)) +* API changes and switch to async iterators ([#29](https://github.com/libp2p/js-interfaces/issues/29)) ([bf5c646](https://github.com/libp2p/js-interfaces/commit/bf5c646)) + + +### Features + +* add onStreamEnd, muxer.streams and timeline ([#56](https://github.com/libp2p/js-interfaces/issues/56)) ([0f60832](https://github.com/libp2p/js-interfaces/commit/0f60832)) +* add support for timeline proxying ([#31](https://github.com/libp2p/js-interfaces/issues/31)) ([541bf83](https://github.com/libp2p/js-interfaces/commit/541bf83)) +* add type to AbortError ([#45](https://github.com/libp2p/js-interfaces/issues/45)) ([4fd37bb](https://github.com/libp2p/js-interfaces/commit/4fd37bb)) +* add upgrader support to transports ([#53](https://github.com/libp2p/js-interfaces/issues/53)) ([a5ad120](https://github.com/libp2p/js-interfaces/commit/a5ad120)) +* async crypto + sauce labs + aegir 9 ([b40114c](https://github.com/libp2p/js-interfaces/commit/b40114c)) +* callbacks -> async / await ([#44](https://github.com/libp2p/js-interfaces/issues/44)) ([b30ee5f](https://github.com/libp2p/js-interfaces/commit/b30ee5f)) +* initial commit ([584a69b](https://github.com/libp2p/js-interfaces/commit/584a69b)) +* make listen take an array of addrs ([#46](https://github.com/libp2p/js-interfaces/issues/46)) ([1dc5baa](https://github.com/libp2p/js-interfaces/commit/1dc5baa)) +* move to next aegir ([11980ac](https://github.com/libp2p/js-interfaces/commit/11980ac)) +* timeline and close checking ([#55](https://github.com/libp2p/js-interfaces/issues/55)) ([993ca1c](https://github.com/libp2p/js-interfaces/commit/993ca1c)) +* **api:** update the interface usage from dial to dialer and listen to listener ([5069679](https://github.com/libp2p/js-interfaces/commit/5069679)) +* **connection:** migrate to pull-streams ([ed5727a](https://github.com/libp2p/js-interfaces/commit/ed5727a)) +* **dialer:** remove conn from on connect callback ([1bd20d9](https://github.com/libp2p/js-interfaces/commit/1bd20d9)) +* **pull:** migration to pull streams. Upgrade tests to use mocha as ([cc3130f](https://github.com/libp2p/js-interfaces/commit/cc3130f)) +* **spec:** update the dial interface to cope with new pull additions ([2e12166](https://github.com/libp2p/js-interfaces/commit/2e12166)) +* **tests:** add closing tests, make sure errors are propagated ([c06da3b](https://github.com/libp2p/js-interfaces/commit/c06da3b)) +* **tests:** add dial and listen tests ([d50224d](https://github.com/libp2p/js-interfaces/commit/d50224d)) +* **tests:** stub test for aegir to verify ([949faf0](https://github.com/libp2p/js-interfaces/commit/949faf0)) + + +### Reverts + +* "feat: make listen take an array of addrs ([#46](https://github.com/libp2p/js-interfaces/issues/46))" ([#51](https://github.com/libp2p/js-interfaces/issues/51)) ([030195e](https://github.com/libp2p/js-interfaces/commit/030195e)) + + +### BREAKING CHANGES + +* all the callbacks in the provided API were removed and each function uses async/await. Additionally, pull-streams are no longer being used. See the README for new usage. +* This adds new validations to the stream muxer, which will cause existing tests to fail. +* the API is now async / await. See https://github.com/libp2p/interface-stream-muxer/pull/55#issue-275014779 for a summary of the changes. +* Transports must now be passed and use an `Upgrader` instance. See the Readme for usage. Compliance test suites will now need to pass `options` from `common.setup(options)` to their Transport constructor. + +* docs: update readme to include upgrader + +* docs: update readme to include MultiaddrConnection ref + +* feat: add upgrader spy to test suite + +* test: validate returned value of spy +* All places in the API that used callbacks are now replaced with async/await + +* test: add tests for canceling dials + +* feat: Adapter class diff --git a/packages/interfaces/LICENSE b/packages/interfaces/LICENSE new file mode 100644 index 0000000000..20ce483c86 --- /dev/null +++ b/packages/interfaces/LICENSE @@ -0,0 +1,4 @@ +This project is dual licensed under MIT and Apache-2.0. + +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/packages/interfaces/LICENSE-APACHE b/packages/interfaces/LICENSE-APACHE new file mode 100644 index 0000000000..14478a3b60 --- /dev/null +++ b/packages/interfaces/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/packages/interfaces/LICENSE-MIT b/packages/interfaces/LICENSE-MIT new file mode 100644 index 0000000000..72dc60d84b --- /dev/null +++ b/packages/interfaces/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/interfaces/README.md b/packages/interfaces/README.md new file mode 100644 index 0000000000..4e17b6d5c2 --- /dev/null +++ b/packages/interfaces/README.md @@ -0,0 +1,101 @@ +# @libp2p/interfaces + +[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/) +[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io) +[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p) +[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) + +> Common code shared by the various libp2p interfaces + +## Table of contents + +- [Install](#install) +- [Usage](#usage) + - [AbortError](#aborterror) + - [Events](#events) + - [AbortOptions](#abortoptions) + - [Startable](#startable) +- [API Docs](#api-docs) +- [License](#license) +- [Contribution](#contribution) + +## Install + +```console +$ npm i @libp2p/interfaces +``` + +## Usage + +### AbortError + +Throw an error with a `.code` property of `'ABORT_ERR'`: + +```js +import { AbortError } from '@libp2p/interfaces/errors' + +throw new AbortError() +``` + +### Events + +Typed events: + +```js +import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events' + +export interface MyEmitterEvents { + 'some-event': CustomEvent; +} + +class MyEmitter extends EventEmitter { + +} + +// later +const myEmitter = new MyEmitter() +myEmitter.addEventListener('some-event', (evt) => { + const num = evt.detail // <-- inferred as number +}) +``` + +### AbortOptions + +```js +import type { AbortOptions } from '@libp2p/interfaces' +``` + +### Startable + +Lifecycles for components + +```js +import { start, stop, isStartable } from '@libp2p/interfaces/startable' +import type { Startable } from '@libp2p/interfaces/startable' + +class MyStartable implements Startable { + // .. implementation methods +} + +const myStartable = new MyStartable() + +isStartable(myStartable) // returns true + +await start(myStartable) +await stop(myStartable) +``` + +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + +## Contribution + +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. diff --git a/packages/interfaces/package.json b/packages/interfaces/package.json new file mode 100644 index 0000000000..d55124fae2 --- /dev/null +++ b/packages/interfaces/package.json @@ -0,0 +1,164 @@ +{ + "name": "@libp2p/interfaces", + "version": "3.3.2", + "description": "Common code shared by the various libp2p interfaces", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interfaces#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/libp2p/js-libp2p.git" + }, + "bugs": { + "url": "https://github.com/libp2p/js-libp2p/issues" + }, + "keywords": [ + "interface", + "libp2p" + ], + "type": "module", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ], + "src/*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ] + } + }, + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./errors": { + "types": "./dist/src/errors.d.ts", + "import": "./dist/src/errors.js" + }, + "./events": { + "types": "./dist/src/events.d.ts", + "import": "./dist/src/events.js" + }, + "./startable": { + "types": "./dist/src/startable.d.ts", + "import": "./dist/src/startable.js" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/github", + "@semantic-release/git" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "dep-check": "aegir dep-check", + "build": "aegir build", + "release": "aegir release" + }, + "devDependencies": { + "aegir": "^39.0.5" + }, + "typedoc": { + "entryPoint": "./src/index.ts" + } +} diff --git a/packages/interfaces/src/errors.ts b/packages/interfaces/src/errors.ts new file mode 100644 index 0000000000..a25be515db --- /dev/null +++ b/packages/interfaces/src/errors.ts @@ -0,0 +1,35 @@ + +/** + * When this error is thrown it means an operation was aborted, + * usually in response to the `abort` event being emitted by an + * AbortSignal. + */ +export class AbortError extends Error { + public readonly code: string + public readonly type: string + + constructor (message: string = 'The operation was aborted') { + super(message) + this.code = AbortError.code + this.type = AbortError.type + } + + static readonly code = 'ABORT_ERR' + + static readonly type = 'aborted' +} + +export class CodeError = Record> extends Error { + public readonly props: T + + constructor ( + message: string, + public readonly code: string, + props?: T + ) { + super(message) + + this.name = props?.name ?? 'CodeError' + this.props = props ?? {} as T // eslint-disable-line @typescript-eslint/consistent-type-assertions + } +} diff --git a/packages/interfaces/src/events.ts b/packages/interfaces/src/events.ts new file mode 100644 index 0000000000..b92e51879e --- /dev/null +++ b/packages/interfaces/src/events.ts @@ -0,0 +1,101 @@ + +export interface EventCallback { (evt: EventType): void } +export interface EventObject { handleEvent: EventCallback } +export type EventHandler = EventCallback | EventObject + +interface Listener { + once: boolean + callback: any +} + +/** + * Adds types to the EventTarget class. Hopefully this won't be necessary forever. + * + * https://github.com/microsoft/TypeScript/issues/28357 + * https://github.com/microsoft/TypeScript/issues/43477 + * https://github.com/microsoft/TypeScript/issues/299 + * etc + */ +export class EventEmitter> extends EventTarget { + #listeners = new Map() + + listenerCount (type: string): number { + const listeners = this.#listeners.get(type) + + if (listeners == null) { + return 0 + } + + return listeners.length + } + + addEventListener(type: K, listener: EventHandler | null, options?: boolean | AddEventListenerOptions): void + addEventListener (type: string, listener: EventHandler, options?: boolean | AddEventListenerOptions): void { + super.addEventListener(type, listener, options) + + let list = this.#listeners.get(type) + + if (list == null) { + list = [] + this.#listeners.set(type, list) + } + + list.push({ + callback: listener, + once: (options !== true && options !== false && options?.once) ?? false + }) + } + + removeEventListener(type: K, listener?: EventHandler | null, options?: boolean | EventListenerOptions): void + removeEventListener (type: string, listener?: EventHandler, options?: boolean | EventListenerOptions): void { + super.removeEventListener(type.toString(), listener ?? null, options) + + let list = this.#listeners.get(type) + + if (list == null) { + return + } + + list = list.filter(({ callback }) => callback !== listener) + this.#listeners.set(type, list) + } + + dispatchEvent (event: Event): boolean { + const result = super.dispatchEvent(event) + + let list = this.#listeners.get(event.type) + + if (list == null) { + return result + } + + list = list.filter(({ once }) => !once) + this.#listeners.set(event.type, list) + + return result + } + + safeDispatchEvent(type: keyof EventMap, detail: CustomEventInit): boolean { + return this.dispatchEvent(new CustomEvent(type as string, detail)) + } +} + +/** + * CustomEvent is a standard event but it's not supported by node. + * + * Remove this when https://github.com/nodejs/node/issues/40678 is closed. + * + * Ref: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent + */ +class CustomEventPolyfill extends Event { + /** Returns any custom data event was created with. Typically used for synthetic events. */ + public detail: T + + constructor (message: string, data?: EventInit & { detail: T }) { + super(message, data) + // @ts-expect-error could be undefined + this.detail = data?.detail + } +} + +export const CustomEvent = globalThis.CustomEvent ?? CustomEventPolyfill diff --git a/packages/interfaces/src/index.ts b/packages/interfaces/src/index.ts new file mode 100644 index 0000000000..170a6ca762 --- /dev/null +++ b/packages/interfaces/src/index.ts @@ -0,0 +1,30 @@ + +/** + * An object that contains an AbortSignal as + * the optional `signal` property. + * + * @example + * + * ```js + * const controller = new AbortController() + * + * aLongRunningOperation({ + * signal: controller.signal + * }) + * + * // later + * + * controller.abort() + */ +export interface AbortOptions { + signal?: AbortSignal +} + +/** + * Returns a new type with all fields marked optional. + * + * Borrowed from the tsdef module. + */ +export type RecursivePartial = { + [P in keyof T]?: T[P] extends Array ? Array> : T[P] extends (...args: any[]) => any ? T[P] : RecursivePartial +} diff --git a/packages/interfaces/src/startable.ts b/packages/interfaces/src/startable.ts new file mode 100644 index 0000000000..5d9be74c9c --- /dev/null +++ b/packages/interfaces/src/startable.ts @@ -0,0 +1,117 @@ + +/** + * Implemented by components that have a lifecycle + */ +export interface Startable { + isStarted: () => boolean + + /** + * If implemented, this method will be invoked before the start method. + * + * It should not assume any other components have been started. + */ + beforeStart?: () => void | Promise + + /** + * This method will be invoked to start the component. + * + * It should not assume that any other components have been started. + */ + start: () => void | Promise + + /** + * If implemented, this method will be invoked after the start method. + * + * All other components will have had their start method invoked before this method is called. + */ + afterStart?: () => void | Promise + + /** + * If implemented, this method will be invoked before the stop method. + * + * Any other components will still be running when this method is called. + */ + beforeStop?: () => void | Promise + + /** + * This method will be invoked to stop the component. + * + * It should not assume any other components are running when it is called. + */ + stop: () => void | Promise + + /** + * If implemented, this method will be invoked after the stop method. + * + * All other components will have had their stop method invoked before this method is called. + */ + afterStop?: () => void | Promise +} + +export function isStartable (obj: any): obj is Startable { + return obj != null && typeof obj.start === 'function' && typeof obj.stop === 'function' +} + +export async function start (...objs: any[]): Promise { + const startables: Startable[] = [] + + for (const obj of objs) { + if (isStartable(obj)) { + startables.push(obj) + } + } + + await Promise.all( + startables.map(async s => { + if (s.beforeStart != null) { + await s.beforeStart() + } + }) + ) + + await Promise.all( + startables.map(async s => { + await s.start() + }) + ) + + await Promise.all( + startables.map(async s => { + if (s.afterStart != null) { + await s.afterStart() + } + }) + ) +} + +export async function stop (...objs: any[]): Promise { + const startables: Startable[] = [] + + for (const obj of objs) { + if (isStartable(obj)) { + startables.push(obj) + } + } + + await Promise.all( + startables.map(async s => { + if (s.beforeStop != null) { + await s.beforeStop() + } + }) + ) + + await Promise.all( + startables.map(async s => { + await s.stop() + }) + ) + + await Promise.all( + startables.map(async s => { + if (s.afterStop != null) { + await s.afterStop() + } + }) + ) +} diff --git a/packages/interfaces/tsconfig.json b/packages/interfaces/tsconfig.json new file mode 100644 index 0000000000..5fe8ea40d7 --- /dev/null +++ b/packages/interfaces/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src" + ] +} diff --git a/packages/libp2p/.aegir.js b/packages/libp2p/.aegir.js index d9c81e8028..21e54fde91 100644 --- a/packages/libp2p/.aegir.js +++ b/packages/libp2p/.aegir.js @@ -1,10 +1,4 @@ -import { webSockets } from '@libp2p/websockets' -import { mplex } from '@libp2p/mplex' -import { noise } from '@chainsafe/libp2p-noise' import { pipe } from 'it-pipe' -import { createEd25519PeerId } from '@libp2p/peer-id-factory' -import { yamux } from '@chainsafe/libp2p-yamux' -import { WebSockets } from '@multiformats/mafmt' /** @type {import('aegir').PartialOptions} */ export default { @@ -14,6 +8,12 @@ export default { test: { before: async () => { // use dynamic import because we only want to reference these files during the test run, e.g. after building + const { webSockets } = await import('@libp2p/websockets') + const { mplex } = await import('@libp2p/mplex') + const { noise } = await import('@chainsafe/libp2p-noise') + const { createEd25519PeerId } = await import('@libp2p/peer-id-factory') + const { yamux } = await import('@chainsafe/libp2p-yamux') + const { WebSockets } = await import('@multiformats/mafmt') const { createLibp2p } = await import('./dist/src/index.js') const { plaintext } = await import('./dist/src/insecure/index.js') const { circuitRelayServer, circuitRelayTransport } = await import('./dist/src/circuit-relay/index.js') diff --git a/packages/libp2p/package.json b/packages/libp2p/package.json index 602a2f370a..546978e727 100644 --- a/packages/libp2p/package.json +++ b/packages/libp2p/package.json @@ -3,7 +3,7 @@ "version": "0.45.9", "description": "JavaScript implementation of libp2p, a modular peer to peer network stack", "license": "Apache-2.0 OR MIT", - "homepage": "https://github.com/libp2p/js-libp2p#readme", + "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/libp2p#readme", "repository": { "type": "git", "url": "git+https://github.com/libp2p/js-libp2p.git" @@ -19,10 +19,6 @@ "peer", "peer-to-peer" ], - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - }, "type": "module", "types": "./dist/src/index.d.ts", "typesVersions": { @@ -72,10 +68,6 @@ "types": "./dist/src/insecure/index.d.ts", "import": "./dist/src/insecure/index.js" }, - "./upnp-nat": { - "types": "./dist/src/upnp-nat/index.d.ts", - "import": "./dist/src/upnp-nat/index.js" - }, "./ping": { "types": "./dist/src/ping/index.d.ts", "import": "./dist/src/ping/index.js" @@ -83,6 +75,10 @@ "./pnet": { "types": "./dist/src/pnet/index.d.ts", "import": "./dist/src/pnet/index.js" + }, + "./upnp-nat": { + "types": "./dist/src/upnp-nat/index.d.ts", + "import": "./dist/src/upnp-nat/index.js" } }, "eslintConfig": { @@ -121,29 +117,29 @@ "@achingbrain/nat-port-mapper": "^1.0.9", "@libp2p/crypto": "^1.0.17", "@libp2p/interface-address-manager": "^3.0.0", - "@libp2p/interface-connection": "^5.1.1", + "@libp2p/interface-connection": "^5.0.0", "@libp2p/interface-connection-encrypter": "^4.0.0", "@libp2p/interface-connection-gater": "^3.0.0", "@libp2p/interface-connection-manager": "^3.0.0", - "@libp2p/interface-content-routing": "^2.1.0", - "@libp2p/interface-keychain": "^2.0.4", - "@libp2p/interface-libp2p": "^3.2.0", + "@libp2p/interface-content-routing": "^2.0.0", + "@libp2p/interface-keychain": "^2.0.0", + "@libp2p/interface-libp2p": "^3.0.0", "@libp2p/interface-metrics": "^4.0.0", "@libp2p/interface-peer-discovery": "^2.0.0", - "@libp2p/interface-peer-id": "^2.0.1", - "@libp2p/interface-peer-info": "^1.0.3", - "@libp2p/interface-peer-routing": "^1.1.0", - "@libp2p/interface-peer-store": "^2.0.4", + "@libp2p/interface-peer-id": "^2.0.0", + "@libp2p/interface-peer-info": "^1.0.0", + "@libp2p/interface-peer-routing": "^1.0.0", + "@libp2p/interface-peer-store": "^2.0.0", "@libp2p/interface-pubsub": "^4.0.0", - "@libp2p/interface-record": "^2.0.6", - "@libp2p/interface-registrar": "^2.0.3", + "@libp2p/interface-record": "^2.0.0", + "@libp2p/interface-registrar": "^2.0.0", "@libp2p/interface-stream-muxer": "^4.0.0", "@libp2p/interface-transport": "^4.0.0", - "@libp2p/interfaces": "^3.2.0", + "@libp2p/interfaces": "^3.0.0", "@libp2p/keychain": "^2.0.0", "@libp2p/logger": "^2.1.1", "@libp2p/multistream-select": "^3.1.8", - "@libp2p/peer-collections": "^3.0.0", + "@libp2p/peer-collections": "^3.0.1", "@libp2p/peer-id": "^2.0.0", "@libp2p/peer-id-factory": "^2.0.0", "@libp2p/peer-record": "^5.0.0", @@ -178,7 +174,7 @@ "private-ip": "^3.0.0", "protons-runtime": "^5.0.0", "rate-limiter-flexible": "^2.3.11", - "uint8arraylist": "^2.3.2", + "uint8arraylist": "^2.4.3", "uint8arrays": "^4.0.2", "wherearewe": "^2.0.0", "xsalsa20": "^1.1.0" @@ -191,8 +187,8 @@ "@libp2p/daemon-client": "^6.0.2", "@libp2p/daemon-server": "^5.0.2", "@libp2p/floodsub": "^7.0.1", - "@libp2p/interface-compliance-tests": "^3.0.6", - "@libp2p/interface-connection-compliance-tests": "^2.0.8", + "@libp2p/interface-compliance-tests": "^3.0.0", + "@libp2p/interface-connection-compliance-tests": "^2.0.0", "@libp2p/interface-connection-encrypter-compliance-tests": "^5.0.0", "@libp2p/interface-mocks": "^12.0.0", "@libp2p/interop": "^8.0.0", diff --git a/packages/libp2p/tsconfig.json b/packages/libp2p/tsconfig.json index 13a3599639..9ac0d9429c 100644 --- a/packages/libp2p/tsconfig.json +++ b/packages/libp2p/tsconfig.json @@ -6,5 +6,79 @@ "include": [ "src", "test" + ], + "references": [ + { + "path": "../interface-address-manager" + }, + { + "path": "../interface-compliance-tests" + }, + { + "path": "../interface-connection" + }, + { + "path": "../interface-connection-compliance-tests" + }, + { + "path": "../interface-connection-encrypter" + }, + { + "path": "../interface-connection-encrypter-compliance-tests" + }, + { + "path": "../interface-connection-gater" + }, + { + "path": "../interface-connection-manager" + }, + { + "path": "../interface-content-routing" + }, + { + "path": "../interface-keychain" + }, + { + "path": "../interface-libp2p" + }, + { + "path": "../interface-metrics" + }, + { + "path": "../interface-mocks" + }, + { + "path": "../interface-peer-discovery" + }, + { + "path": "../interface-peer-id" + }, + { + "path": "../interface-peer-info" + }, + { + "path": "../interface-peer-routing" + }, + { + "path": "../interface-peer-store" + }, + { + "path": "../interface-pubsub" + }, + { + "path": "../interface-record" + }, + { + "path": "../interface-registrar" + }, + { + "path": "../interface-stream-muxer" + }, + { + "path": "../interface-transport" + }, + { + "path": "../interfaces" + } ] }