@helia/ipns 8.2.4 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +31 -135
  2. package/dist/index.min.js +10 -11
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/constants.d.ts +17 -0
  5. package/dist/src/constants.d.ts.map +1 -0
  6. package/dist/src/constants.js +19 -0
  7. package/dist/src/constants.js.map +1 -0
  8. package/dist/src/errors.d.ts +0 -4
  9. package/dist/src/errors.d.ts.map +1 -1
  10. package/dist/src/errors.js +0 -7
  11. package/dist/src/errors.js.map +1 -1
  12. package/dist/src/index.d.ts +109 -201
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +34 -417
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/ipns.d.ts +22 -0
  17. package/dist/src/ipns.d.ts.map +1 -0
  18. package/dist/src/ipns.js +339 -0
  19. package/dist/src/ipns.js.map +1 -0
  20. package/dist/src/local-store.d.ts +42 -0
  21. package/dist/src/local-store.d.ts.map +1 -0
  22. package/dist/src/local-store.js +119 -0
  23. package/dist/src/local-store.js.map +1 -0
  24. package/dist/src/pb/metadata.d.ts +12 -0
  25. package/dist/src/pb/metadata.d.ts.map +1 -0
  26. package/dist/src/pb/metadata.js +57 -0
  27. package/dist/src/pb/metadata.js.map +1 -0
  28. package/dist/src/routing/index.d.ts +4 -2
  29. package/dist/src/routing/index.d.ts.map +1 -1
  30. package/dist/src/routing/index.js.map +1 -1
  31. package/dist/src/routing/local-store.d.ts +4 -19
  32. package/dist/src/routing/local-store.d.ts.map +1 -1
  33. package/dist/src/routing/local-store.js +7 -62
  34. package/dist/src/routing/local-store.js.map +1 -1
  35. package/dist/src/routing/pubsub.d.ts +21 -1
  36. package/dist/src/routing/pubsub.d.ts.map +1 -1
  37. package/dist/src/routing/pubsub.js +2 -2
  38. package/dist/src/routing/pubsub.js.map +1 -1
  39. package/dist/src/utils.d.ts +24 -0
  40. package/dist/src/utils.d.ts.map +1 -1
  41. package/dist/src/utils.js +56 -0
  42. package/dist/src/utils.js.map +1 -1
  43. package/dist/typedoc-urls.json +10 -13
  44. package/package.json +21 -23
  45. package/src/constants.ts +24 -0
  46. package/src/errors.ts +0 -9
  47. package/src/index.ts +116 -545
  48. package/src/ipns.ts +400 -0
  49. package/src/local-store.ts +162 -0
  50. package/src/pb/metadata.proto +9 -0
  51. package/src/pb/metadata.ts +74 -0
  52. package/src/routing/index.ts +4 -3
  53. package/src/routing/local-store.ts +9 -87
  54. package/src/routing/pubsub.ts +28 -4
  55. package/src/utils.ts +70 -0
  56. package/dist/src/dnslink.d.ts +0 -9
  57. package/dist/src/dnslink.d.ts.map +0 -1
  58. package/dist/src/dnslink.js +0 -138
  59. package/dist/src/dnslink.js.map +0 -1
  60. package/src/dnslink.ts +0 -163
package/README.md CHANGED
@@ -30,7 +30,7 @@ repo and examine the changes made.
30
30
 
31
31
  -->
32
32
 
