├── .aegir.js
├── .github
├── dependabot.yml
├── pull_request_template.md
└── workflows
│ ├── generated-pr.yml
│ ├── js-test-and-release.yml
│ ├── semantic-pull-request.yml
│ └── stale.yml
├── .gitignore
├── CHANGELOG.md
├── CODEOWNERS
├── LICENSE
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── package.json
├── src
└── index.ts
├── test
└── index.spec.ts
├── tsconfig.json
└── typedoc.json
/.aegir.js:
--------------------------------------------------------------------------------
1 | import { createServer } from 'ipfsd-ctl'
2 | import * as ipfsHttpModule from 'kubo-rpc-client'
3 | import goIpfsModule from 'kubo'
4 |
5 | let server
6 |
7 | export default {
8 | test: {
9 | before: async () => {
10 | server = createServer({
11 | host: '127.0.0.1',
12 | port: 57583
13 | }, {
14 | type: 'go',
15 | ipfsHttpModule,
16 | ipfsBin: goIpfsModule.path(),
17 | test: true
18 | })
19 |
20 | await server.start()
21 | },
22 | after: () => server.stop()
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "10:00"
8 | open-pull-requests-limit: 10
9 | commit-message:
10 | prefix: "deps"
11 | prefix-development: "deps(dev)"
12 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Title
2 |
8 |
9 | ## Description
10 |
11 |
17 |
18 | ## Notes & open questions
19 |
20 |
23 |
24 | ## Change checklist
25 |
26 | - [ ] I have performed a self-review of my own code
27 | - [ ] I have made corresponding changes to the documentation if necessary (this includes comments as well)
28 | - [ ] I have added tests that prove my fix is effective or that my feature works
--------------------------------------------------------------------------------
/.github/workflows/generated-pr.yml:
--------------------------------------------------------------------------------
1 | name: Close Generated PRs
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *'
6 | workflow_dispatch:
7 |
8 | permissions:
9 | issues: write
10 | pull-requests: write
11 |
12 | jobs:
13 | stale:
14 | uses: ipdxco/unified-github-workflows/.github/workflows/reusable-generated-pr.yml@v1
15 |
--------------------------------------------------------------------------------
/.github/workflows/js-test-and-release.yml:
--------------------------------------------------------------------------------
1 | name: test & maybe release
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | workflow_dispatch:
9 |
10 | permissions:
11 | contents: write
12 | id-token: write
13 | packages: write
14 | pull-requests: write
15 |
16 | concurrency:
17 | group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | js-test-and-release:
22 | uses: ipdxco/unified-github-workflows/.github/workflows/js-test-and-release.yml@v1.0
23 | secrets:
24 | DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
25 | DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
26 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
27 | UCI_GITHUB_TOKEN: ${{ secrets.UCI_GITHUB_TOKEN }}
28 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
29 |
--------------------------------------------------------------------------------
/.github/workflows/semantic-pull-request.yml:
--------------------------------------------------------------------------------
1 | name: Semantic PR
2 |
3 | on:
4 | pull_request_target:
5 | types:
6 | - opened
7 | - edited
8 | - synchronize
9 |
10 | jobs:
11 | main:
12 | uses: ipdxco/unified-github-workflows/.github/workflows/reusable-semantic-pull-request.yml@v1
13 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Close Stale Issues
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *'
6 | workflow_dispatch:
7 |
8 | permissions:
9 | issues: write
10 | pull-requests: write
11 |
12 | jobs:
13 | stale:
14 | uses: ipdxco/unified-github-workflows/.github/workflows/reusable-stale-issue.yml@v1
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | dist
4 | .docs
5 | .coverage
6 | node_modules
7 | package-lock.json
8 | yarn.lock
9 | .vscode
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [4.0.14](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.13...v4.0.14) (2023-10-09)
2 |
3 |
4 | ### Dependencies
5 |
6 | * swap go-ipfs for kubo ([#154](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/154)) ([0e3ca6c](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/0e3ca6cc057caf87911d4be4467fc31e9698559c))
7 |
8 | ## [4.0.13](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.12...v4.0.13) (2023-10-06)
9 |
10 |
11 | ### Trivial Changes
12 |
13 | * add missing dep ([ba7f237](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/ba7f23742998980231f6be4bb885979f9bab1059))
14 | * Update .github/pull_request_template.md [skip ci] ([7ec087a](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/7ec087a24013a4406393efee09c8385c976ff6c6))
15 | * update config ([4095e1d](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/4095e1d0efb563f27d1fae1df6ef9bfe3011fcdc))
16 |
17 |
18 | ### Dependencies
19 |
20 | * **dev:** bump aegir from 39.0.13 to 40.0.8 ([#149](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/149)) ([2b97412](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/2b97412c2eeb080732434008d61cf38d6163ec37))
21 |
22 | ## [4.0.12](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.11...v4.0.12) (2023-08-30)
23 |
24 |
25 | ### Dependencies
26 |
27 | * upgrade all deps ([#153](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/153)) ([6835c29](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/6835c292721de83cc43ad9c0279550ce7b8063e1))
28 |
29 | ## [4.0.11](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.10...v4.0.11) (2023-08-24)
30 |
31 |
32 | ### Trivial Changes
33 |
34 | * add or force update .github/workflows/js-test-and-release.yml ([#152](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/152)) ([fbd004f](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/fbd004f7bd8f51d0db1ca408fdfcec65096a603c))
35 | * delete templates [skip ci] ([#151](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/151)) ([4f1dd24](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/4f1dd24d66ee781b826ee7ad5be0262b88f8ba4a))
36 | * Update CODEOWNERS [skip ci] ([61f7181](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/61f7181c499943a0bd8eb429f462982fcc19e6e7))
37 |
38 |
39 | ### Dependencies
40 |
41 | * bump multiformats from 11.0.2 to 12.0.1 ([#141](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/141)) ([09e2564](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/09e2564c97c4599526383928309b0968e07255d8))
42 |
43 | ## [4.0.10](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.9...v4.0.10) (2023-08-01)
44 |
45 |
46 | ### Dependencies
47 |
48 | * bump @libp2p/logger from 2.1.1 to 3.0.0 ([#146](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/146)) ([92d5157](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/92d51573fd6e9adfa30b03c49b1cf03b40987426))
49 | * bump @libp2p/peer-id from 2.0.4 to 3.0.0 ([#147](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/147)) ([a973107](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/a973107981bf3bb255b9937e4b773bd8f066d437))
50 | * **dev:** bump @libp2p/peer-id-factory from 2.0.4 to 3.0.0 ([#148](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/148)) ([9cc56e0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/9cc56e0b5374336e3702f41ef9e513e54a4dbae8))
51 |
52 | ## [4.0.9](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.8...v4.0.9) (2023-07-03)
53 |
54 |
55 | ### Trivial Changes
56 |
57 | * Update .github/workflows/semantic-pull-request.yml [skip ci] ([c8a44d6](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/c8a44d67250fa8a7a4dfa70e5010bfb4c7dcb077))
58 | * Update .github/workflows/stale.yml [skip ci] ([dca049c](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/dca049c2b20f6dfbef273d42f2c525a0f8ba6ddf))
59 | * Update .github/workflows/stale.yml [skip ci] ([b97c54f](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/b97c54f2dd9b9543812e409c4f14f3882273e99f))
60 |
61 |
62 | ### Dependencies
63 |
64 | * **dev:** bump go-ipfs from 0.20.0 to 0.21.0 ([#142](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/142)) ([6d6e445](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/6d6e445bd43a0ea6db0b0d6eccba8be6d11a2176))
65 |
66 | ## [4.0.8](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.7...v4.0.8) (2023-05-31)
67 |
68 |
69 | ### Dependencies
70 |
71 | * swap ipfs-http-client for kubo-rpc-client ([#140](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/140)) ([0f3e0a3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/0f3e0a380b0dfec0395283ad49030a03399ae645))
72 |
73 | ## [4.0.7](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.6...v4.0.7) (2023-05-31)
74 |
75 |
76 | ### Dependencies
77 |
78 | * **dev:** bump aegir from 38.1.8 to 39.0.9 ([#139](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/139)) ([797c287](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/797c287d54cea3226debcdbd196a7d5e17641b1f))
79 | * **dev:** bump it-drain from 2.0.1 to 3.0.2 ([#135](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/135)) ([9933748](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/993374867a6a9b189bfb23abc4ba5851528b59b7))
80 |
81 | ## [4.0.6](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.5...v4.0.6) (2023-05-05)
82 |
83 |
84 | ### Bug Fixes
85 |
86 | * remove use of timeout-abort-controller ([#129](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/129)) ([2fbde9a](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/2fbde9a1d297948fee320eeda4f4b0c53d3e75f0))
87 |
88 | ## [4.0.5](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.4...v4.0.5) (2023-03-31)
89 |
90 |
91 | ### Dependencies
92 |
93 | * **dev:** bump it-all from 2.0.1 to 3.0.1 ([#124](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/124)) ([8d41444](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/8d4144478f566f85ab64f9054ca0f378025a23c9))
94 |
95 | ## [4.0.4](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.3...v4.0.4) (2023-03-22)
96 |
97 |
98 | ### Bug Fixes
99 |
100 | * replace err-code with CodeError ([#122](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/122)) ([a02a0ce](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/a02a0cea483acbfccf6fbb2399d5dff03dfb5a8e))
101 |
102 | ## [4.0.3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.2...v4.0.3) (2023-03-21)
103 |
104 |
105 | ### Bug Fixes
106 |
107 | * **debug-logs:** use 'libp2p:' namespace ([#121](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/121)) ([a3e085e](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/a3e085e113ddcf032ae7a4a61f6fdd7fb95cebd2))
108 |
109 | ## [4.0.2](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.1...v4.0.2) (2023-03-20)
110 |
111 |
112 | ### Dependencies
113 |
114 | * **dev:** bump ipfsd-ctl from 12.2.2 to 13.0.0 ([#104](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/104)) ([9221778](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/9221778669ed0b926d85a745e3a3adaf9e64ed24))
115 |
116 | ## [4.0.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v4.0.0...v4.0.1) (2023-03-16)
117 |
118 |
119 | ### Trivial Changes
120 |
121 | * Update .github/workflows/semantic-pull-request.yml [skip ci] ([b0f81bf](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/b0f81bf27e440b3420d8516c41156c527d8d8c78))
122 | * Update .github/workflows/semantic-pull-request.yml [skip ci] ([c89a5e1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/c89a5e14ac5d7fb433d68aa6df36c84fc6f4a4be))
123 | * Update .github/workflows/semantic-pull-request.yml [skip ci] ([dc5e6d9](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/dc5e6d9b06a1ffba4d787bd8f0c96a6b0a755e62))
124 | * upgrade aegir to `38.1.2` ([#109](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/109)) ([17e7928](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/17e79283b9a50bdee6d6f15405299a7e2cd1bac1))
125 |
126 |
127 | ### Documentation
128 |
129 | * Update README.md ([#117](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/117)) ([2662c50](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/2662c50eee8f58fedbae281b6494b9352a14498a))
130 |
131 | ## [4.0.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v3.0.1...v4.0.0) (2023-01-06)
132 |
133 |
134 | ### ⚠ BREAKING CHANGES
135 |
136 | * update multiformats to v11 (#101)
137 |
138 | ### Bug Fixes
139 |
140 | * update multiformats to v11 ([#101](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/101)) ([c924389](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/c924389f7a0156978497e6b293c9c2dc39885be0))
141 |
142 | ## [3.0.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v3.0.0...v3.0.1) (2022-12-19)
143 |
144 |
145 | ### Documentation
146 |
147 | * publish api docs ([#99](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/99)) ([5bd7679](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/5bd7679865a0dd14412ad50a5180798a27dc41c3))
148 |
149 | ## [3.0.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v2.0.2...v3.0.0) (2022-10-13)
150 |
151 |
152 | ### ⚠ BREAKING CHANGES
153 |
154 | * modules no longer implement `Initializable` instead switching to constructor injection
155 |
156 | ### Bug Fixes
157 |
158 | * remove @libp2p/components ([#90](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/90)) ([a3816b1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/a3816b1da57ffcee5e378271d70778f62aa90402))
159 |
160 |
161 | ### Trivial Changes
162 |
163 | * Update .github/workflows/stale.yml [skip ci] ([4f472d3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/4f472d30506ea297500859481e75db993bce2a82))
164 |
165 | ## [2.0.2](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v2.0.1...v2.0.2) (2022-09-07)
166 |
167 |
168 | ### Dependencies
169 |
170 | * update all ipfs related deps ([#87](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/87)) ([0f4b87f](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/0f4b87fe00471d62988d94f8026555d2b0377dc0))
171 |
172 | ## [2.0.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v2.0.0...v2.0.1) (2022-06-15)
173 |
174 |
175 | ### Trivial Changes
176 |
177 | * update deps ([#77](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/77)) ([d982ab9](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/d982ab96db013e5b752ff04dedcb8201fb00c5fc))
178 |
179 | ## [2.0.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v1.0.5...v2.0.0) (2022-06-15)
180 |
181 |
182 | ### ⚠ BREAKING CHANGES
183 |
184 | * uses new single-issue libp2p interface modules
185 |
186 | ### Features
187 |
188 | * update to latest libp2p interfaces ([#76](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/76)) ([413ebe9](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/413ebe96ce6c64e2fc0daac6de4cf5c08ab844ad))
189 |
190 | ### [1.0.5](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v1.0.4...v1.0.5) (2022-06-06)
191 |
192 |
193 | ### Bug Fixes
194 |
195 | * update ipfs-http-client ([#72](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/72)) ([5998f1c](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/5998f1cb5bfe810fb7fed6fb7362f5e8b551ce45))
196 |
197 | ### [1.0.4](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v1.0.3...v1.0.4) (2022-05-23)
198 |
199 |
200 | ### Trivial Changes
201 |
202 | * **deps:** bump @libp2p/interfaces from 1.3.32 to 2.0.1 ([#70](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/70)) ([ebd8b76](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/ebd8b76c9177c0d14e8756f7cedb7c425ec349fb))
203 |
204 | ### [1.0.3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v1.0.2...v1.0.3) (2022-05-11)
205 |
206 |
207 | ### Bug Fixes
208 |
209 | * abort in flight requests when shutting down ([#68](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/68)) ([31c5db6](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/31c5db667e70dd17751fb26f39bd58f4ca3db89c))
210 |
211 | ### [1.0.2](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v1.0.1...v1.0.2) (2022-03-24)
212 |
213 |
214 | ### Bug Fixes
215 |
216 | * update interfaces ([#60](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/60)) ([f494708](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/f494708df5d75c0af6e85591e2481c4a1ab4794b))
217 |
218 | ### [1.0.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v1.0.0...v1.0.1) (2022-03-16)
219 |
220 |
221 | ### Bug Fixes
222 |
223 | * update interfaces ([#59](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/59)) ([67e8ae3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/67e8ae3c1adae5b4833b514f38e16f54439dab75))
224 |
225 | ## [1.0.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.11.1...v1.0.0) (2022-03-04)
226 |
227 |
228 | ### ⚠ BREAKING CHANGES
229 |
230 | * switch to named exports, ESM only
231 |
232 | ### Features
233 |
234 | * convert to typescript ([#58](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/58)) ([3013bf8](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/3013bf8c733f23ce08c98c4faad94d8b8bcd63cd))
235 |
236 | ## [0.11.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.11.0...v0.11.1) (2021-12-07)
237 |
238 |
239 | ### Bug Fixes
240 |
241 | * yield closer peers as they arrive ([#51](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/51)) ([1892785](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/1892785d70a5d709aac66f2494f79e7768a2b7c4))
242 |
243 |
244 |
245 | # [0.11.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.10.0...v0.11.0) (2021-12-02)
246 |
247 |
248 | ### chore
249 |
250 | * update peer-id dep ([#47](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/47)) ([1664f69](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/1664f69b7234e8bc41dc6641ebd70fb8fa1b0129))
251 |
252 |
253 | ### BREAKING CHANGES
254 |
255 | * requires node 15
256 |
257 |
258 |
259 | # [0.10.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.9.0...v0.10.0) (2021-07-07)
260 |
261 |
262 | ### chore
263 |
264 | * update to new multiformats ([#46](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/46)) ([44cd293](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/44cd2933b705285cc5081e7469ddc3c137a539dc))
265 |
266 |
267 | ### BREAKING CHANGES
268 |
269 | * uses the CID class from the new multiformats module
270 |
271 |
272 |
273 | # [0.9.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.8.1...v0.9.0) (2021-04-09)
274 |
275 |
276 |
277 | ## [0.8.2](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.8.1...v0.8.2) (2020-11-30)
278 |
279 |
280 |
281 | ## [0.8.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.4.0...v0.8.1) (2020-11-27)
282 |
283 |
284 | ### Bug Fixes
285 |
286 | * accept http client instance ([#39](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/39)) ([bd9ecc3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/bd9ecc311e87604d489cae5e832691bd1dec7429))
287 |
288 |
289 | ### chore
290 |
291 | * make ipfs-http-client a peer dependency ([#32](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/32)) ([a1b1b5e](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/a1b1b5ec59af97f5ab708c757808940dbcb070d9))
292 | * remove-peer-info-from-api ([#25](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/25)) ([f49ddc0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/f49ddc0740963587fc0976c2a627f241bd045abf))
293 |
294 |
295 | ### Features
296 |
297 | * add support for api dht/query endpoint ([#37](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/37)) ([6fa569c](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/6fa569cdaaeca3ca200af8b3c10b2a098faff5c1))
298 |
299 |
300 | ### BREAKING CHANGES
301 |
302 | * The ipfs-http-client must now be installed
303 | as a peer dependency. It is no longer included as a dependency
304 | of this module.
305 |
306 | The reason the http-client should be a peerDependency and
307 | not a dependency is that its API requires knowledge of the
308 | http-client (we pass in the api endpoint details).
309 | * findPeer returns id and addrs properties instead of peer-info instance
310 |
311 | * chore: address review
312 |
313 |
314 |
315 | # [0.8.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.7.0...v0.8.0) (2020-10-21)
316 |
317 |
318 |
319 |
320 | # [0.7.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.6.1...v0.7.0) (2020-08-26)
321 |
322 |
323 | ### Bug Fixes
324 |
325 | * accept http client instance ([#39](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/39)) ([bd9ecc3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/bd9ecc3))
326 |
327 |
328 |
329 |
330 | ## [0.6.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.6.0...v0.6.1) (2020-08-14)
331 |
332 |
333 | ### Features
334 |
335 | * add support for api dht/query endpoint ([#37](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/37)) ([6fa569c](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/6fa569c))
336 |
337 |
338 |
339 |
340 | # [0.6.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.5.0...v0.6.0) (2020-08-12)
341 |
342 |
343 |
344 |
345 | # [0.5.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.4.3...v0.5.0) (2020-04-23)
346 |
347 |
348 | ### Chores
349 |
350 | * make ipfs-http-client a peer dependency ([#32](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/32)) ([a1b1b5e](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/a1b1b5e))
351 | * remove-peer-info-from-api ([#25](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/25)) ([f49ddc0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/f49ddc0))
352 |
353 |
354 | ### BREAKING CHANGES
355 |
356 | * The ipfs-http-client must now be installed
357 | as a peer dependency. It is no longer included as a dependency
358 | of this module.
359 |
360 | The reason the http-client should be a peerDependency and
361 | not a dependency is that its API requires knowledge of the
362 | http-client (we pass in the api endpoint details).
363 | * findPeer returns id and addrs properties instead of peer-info instance
364 |
365 | * chore: address review
366 |
367 |
368 |
369 |
370 | ## [0.4.3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.4.2...v0.4.3) (2020-04-16)
371 |
372 |
373 |
374 |
375 | ## [0.4.2](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.4.1...v0.4.2) (2020-04-09)
376 |
377 |
378 |
379 |
380 | ## [0.4.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.4.0...v0.4.1) (2020-02-04)
381 |
382 |
383 |
384 |
385 | # [0.4.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.3.1...v0.4.0) (2019-11-29)
386 |
387 |
388 | ### Chores
389 |
390 | * rename timeout option ([#14](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/14)) ([36d852f](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/36d852f))
391 |
392 |
393 | ### BREAKING CHANGES
394 |
395 | * maxTimeout option renamed to timeout
396 |
397 |
398 |
399 |
400 | ## [0.3.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.3.0...v0.3.1) (2019-07-24)
401 |
402 |
403 | ### Bug Fixes
404 |
405 | * limit concurrent HTTP requests ([#12](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/12)) ([e844d30](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/e844d30))
406 |
407 |
408 |
409 |
410 | # [0.3.0](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.2.3...v0.3.0) (2019-07-12)
411 |
412 |
413 | ### Features
414 |
415 | * refactor to use async/await ([#8](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/8)) ([1827328](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/1827328))
416 |
417 |
418 | ### BREAKING CHANGES
419 |
420 | * API refactored to use async/await
421 |
422 | Also upgrades all the deps, moves from `ipfs-api` to `ipfs-http-client`
423 | and removes a lot of results massaging that is now done in the
424 | http client.
425 |
426 |
427 |
428 |
429 | ## [0.2.3](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.2.2...v0.2.3) (2019-07-10)
430 |
431 |
432 |
433 |
434 | ## [0.2.2](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.2.1...v0.2.2) (2018-09-27)
435 |
436 |
437 | ### Features
438 |
439 | * add timeout defaults ([#6](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/6)) ([2909585](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/2909585))
440 |
441 |
442 |
443 |
444 | ## [0.2.1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/compare/v0.2.0...v0.2.1) (2018-08-30)
445 |
446 |
447 | ### Bug Fixes
448 |
449 | * better support for peer ids ([#5](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/5)) ([60655a9](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/60655a9))
450 |
451 |
452 |
453 |
454 | # 0.2.0 (2018-08-23)
455 |
456 |
457 | ### Bug Fixes
458 |
459 | * Syntax highlighting on README ([67fb497](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/67fb497))
460 |
461 |
462 | ### Features
463 |
464 | * initial implementation ([#1](https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues/1)) ([7fd93ae](https://github.com/libp2p/js-libp2p-delegated-peer-routing/commit/7fd93ae))
465 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @libp2p/js-libp2p-dev
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This project is dual licensed under MIT and Apache-2.0.
2 |
3 | MIT: https://www.opensource.org/licenses/mit
4 | Apache-2.0: https://www.apache.org/licenses/license-2.0
5 |
--------------------------------------------------------------------------------
/LICENSE-APACHE:
--------------------------------------------------------------------------------
1 | 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
2 |
3 | http://www.apache.org/licenses/LICENSE-2.0
4 |
5 | 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.
6 |
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @libp2p/delegated-peer-routing
2 |
3 | [](http://libp2p.io/)
4 | [](https://discuss.libp2p.io)
5 | [](https://codecov.io/gh/libp2p/js-libp2p-delegated-peer-routing)
6 | [](https://github.com/libp2p/js-libp2p-delegated-peer-routing/actions/workflows/js-test-and-release.yml?query=branch%3Amaster)
7 |
8 | > Leverage other peers in the libp2p network to perform Peer Routing calls.
9 |
10 | ## Table of contents
11 |
12 | - [Install](#install)
13 | - [Browser `
32 | ```
33 |
34 | Leverage other peers in the network to perform Peer Routing calls.
35 |
36 | Requires access to `/api/v0/dht/findpeer` and `/api/v0/dht/query` HTTP API endpoints of the delegate node.
37 |
38 | ## Requirements
39 |
40 | `libp2p-delegated-peer-routing` leverages the `kubo-rpc-client` library and requires an instance of it as a constructor argument.
41 |
42 | ```sh
43 | npm install kubo-rpc-client libp2p-delegated-peer-routing
44 | ```
45 |
46 | ## Example
47 |
48 | ```js
49 | import { createLibp2p } from 'libp2p'
50 | import { delegatedPeerRouting } from '@libp2p/delegated-peer-routing'
51 | import { create as kuboClient } from 'kubo-rpc-client'
52 |
53 | // default is to use ipfs.io
54 | const client = kuboClient({
55 | // use default api settings
56 | protocol: 'https',
57 | port: 443,
58 | host: 'node0.delegate.ipfs.io'
59 | })
60 |
61 | const node = await createLibp2p({
62 | peerRouters: [
63 | delegatedPeerRouting(client)
64 | ]
65 | //.. other config
66 | })
67 | await node.start()
68 |
69 | const peerInfo = await node.peerRouting.findPeer('peerid')
70 | console.log('peerInfo', peerInfo)
71 | ```
72 |
73 | ## API Docs
74 |
75 | -
76 |
77 | ## License
78 |
79 | Licensed under either of
80 |
81 | - Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / )
82 | - MIT ([LICENSE-MIT](LICENSE-MIT) / )
83 |
84 | ## Contribution
85 |
86 | 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.
87 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@libp2p/delegated-peer-routing",
3 | "version": "4.0.14",
4 | "description": "Leverage other peers in the libp2p network to perform Peer Routing calls.",
5 | "license": "Apache-2.0 OR MIT",
6 | "homepage": "https://github.com/libp2p/js-libp2p-delegated-peer-routing#readme",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/libp2p/js-libp2p-delegated-peer-routing.git"
10 | },
11 | "bugs": {
12 | "url": "https://github.com/libp2p/js-libp2p-delegated-peer-routing/issues"
13 | },
14 | "type": "module",
15 | "types": "./dist/src/index.d.ts",
16 | "files": [
17 | "src",
18 | "dist",
19 | "!dist/test",
20 | "!**/*.tsbuildinfo"
21 | ],
22 | "exports": {
23 | ".": {
24 | "types": "./src/index.d.ts",
25 | "import": "./dist/src/index.js"
26 | }
27 | },
28 | "eslintConfig": {
29 | "extends": "ipfs",
30 | "parserOptions": {
31 | "project": true,
32 | "sourceType": "module"
33 | }
34 | },
35 | "release": {
36 | "branches": [
37 | "master"
38 | ],
39 | "plugins": [
40 | [
41 | "@semantic-release/commit-analyzer",
42 | {
43 | "preset": "conventionalcommits",
44 | "releaseRules": [
45 | {
46 | "breaking": true,
47 | "release": "major"
48 | },
49 | {
50 | "revert": true,
51 | "release": "patch"
52 | },
53 | {
54 | "type": "feat",
55 | "release": "minor"
56 | },
57 | {
58 | "type": "fix",
59 | "release": "patch"
60 | },
61 | {
62 | "type": "docs",
63 | "release": "patch"
64 | },
65 | {
66 | "type": "test",
67 | "release": "patch"
68 | },
69 | {
70 | "type": "deps",
71 | "release": "patch"
72 | },
73 | {
74 | "scope": "no-release",
75 | "release": false
76 | }
77 | ]
78 | }
79 | ],
80 | [
81 | "@semantic-release/release-notes-generator",
82 | {
83 | "preset": "conventionalcommits",
84 | "presetConfig": {
85 | "types": [
86 | {
87 | "type": "feat",
88 | "section": "Features"
89 | },
90 | {
91 | "type": "fix",
92 | "section": "Bug Fixes"
93 | },
94 | {
95 | "type": "chore",
96 | "section": "Trivial Changes"
97 | },
98 | {
99 | "type": "docs",
100 | "section": "Documentation"
101 | },
102 | {
103 | "type": "deps",
104 | "section": "Dependencies"
105 | },
106 | {
107 | "type": "test",
108 | "section": "Tests"
109 | }
110 | ]
111 | }
112 | }
113 | ],
114 | "@semantic-release/changelog",
115 | "@semantic-release/npm",
116 | "@semantic-release/github",
117 | "@semantic-release/git"
118 | ]
119 | },
120 | "scripts": {
121 | "clean": "aegir clean",
122 | "lint": "aegir lint",
123 | "dep-check": "aegir dep-check",
124 | "build": "aegir build",
125 | "test": "aegir test",
126 | "test:chrome": "aegir test -t browser --cov",
127 | "test:chrome-webworker": "aegir test -t webworker",
128 | "test:firefox": "aegir test -t browser -- --browser firefox",
129 | "test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
130 | "test:node": "aegir test -t node --cov",
131 | "test:electron-main": "aegir test -t electron-main",
132 | "release": "aegir release",
133 | "docs": "aegir docs"
134 | },
135 | "dependencies": {
136 | "@libp2p/interface-peer-id": "^2.0.2",
137 | "@libp2p/interface-peer-info": "^1.0.10",
138 | "@libp2p/interface-peer-routing": "^1.1.1",
139 | "@libp2p/interfaces": "^3.3.2",
140 | "@libp2p/logger": "^3.0.2",
141 | "@libp2p/peer-id": "^3.0.2",
142 | "any-signal": "^4.1.1",
143 | "ipfs-core-types": "^0.14.1",
144 | "multiformats": "^12.1.2",
145 | "p-defer": "^4.0.0",
146 | "p-queue": "^7.3.4"
147 | },
148 | "devDependencies": {
149 | "@libp2p/peer-id-factory": "^3.0.3",
150 | "aegir": "^41.0.3",
151 | "ipfsd-ctl": "^13.0.0",
152 | "it-all": "^3.0.3",
153 | "it-drain": "^3.0.3",
154 | "kubo": "^0.23.0",
155 | "kubo-rpc-client": "^3.0.1",
156 | "uint8arrays": "^4.0.6",
157 | "wherearewe": "^2.0.1"
158 | },
159 | "browser": {
160 | "kubo": false
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { CodeError } from '@libp2p/interfaces/errors'
2 | import { logger } from '@libp2p/logger'
3 | import { peerIdFromBytes } from '@libp2p/peer-id'
4 | import { anySignal } from 'any-signal'
5 | import { CID } from 'multiformats/cid'
6 | import defer from 'p-defer'
7 | import PQueue from 'p-queue'
8 | import type { PeerId } from '@libp2p/interface-peer-id'
9 | import type { PeerInfo } from '@libp2p/interface-peer-info'
10 | import type { PeerRouting } from '@libp2p/interface-peer-routing'
11 | import type { Startable } from '@libp2p/interfaces/startable'
12 | import type { AbortOptions } from 'ipfs-core-types/src/utils'
13 |
14 | const log = logger('libp2p:delegated-peer-routing')
15 |
16 | const DEFAULT_TIMEOUT = 30e3 // 30 second default
17 | const CONCURRENT_HTTP_REQUESTS = 4
18 |
19 | export interface HTTPClientExtraOptions {
20 | headers?: Record
21 | searchParams?: URLSearchParams
22 | }
23 |
24 | export enum EventTypes {
25 | SENDING_QUERY = 0,
26 | PEER_RESPONSE,
27 | FINAL_PEER,
28 | QUERY_ERROR,
29 | PROVIDER,
30 | VALUE,
31 | ADDING_PEER,
32 | DIALING_PEER
33 | }
34 |
35 | /**
36 | * The types of messages set/received during DHT queries
37 | */
38 | export enum MessageType {
39 | PUT_VALUE = 0,
40 | GET_VALUE,
41 | ADD_PROVIDER,
42 | GET_PROVIDERS,
43 | FIND_NODE,
44 | PING
45 | }
46 |
47 | export type MessageName = keyof typeof MessageType
48 |
49 | export interface DHTRecord {
50 | key: Uint8Array
51 | value: Uint8Array
52 | timeReceived?: Date
53 | }
54 |
55 | export interface SendingQueryEvent {
56 | type: EventTypes.SENDING_QUERY
57 | name: 'SENDING_QUERY'
58 | }
59 |
60 | export interface PeerResponseEvent {
61 | from: PeerId
62 | type: EventTypes.PEER_RESPONSE
63 | name: 'PEER_RESPONSE'
64 | messageType: MessageType
65 | messageName: MessageName
66 | providers: PeerInfo[]
67 | closer: PeerInfo[]
68 | record?: DHTRecord
69 | }
70 |
71 | export interface FinalPeerEvent {
72 | peer: PeerInfo
73 | type: EventTypes.FINAL_PEER
74 | name: 'FINAL_PEER'
75 | }
76 |
77 | export interface QueryErrorEvent {
78 | type: EventTypes.QUERY_ERROR
79 | name: 'QUERY_ERROR'
80 | error: Error
81 | }
82 |
83 | export interface ProviderEvent {
84 | type: EventTypes.PROVIDER
85 | name: 'PROVIDER'
86 | providers: PeerInfo[]
87 | }
88 |
89 | export interface ValueEvent {
90 | type: EventTypes.VALUE
91 | name: 'VALUE'
92 | value: Uint8Array
93 | }
94 |
95 | export interface AddingPeerEvent {
96 | type: EventTypes.ADDING_PEER
97 | name: 'ADDING_PEER'
98 | peer: PeerId
99 | }
100 |
101 | export interface DialingPeerEvent {
102 | peer: PeerId
103 | type: EventTypes.DIALING_PEER
104 | name: 'DIALING_PEER'
105 | }
106 |
107 | export type QueryEvent = SendingQueryEvent | PeerResponseEvent | FinalPeerEvent | QueryErrorEvent | ProviderEvent | ValueEvent | AddingPeerEvent | DialingPeerEvent
108 |
109 | export interface Delegate {
110 | getEndpointConfig(): { protocol: string, host: string, port: string }
111 |
112 | dht: {
113 | findPeer(peerId: PeerId, options?: AbortOptions): AsyncIterable
114 | query(peerId: PeerId | CID, options?: AbortOptions): AsyncIterable
115 | }
116 | }
117 |
118 | class DelegatedPeerRouting implements PeerRouting, Startable {
119 | private readonly client: Delegate
120 | private readonly httpQueue: PQueue
121 | private started: boolean
122 | private abortController: AbortController
123 |
124 | /**
125 | * Create a new DelegatedPeerRouting instance
126 | */
127 | constructor (client: Delegate) {
128 | if (client == null) {
129 | throw new Error('missing ipfs http client')
130 | }
131 |
132 | this.client = client
133 | this.started = false
134 | this.abortController = new AbortController()
135 |
136 | // limit concurrency to avoid request flood in web browser
137 | // https://github.com/libp2p/js-libp2p-delegated-content-routing/issues/12
138 | this.httpQueue = new PQueue({
139 | concurrency: CONCURRENT_HTTP_REQUESTS
140 | })
141 |
142 | const {
143 | protocol,
144 | host,
145 | port
146 | } = client.getEndpointConfig()
147 |
148 | log(`enabled DelegatedPeerRouting via ${protocol}://${host}:${port}`)
149 | }
150 |
151 | isStarted (): boolean {
152 | return this.started
153 | }
154 |
155 | start (): void {
156 | this.started = true
157 | }
158 |
159 | stop (): void {
160 | this.httpQueue.clear()
161 | this.abortController.abort()
162 | this.abortController = new AbortController()
163 | this.started = false
164 | }
165 |
166 | /**
167 | * Attempts to find the given peer
168 | */
169 | async findPeer (id: PeerId, options: HTTPClientExtraOptions & AbortOptions = {}): Promise {
170 | log('findPeer starts: %p', id)
171 | options.timeout = options.timeout ?? DEFAULT_TIMEOUT
172 |
173 | const signal = anySignal([this.abortController.signal, options.signal])
174 | const onStart = defer()
175 | const onFinish = defer()
176 |
177 | void this.httpQueue.add(async () => {
178 | onStart.resolve()
179 | return onFinish.promise
180 | })
181 |
182 | try {
183 | await onStart.promise
184 |
185 | for await (const event of this.client.dht.findPeer(id, {
186 | ...options,
187 | signal
188 | })) {
189 | if (event.name === 'FINAL_PEER' && event.peer.multiaddrs.length > 0) {
190 | const peerInfo: PeerInfo = {
191 | id: event.peer.id,
192 | multiaddrs: event.peer.multiaddrs,
193 | protocols: []
194 | }
195 |
196 | return peerInfo
197 | }
198 | }
199 |
200 | throw new CodeError('Not found', 'ERR_NOT_FOUND')
201 | } catch (err: any) {
202 | log.error('findPeer errored: %o', err)
203 |
204 | throw err
205 | } finally {
206 | signal.clear()
207 | onFinish.resolve()
208 | log('findPeer finished: %p', id)
209 | }
210 | }
211 |
212 | /**
213 | * Attempt to find the closest peers on the network to the given key
214 | */
215 | async * getClosestPeers (key: Uint8Array, options: HTTPClientExtraOptions & AbortOptions = {}): AsyncGenerator {
216 | let cidOrPeerId: CID | PeerId
217 | const cid = CID.asCID(key)
218 |
219 | if (cid != null) {
220 | cidOrPeerId = cid
221 | } else {
222 | cidOrPeerId = peerIdFromBytes(key)
223 | }
224 |
225 | log('getClosestPeers starts: %s', cidOrPeerId)
226 | options.timeout = options.timeout ?? DEFAULT_TIMEOUT
227 |
228 | const signal = anySignal([this.abortController.signal, options.signal])
229 | const onStart = defer()
230 | const onFinish = defer()
231 |
232 | void this.httpQueue.add(async () => {
233 | onStart.resolve()
234 | return onFinish.promise
235 | })
236 |
237 | try {
238 | await onStart.promise
239 |
240 | for await (const event of this.client.dht.query(cidOrPeerId, {
241 | ...options,
242 | signal
243 | })) {
244 | if (event.name === 'PEER_RESPONSE') {
245 | yield * event.closer.map(closer => ({
246 | id: closer.id,
247 | multiaddrs: closer.multiaddrs,
248 | protocols: []
249 | }))
250 | }
251 | }
252 | } catch (err) {
253 | log.error('getClosestPeers errored:', err)
254 | throw err
255 | } finally {
256 | signal.clear()
257 | onFinish.resolve()
258 | log('getClosestPeers finished: %b', key)
259 | }
260 | }
261 | }
262 |
263 | export function delegatedPeerRouting (client: Delegate): (components?: any) => PeerRouting {
264 | return () => new DelegatedPeerRouting(client)
265 | }
266 |
--------------------------------------------------------------------------------
/test/index.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 |
3 | import { stop } from '@libp2p/interfaces/startable'
4 | import { peerIdFromString } from '@libp2p/peer-id'
5 | import { createEd25519PeerId } from '@libp2p/peer-id-factory'
6 | import { expect } from 'aegir/chai'
7 | import { type Controller, createFactory } from 'ipfsd-ctl'
8 | import all from 'it-all'
9 | import drain from 'it-drain'
10 | import goIpfs from 'kubo'
11 | import { create, type Options, CID as IPFSCID } from 'kubo-rpc-client'
12 | import { CID } from 'multiformats/cid'
13 | import pDefer from 'p-defer'
14 | import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
15 | import { isElectronMain, isNode } from 'wherearewe'
16 | import { delegatedPeerRouting } from '../src/index.js'
17 | import type { PeerId } from '@libp2p/interface-peer-id'
18 | import type { AbortOptions } from '@libp2p/interfaces'
19 | import type { IDResult } from 'ipfs-core-types/src/root'
20 |
21 | const factory = createFactory({
22 | type: 'go',
23 | ipfsHttpModule: { create },
24 | ipfsBin: isNode || isElectronMain ? goIpfs.path() : undefined,
25 | test: true,
26 | disposable: true,
27 | endpoint: 'http://localhost:57583'
28 | })
29 |
30 | async function spawnNode (bootstrap: any[] = []): Promise<{ node: Controller, id: IDResult }> {
31 | const node = await factory.spawn({
32 | // Lock down the nodes so testing can be deterministic
33 | ipfsOptions: {
34 | config: {
35 | Bootstrap: bootstrap
36 | }
37 | }
38 | })
39 | const id = await node.api.id()
40 |
41 | return {
42 | node,
43 | id
44 | }
45 | }
46 |
47 | function createIpfsClient (opts: Options): any {
48 | const client = create(opts)
49 |
50 | return {
51 | getEndpointConfig: () => client.getEndpointConfig(),
52 | block: {
53 | async stat (cid: CID, options?: AbortOptions) {
54 | const result = await client.block.stat(IPFSCID.parse(cid.toString()), options)
55 |
56 | return {
57 | cid: CID.parse(result.cid.toString()),
58 | size: result.size
59 | }
60 | }
61 | },
62 | dht: {
63 | async * findPeer (peerId: PeerId, options?: AbortOptions) {
64 | yield * client.dht.findPeer(peerId, options)
65 | },
66 | async * query (peerId: PeerId | CID, options?: AbortOptions) {
67 | yield * client.dht.query(peerId, options)
68 | }
69 | }
70 | }
71 | }
72 |
73 | describe('DelegatedPeerRouting', function () {
74 | this.timeout(20 * 1000) // we're spawning daemons, give ci some time
75 |
76 | let nodeToFind: Controller
77 | let peerIdToFind: IDResult
78 | let delegatedNode: Controller
79 | let bootstrapNode: Controller
80 | let bootstrapId: IDResult
81 |
82 | before(async () => {
83 | // Spawn a "Boostrap" node that doesnt connect to anything
84 | const bootstrap = await spawnNode()
85 | bootstrapNode = bootstrap.node
86 | bootstrapId = bootstrap.id
87 |
88 | // Spawn our local node and bootstrap the bootstrapper node
89 | const local = await spawnNode(bootstrapId.addresses)
90 | nodeToFind = local.node
91 | peerIdToFind = local.id
92 |
93 | // Spawn the delegate node and bootstrap the bootstrapper node
94 | const delegate = await spawnNode(bootstrapId.addresses)
95 | delegatedNode = delegate.node
96 | })
97 |
98 | after(async () => {
99 | return Promise.all([
100 | nodeToFind.stop(),
101 | delegatedNode.stop(),
102 | bootstrapNode.stop()
103 | ])
104 | })
105 |
106 | describe('create', () => {
107 | it('should require an http api client instance at construction time', () => {
108 | // @ts-expect-error invalid parameters
109 | expect(() => delegatedPeerRouting()()).to.throw()
110 | })
111 |
112 | it('should accept an http api client instance at construction time', () => {
113 | const client = createIpfsClient({
114 | protocol: 'http',
115 | port: 8000,
116 | host: 'localhost'
117 | })
118 |
119 | const router = delegatedPeerRouting(client)()
120 |
121 | expect(router).to.have.property('client')
122 | .that.has.property('getEndpointConfig')
123 | .that.is.a('function')
124 |
125 | expect(client.getEndpointConfig()).to.deep.include({
126 | protocol: 'http:',
127 | port: '8000',
128 | host: 'localhost'
129 | })
130 | })
131 | })
132 |
133 | describe('findPeers', () => {
134 | it('should be able to find peers via the delegate with a peer id string', async () => {
135 | const opts = delegatedNode.apiAddr.toOptions()
136 |
137 | const router = delegatedPeerRouting(createIpfsClient({
138 | protocol: 'http',
139 | port: opts.port,
140 | host: opts.host
141 | }))()
142 |
143 | const peer = await router.findPeer(peerIdToFind.id)
144 |
145 | const { id, multiaddrs } = peer
146 | expect(id).to.exist()
147 | expect(multiaddrs).to.exist()
148 |
149 | expect(id.equals(peerIdToFind.id)).to.be.true()
150 | })
151 |
152 | it('should be able to find peers via the delegate with a peerid', async () => {
153 | const opts = delegatedNode.apiAddr.toOptions()
154 |
155 | const router = delegatedPeerRouting(createIpfsClient({
156 | protocol: 'http',
157 | port: opts.port,
158 | host: opts.host
159 | }))()
160 |
161 | const peer = await router.findPeer(peerIdToFind.id)
162 |
163 | const { id, multiaddrs } = peer
164 | expect(id).to.exist()
165 | expect(multiaddrs).to.exist()
166 |
167 | expect(id.toString()).to.eql(peerIdToFind.id.toString())
168 | })
169 |
170 | it('should be able to specify a timeout', async () => {
171 | const opts = delegatedNode.apiAddr.toOptions()
172 |
173 | const router = delegatedPeerRouting(createIpfsClient({
174 | protocol: 'http',
175 | port: opts.port,
176 | host: opts.host
177 | }))()
178 | const signal = AbortSignal.timeout(5e3)
179 |
180 | const peer = await router.findPeer(peerIdToFind.id, { signal })
181 |
182 | const { id, multiaddrs } = peer
183 | expect(id).to.exist()
184 | expect(multiaddrs).to.exist()
185 |
186 | expect(id.toString()).to.eql(peerIdToFind.id.toString())
187 | })
188 |
189 | it('should not be able to find peers not on the network', async () => {
190 | const opts = delegatedNode.apiAddr.toOptions()
191 |
192 | const router = delegatedPeerRouting(createIpfsClient({
193 | protocol: 'http',
194 | port: opts.port,
195 | host: opts.host
196 | }))()
197 |
198 | // This is one of the default Bootstrap nodes, but we're not connected to it
199 | // so we'll test with it.
200 | await expect(router.findPeer(peerIdFromString('QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64')))
201 | .to.eventually.be.rejected.with.property('code', 'ERR_NOT_FOUND')
202 | })
203 | })
204 |
205 | describe('query', () => {
206 | it('should be able to query for the closest peers', async () => {
207 | const opts = delegatedNode.apiAddr.toOptions()
208 |
209 | const router = delegatedPeerRouting(createIpfsClient({
210 | protocol: 'http',
211 | port: opts.port,
212 | host: opts.host
213 | }))()
214 |
215 | const nodeId = await delegatedNode.api.id()
216 | const delegatePeerId = nodeId.id
217 |
218 | const key = peerIdToFind.id.toBytes()
219 |
220 | const closerPeers = await all(router.getClosestPeers(key))
221 |
222 | // we should be closest to the 2 other peers
223 | expect(closerPeers.length).to.equal(2)
224 | closerPeers.forEach(result => {
225 | // shouldn't be the delegate
226 |
227 | expect(delegatePeerId.equals(result.id)).to.equal(false)
228 | expect(result.multiaddrs).to.be.an('array')
229 | })
230 | })
231 |
232 | it('should find closest peers even if the peer does not exist', async () => {
233 | const opts = delegatedNode.apiAddr.toOptions()
234 |
235 | const router = delegatedPeerRouting(createIpfsClient({
236 | protocol: 'http',
237 | port: opts.port,
238 | host: opts.host
239 | }))()
240 |
241 | const nodeId = await delegatedNode.api.id()
242 | const delegatePeerId = nodeId.id
243 |
244 | const peerId = await createEd25519PeerId()
245 | const closerPeers = await all(router.getClosestPeers(peerId.toBytes()))
246 |
247 | // we should be closest to the 2 other peers
248 | expect(closerPeers.length).to.equal(2)
249 | closerPeers.forEach(result => {
250 | // shouldnt be the delegate
251 |
252 | expect(delegatePeerId.equals(result.id)).to.equal(false)
253 | expect(result.multiaddrs).to.be.an('array')
254 | })
255 | })
256 | })
257 |
258 | describe('stop', () => {
259 | it('should cancel in-flight requests when stopping', async () => {
260 | const opts = delegatedNode.apiAddr.toOptions()
261 |
262 | const router = delegatedPeerRouting(createIpfsClient({
263 | protocol: 'http',
264 | port: opts.port,
265 | host: opts.host
266 | }))()
267 |
268 | const deferred = pDefer()
269 | const peer = uint8ArrayFromString('QmVv4Wz46JaZJeH5PMV4LGbRiiMKEmszPYY3g6fjGnVXBs', 'base58btc')
270 |
271 | void drain(router.getClosestPeers(peer))
272 | .then(() => {
273 | deferred.reject(new Error('Did not abort'))
274 | })
275 | .catch(err => {
276 | deferred.resolve(err)
277 | })
278 |
279 | await stop(router)
280 | await expect(deferred.promise).to.eventually.have.property('message').that.matches(/aborted/)
281 | })
282 | })
283 | })
284 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "aegir/src/config/tsconfig.aegir.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "emitDeclarationOnly": false,
6 | "module": "ES2020"
7 | },
8 | "include": [
9 | "src",
10 | "test"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "entryPoints": [
3 | "./src/index.ts"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------