33
- IPNS operations using a Helia node
33
+ [IPNS](https://docs.ipfs.tech/concepts/ipns/) operations using a Helia node
34
34
 
35
35
  ## Example - Getting started
36
36
 
@@ -40,23 +40,19 @@ With IPNSRouting routers:
40
40
  import { createHelia } from 'helia'
41
41
  import { ipns } from '@helia/ipns'
42
42
  import { unixfs } from '@helia/unixfs'
43
- import { generateKeyPair } from '@libp2p/crypto/keys'
44
43
 
45
44
  const helia = await createHelia()
46
45
  const name = ipns(helia)
47
46
 
48
- // create a keypair to publish an IPNS name
49
- const privateKey = await generateKeyPair('Ed25519')
50
-
51
47
  // store some data to publish
52
48
  const fs = unixfs(helia)
53
49
  const cid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
54
50
 
55
51
  // publish the name
56
- await name.publish(privateKey, cid)
52
+ const { publicKey } = await name.publish('key-1', cid)
57
53
 
58
54
  // resolve the name
59
- const result = await name.resolve(privateKey.publicKey)
55
+ const result = await name.resolve(publicKey)
60
56
 
61
57
  console.info(result.cid, result.path)
62
58
  ```
@@ -75,24 +71,18 @@ import { generateKeyPair } from '@libp2p/crypto/keys'
75
71
  const helia = await createHelia()
76
72
  const name = ipns(helia)
77
73
 
78
- // create a keypair to publish an IPNS name
79
- const privateKey = await generateKeyPair('Ed25519')
80
-
81
74
  // store some data to publish
82
75
  const fs = unixfs(helia)
83
76
  const cid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
84
77
 
85
78
  // publish the name
86
- await name.publish(privateKey, cid)
87
-
88
- // create another keypair to re-publish the original record
89
- const recursivePrivateKey = await generateKeyPair('Ed25519')
79
+ const { publicKey } = await name.publish('key-1', cid)
90
80
 
91
81
  // publish the recursive name
92
- await name.publish(recursivePrivateKey, privateKey.publicKey)
82
+ const { publicKey: recursivePublicKey } = await name.publish('key-2', publicKey)
93
83
 
94
84
  // resolve the name recursively - it resolves until a CID is found
95
- const result = await name.resolve(recursivePrivateKey.publicKey)
85
+ const result = await name.resolve(recursivePublicKey)
96
86
  console.info(result.cid.toString() === cid.toString()) // true
97
87
  ```
98
88
 
@@ -109,9 +99,6 @@ import { generateKeyPair } from '@libp2p/crypto/keys'
109
99
  const helia = await createHelia()
110
100
  const name = ipns(helia)
111
101
 
112
- // create a keypair to publish an IPNS name
113
- const privateKey = await generateKeyPair('Ed25519')
114
-
115
102
  // store some data to publish
116
103
  const fs = unixfs(helia)
117
104
  const fileCid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
@@ -121,10 +108,10 @@ const dirCid = await fs.addDirectory()
121
108
  const finalDirCid = await fs.cp(fileCid, dirCid, '/foo.txt')
122
109
 
123
110
  // publish the name
124
- await name.publish(privateKey, `/ipfs/${finalDirCid}/foo.txt`)
111
+ const { publicKey } = await name.publish('key-1', `/ipfs/${finalDirCid}/foo.txt`)
125
112
 
126
113
  // resolve the name
127
- const result = await name.resolve(privateKey.publicKey)
114
+ const result = await name.resolve(publicKey)
128
115
 
129
116
  console.info(result.cid, result.path) // QmFoo.. 'foo.txt'
130
117
  ```
@@ -150,13 +137,14 @@ import { createHelia, libp2pDefaults } from 'helia'
150
137
  import { ipns } from '@helia/ipns'
151
138
  import { pubsub } from '@helia/ipns/routing'
152
139
  import { unixfs } from '@helia/unixfs'
153
- import { gossipsub } from '@chainsafe/libp2p-gossipsub'
140
+ import { floodsub } from '@libp2p/floodsub'
154
141
  import { generateKeyPair } from '@libp2p/crypto/keys'
155
- import type { Libp2p, PubSub } from '@libp2p/interface'
142
+ import type { PubSub } from '@helia/ipns/routing'
143
+ import type { Libp2p } from '@libp2p/interface'
156
144
  import type { DefaultLibp2pServices } from 'helia'
157
145
 
158
146
  const libp2pOptions = libp2pDefaults()
159
- libp2pOptions.services.pubsub = gossipsub()
147
+ libp2pOptions.services.pubsub = floodsub()
160
148
 
161
149
  const helia = await createHelia<Libp2p<DefaultLibp2pServices & { pubsub: PubSub }>>({
162
150
  libp2p: libp2pOptions
@@ -167,133 +155,30 @@ const name = ipns(helia, {
167
155
  ]
168
156
  })
169
157
 
170
- // create a keypair to publish an IPNS name
171
- const privateKey = await generateKeyPair('Ed25519')
172
158
 
173
159
  // store some data to publish
174
160
  const fs = unixfs(helia)
175
161
  const cid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
176
162
 
177
163
  // publish the name
178
- await name.publish(privateKey, cid)
164
+ const { publicKey } = await name.publish('key-1', cid)
179
165
 
180
166
  // resolve the name
181
- const result = await name.resolve(privateKey.publicKey)
182
- ```
183
-
184
- ## Example - Using custom DNS over HTTPS resolvers
185
-
186
- To use custom resolvers, configure Helia's `dns` option:
187
-
188
- ```TypeScript
189
- import { createHelia } from 'helia'
190
- import { ipns } from '@helia/ipns'
191
- import { dns } from '@multiformats/dns'
192
- import { dnsOverHttps } from '@multiformats/dns/resolvers'
193
- import { helia } from '@helia/ipns/routing'
194
-
195
- const node = await createHelia({
196
- dns: dns({
197
- resolvers: {
198
- '.': dnsOverHttps('https://private-dns-server.me/dns-query')
199
- }
200
- })
201
- })
202
- const name = ipns(node, {
203
- routers: [
204
- helia(node.routing)
205
- ]
206
- })
207
-
208
- const result = name.resolveDNSLink('some-domain-with-dnslink-entry.com')
209
- ```
210
-
211
- ## Example - Resolving a domain with a dnslink entry
212
-
213
- Calling `resolveDNSLink` with the `@helia/ipns` instance:
214
-
215
- ```TypeScript
216
- // resolve a CID from a TXT record in a DNS zone file, using the default
217
- // resolver for the current platform eg:
218
- // > dig _dnslink.ipfs.io TXT
219
- // ;; ANSWER SECTION:
220
- // _dnslink.ipfs.io. 60 IN TXT "dnslink=/ipns/website.ipfs.io"
221
- // > dig _dnslink.website.ipfs.io TXT
222
- // ;; ANSWER SECTION:
223
- // _dnslink.website.ipfs.io. 60 IN TXT "dnslink=/ipfs/QmWebsite"
224
-
225
- import { createHelia } from 'helia'
226
- import { ipns } from '@helia/ipns'
227
-
228
- const node = await createHelia()
229
- const name = ipns(node)
230
-
231
- const { answer } = await name.resolveDNSLink('ipfs.io')
232
-
233
- console.info(answer)
234
- // { data: '/ipfs/QmWebsite' }
235
- ```
236
-
237
- ## Example - Using DNS-Over-HTTPS
238
-
239
- This example uses the Mozilla provided RFC 1035 DNS over HTTPS service. This
240
- uses binary DNS records so requires extra dependencies to process the
241
- response which can increase browser bundle sizes.
242
-
243
- If this is a concern, use the DNS-JSON-Over-HTTPS resolver instead.
244
-
245
- ```TypeScript
246
- import { createHelia } from 'helia'
247
- import { ipns } from '@helia/ipns'
248
- import { dns } from '@multiformats/dns'
249
- import { dnsOverHttps } from '@multiformats/dns/resolvers'
250
-
251
- const node = await createHelia({
252
- dns: dns({
253
- resolvers: {
254
- '.': dnsOverHttps('https://mozilla.cloudflare-dns.com/dns-query')
255
- }
256
- })
257
- })
258
- const name = ipns(node)
259
-
260
- const result = await name.resolveDNSLink('ipfs.io')
261
- ```
262
-
263
- ## Example - Using DNS-JSON-Over-HTTPS
264
-
265
- DNS-JSON-Over-HTTPS resolvers use the RFC 8427 `application/dns-json` and can
266
- result in a smaller browser bundle due to the response being plain JSON.
267
-
268
- ```TypeScript
269
- import { createHelia } from 'helia'
270
- import { ipns } from '@helia/ipns'
271
- import { dns } from '@multiformats/dns'
272
- import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
273
-
274
- const node = await createHelia({
275
- dns: dns({
276
- resolvers: {
277
- '.': dnsJsonOverHttps('https://mozilla.cloudflare-dns.com/dns-query')
278
- }
279
- })
280
- })
281
- const name = ipns(node)
282
-
283
- const result = await name.resolveDNSLink('ipfs.io')
167
+ const result = await name.resolve(publicKey)
284
168
  ```
285
169
 
286
170
  ## Example - Republishing an existing IPNS record
287
171
 
288
- The `republishRecord` method allows you to republish an existing IPNS record without
289
- needing the private key. This is useful for relay nodes or when you want to extend
290
- the availability of a record that was created elsewhere.
172
+ It is sometimes useful to be able to republish an existing IPNS record
173
+ without needing the private key. This allows you to extend the availability
174
+ of a record that was created elsewhere.
291
175
 
292
176
  ```TypeScript
293
177
  import { createHelia } from 'helia'
294
- import { ipns } from '@helia/ipns'
178
+ import { ipns, ipnsValidator } from '@helia/ipns'
295
179
  import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
296
180
  import { CID } from 'multiformats/cid'
181
+ import { multihashToIPNSRoutingKey, marshalIPNSRecord } from 'ipns'
297
182
 
298
183
  const helia = await createHelia()
299
184
  const name = ipns(helia)
@@ -303,7 +188,18 @@ const parsedCid: CID<unknown, 114, 0 | 18, 1> = CID.parse(ipnsName)
303
188
  const delegatedClient = createDelegatedRoutingV1HttpApiClient('https://delegated-ipfs.dev')
304
189
  const record = await delegatedClient.getIPNS(parsedCid)
305
190
 
306
- await name.republishRecord(ipnsName, record)
191
+ const routingKey = multihashToIPNSRoutingKey(parsedCid.multihash)
192
+ const marshaledRecord = marshalIPNSRecord(record)
193
+
194
+ // validate that they key corresponds to the record
195
+ await ipnsValidator(routingKey, marshaledRecord)
196
+
197
+ // publish record to routing
198
+ await Promise.all(
199
+ name.routers.map(async r => {
200
+ await r.put(routingKey, marshaledRecord)
201
+ })
202
+ )
307
203
  ```
308
204
 
309
205
  # Install