@helia/ipns 10.1.1-b34bc7c7 → 10.2.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.
- package/README.md +40 -0
- package/dist/index.min.js +5 -5
- package/dist/index.min.js.map +4 -4
- package/dist/src/errors.d.ts +11 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +13 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +136 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +41 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/ipns/publisher.d.ts +3 -3
- package/dist/src/ipns/publisher.d.ts.map +1 -1
- package/dist/src/ipns/publisher.js +17 -18
- package/dist/src/ipns/publisher.js.map +1 -1
- package/dist/src/ipns/republisher.d.ts +6 -1
- package/dist/src/ipns/republisher.d.ts.map +1 -1
- package/dist/src/ipns/republisher.js +157 -24
- package/dist/src/ipns/republisher.js.map +1 -1
- package/dist/src/ipns/resolver.d.ts +13 -1
- package/dist/src/ipns/resolver.d.ts.map +1 -1
- package/dist/src/ipns/resolver.js +40 -31
- package/dist/src/ipns/resolver.js.map +1 -1
- package/dist/src/ipns.d.ts +6 -3
- package/dist/src/ipns.d.ts.map +1 -1
- package/dist/src/ipns.js +12 -3
- package/dist/src/ipns.js.map +1 -1
- package/dist/src/local-store.d.ts +5 -0
- package/dist/src/local-store.d.ts.map +1 -1
- package/dist/src/local-store.js +68 -23
- package/dist/src/local-store.js.map +1 -1
- package/dist/src/pb/metadata.d.ts +14 -1
- package/dist/src/pb/metadata.d.ts.map +1 -1
- package/dist/src/pb/metadata.js +35 -2
- package/dist/src/pb/metadata.js.map +1 -1
- package/dist/src/routing/index.d.ts +13 -1
- package/dist/src/routing/index.d.ts.map +1 -1
- package/dist/src/routing/index.js +17 -0
- package/dist/src/routing/index.js.map +1 -1
- package/dist/src/utils.d.ts +5 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +18 -0
- package/dist/src/utils.js.map +1 -1
- package/dist/src/validator.d.ts +6 -0
- package/dist/src/validator.d.ts.map +1 -1
- package/dist/src/validator.js +24 -14
- package/dist/src/validator.js.map +1 -1
- package/dist/typedoc-urls.json +90 -0
- package/package.json +2 -2
- package/src/errors.ts +18 -0
- package/src/index.ts +145 -7
- package/src/ipns/publisher.ts +22 -20
- package/src/ipns/republisher.ts +182 -26
- package/src/ipns/resolver.ts +54 -36
- package/src/ipns.ts +20 -6
- package/src/local-store.ts +77 -22
- package/src/pb/metadata.proto +10 -0
- package/src/pb/metadata.ts +44 -3
- package/src/routing/index.ts +30 -1
- package/src/utils.ts +19 -0
- package/src/validator.ts +30 -18
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"codec": "https://ipfs.github.io/helia/functions/_helia_ipns.IPNSEntry.ValidityType.codec.html",
|
|
3
|
+
"ValidityType": "https://ipfs.github.io/helia/enums/_helia_ipns.IPNSEntry.ValidityType.html",
|
|
4
|
+
"IPNSEntryDataFieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntryDataFieldEvent.html",
|
|
5
|
+
"IPNSEntryPublicKeyFieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntryPublicKeyFieldEvent.html",
|
|
6
|
+
"IPNSEntrySequenceFieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntrySequenceFieldEvent.html",
|
|
7
|
+
"IPNSEntrySignatureV1FieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntrySignatureV1FieldEvent.html",
|
|
8
|
+
"IPNSEntrySignatureV2FieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntrySignatureV2FieldEvent.html",
|
|
9
|
+
"IPNSEntryTtlFieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntryTtlFieldEvent.html",
|
|
10
|
+
"IPNSEntryValidityFieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntryValidityFieldEvent.html",
|
|
11
|
+
"IPNSEntryValidityTypeFieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntryValidityTypeFieldEvent.html",
|
|
12
|
+
"IPNSEntryValueFieldEvent": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.IPNSEntryValueFieldEvent.html",
|
|
13
|
+
"decode": "https://ipfs.github.io/helia/functions/_helia_ipns.IPNSEntry.decode.html",
|
|
14
|
+
"encode": "https://ipfs.github.io/helia/functions/_helia_ipns.IPNSEntry.encode.html",
|
|
15
|
+
"stream": "https://ipfs.github.io/helia/functions/_helia_ipns.IPNSEntry.stream.html",
|
|
16
|
+
"InvalidEmbeddedPublicKeyError": "https://ipfs.github.io/helia/classes/_helia_ipns.InvalidEmbeddedPublicKeyError.html",
|
|
17
|
+
"InvalidRecordDataError": "https://ipfs.github.io/helia/classes/_helia_ipns.InvalidRecordDataError.html",
|
|
18
|
+
"InvalidTopicError": "https://ipfs.github.io/helia/classes/_helia_ipns.InvalidTopicError.html",
|
|
19
|
+
"InvalidValueError": "https://ipfs.github.io/helia/classes/_helia_ipns.InvalidValueError.html",
|
|
20
|
+
"RecordExpiredError": "https://ipfs.github.io/helia/classes/_helia_ipns.RecordExpiredError.html",
|
|
21
|
+
"RecordNotFoundError": "https://ipfs.github.io/helia/classes/_helia_ipns.RecordNotFoundError.html",
|
|
22
|
+
"RecordObsoleteError": "https://ipfs.github.io/helia/classes/_helia_ipns.RecordObsoleteError.html",
|
|
23
|
+
"RecordsFailedValidationError": "https://ipfs.github.io/helia/classes/_helia_ipns.RecordsFailedValidationError.html",
|
|
24
|
+
"RecordTooLargeError": "https://ipfs.github.io/helia/classes/_helia_ipns.RecordTooLargeError.html",
|
|
25
|
+
"SignatureCreationError": "https://ipfs.github.io/helia/classes/_helia_ipns.SignatureCreationError.html",
|
|
26
|
+
"SignatureVerificationError": "https://ipfs.github.io/helia/classes/_helia_ipns.SignatureVerificationError.html",
|
|
27
|
+
"UnsupportedValidityError": "https://ipfs.github.io/helia/classes/_helia_ipns.UnsupportedValidityError.html",
|
|
28
|
+
"CreateIPNSRecordOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.CreateIPNSRecordOptions.html",
|
|
29
|
+
"IPNS": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNS.html",
|
|
30
|
+
".:IPNS": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNS.html",
|
|
31
|
+
"IPNSComponents": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSComponents.html",
|
|
32
|
+
".:IPNSComponents": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSComponents.html",
|
|
33
|
+
"IPNSEntry": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSEntry.html",
|
|
34
|
+
"IPNSOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSOptions.html",
|
|
35
|
+
".:IPNSOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSOptions.html",
|
|
36
|
+
"IPNSPublishResult": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSPublishResult.html",
|
|
37
|
+
".:IPNSPublishResult": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSPublishResult.html",
|
|
38
|
+
"IPNSRecordData": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSRecordData.html",
|
|
39
|
+
".:IPNSRecordData": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSRecordData.html",
|
|
40
|
+
"IPNSResolveOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolveOptions.html",
|
|
41
|
+
".:IPNSResolveOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolveOptions.html",
|
|
42
|
+
"IPNSResolver": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolver.html",
|
|
43
|
+
".:IPNSResolver": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolver.html",
|
|
44
|
+
"IPNSResolveResult": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolveResult.html",
|
|
45
|
+
".:IPNSResolveResult": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolveResult.html",
|
|
46
|
+
"IPNSResolverOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolverOptions.html",
|
|
47
|
+
".:IPNSResolverOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSResolverOptions.html",
|
|
48
|
+
"IPNSRouting": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSRouting.html",
|
|
49
|
+
"IPNSRoutingGetOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSRoutingGetOptions.html",
|
|
50
|
+
"IPNSRoutingPutOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.IPNSRoutingPutOptions.html",
|
|
51
|
+
"PublishOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PublishOptions.html",
|
|
52
|
+
".:PublishOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PublishOptions.html",
|
|
53
|
+
"PublishResult": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PublishResult.html",
|
|
54
|
+
"PubSub": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PubSub.html",
|
|
55
|
+
"PubSubEvents": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PubSubEvents.html",
|
|
56
|
+
"PubSubMessage": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PubSubMessage.html",
|
|
57
|
+
"PubsubRoutingComponents": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PubsubRoutingComponents.html",
|
|
58
|
+
"PubSubSubscription": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PubSubSubscription.html",
|
|
59
|
+
"PubSubSubscriptionChangeData": "https://ipfs.github.io/helia/interfaces/_helia_ipns.PubSubSubscriptionChangeData.html",
|
|
60
|
+
"RepublishOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.RepublishOptions.html",
|
|
61
|
+
".:RepublishOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.RepublishOptions.html",
|
|
62
|
+
"RepublishResult": "https://ipfs.github.io/helia/interfaces/_helia_ipns.RepublishResult.html",
|
|
63
|
+
".:RepublishResult": "https://ipfs.github.io/helia/interfaces/_helia_ipns.RepublishResult.html",
|
|
64
|
+
"UnpublishOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.UnpublishOptions.html",
|
|
65
|
+
".:UnpublishOptions": "https://ipfs.github.io/helia/interfaces/_helia_ipns.UnpublishOptions.html",
|
|
66
|
+
"DatastoreProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.DatastoreProgressEvents.html",
|
|
67
|
+
".:DatastoreProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.DatastoreProgressEvents.html",
|
|
68
|
+
"HeliaRoutingProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.HeliaRoutingProgressEvents.html",
|
|
69
|
+
"IPNSRoutingProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.IPNSRoutingProgressEvents.html",
|
|
70
|
+
"PublishProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.PublishProgressEvents.html",
|
|
71
|
+
".:PublishProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.PublishProgressEvents.html",
|
|
72
|
+
"PubSubProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.PubSubProgressEvents.html",
|
|
73
|
+
"ResolveProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.ResolveProgressEvents.html",
|
|
74
|
+
".:ResolveProgressEvents": "https://ipfs.github.io/helia/types/_helia_ipns.ResolveProgressEvents.html",
|
|
75
|
+
"UpkeepPolicy": "https://ipfs.github.io/helia/types/_helia_ipns.UpkeepPolicy.html",
|
|
76
|
+
".:UpkeepPolicy": "https://ipfs.github.io/helia/types/_helia_ipns.UpkeepPolicy.html",
|
|
77
|
+
"createIPNSRecord": "https://ipfs.github.io/helia/functions/_helia_ipns.createIPNSRecord.html",
|
|
78
|
+
"heliaIPNSRouting": "https://ipfs.github.io/helia/functions/_helia_ipns.heliaIPNSRouting.html",
|
|
79
|
+
"ipns": "https://ipfs.github.io/helia/functions/_helia_ipns.ipns.html",
|
|
80
|
+
".:ipns": "https://ipfs.github.io/helia/functions/_helia_ipns.ipns.html",
|
|
81
|
+
"ipnsResolver": "https://ipfs.github.io/helia/functions/_helia_ipns.ipnsResolver.html",
|
|
82
|
+
".:ipnsResolver": "https://ipfs.github.io/helia/functions/_helia_ipns.ipnsResolver.html",
|
|
83
|
+
"ipnsSelector": "https://ipfs.github.io/helia/functions/_helia_ipns.ipnsSelector.html",
|
|
84
|
+
"ipnsValidator": "https://ipfs.github.io/helia/functions/_helia_ipns.ipnsValidator.html",
|
|
85
|
+
"isLocalStoreRouting": "https://ipfs.github.io/helia/functions/_helia_ipns.isLocalStoreRouting.html",
|
|
86
|
+
"multihashFromIPNSRoutingKey": "https://ipfs.github.io/helia/functions/_helia_ipns.multihashFromIPNSRoutingKey.html",
|
|
87
|
+
"multihashToIPNSRoutingKey": "https://ipfs.github.io/helia/functions/_helia_ipns.multihashToIPNSRoutingKey.html",
|
|
88
|
+
"pubSubIPNSRouting": "https://ipfs.github.io/helia/functions/_helia_ipns.pubSubIPNSRouting.html",
|
|
89
|
+
"routerName": "https://ipfs.github.io/helia/functions/_helia_ipns.routerName.html"
|
|
90
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/ipns",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.2.0",
|
|
4
4
|
"description": "An implementation of IPNS for Helia",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/ipfs/helia/tree/main/packages/ipns#readme",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"test:electron-main": "aegir test -t electron-main"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@helia/interface": "7.1.1
|
|
53
|
+
"@helia/interface": "^7.1.1",
|
|
54
54
|
"@ipld/dag-cbor": "^10.0.1",
|
|
55
55
|
"@ipshipyard/crypto": "^1.1.0",
|
|
56
56
|
"@ipshipyard/keychain": "^1.0.2",
|
package/src/errors.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { IPNSEntry } from './pb/ipns.ts'
|
|
2
|
+
|
|
1
3
|
export class RecordsFailedValidationError extends Error {
|
|
2
4
|
static name = 'RecordsFailedValidationError'
|
|
3
5
|
name = 'RecordsFailedValidationError'
|
|
@@ -18,6 +20,22 @@ export class RecordNotFoundError extends Error {
|
|
|
18
20
|
name = 'RecordNotFoundError'
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
export class RecordObsoleteError extends Error {
|
|
24
|
+
static name = 'RecordObsoleteError'
|
|
25
|
+
name = 'RecordObsoleteError'
|
|
26
|
+
/**
|
|
27
|
+
* The more suitable record that made the one being imported or republished
|
|
28
|
+
* obsolete.
|
|
29
|
+
*/
|
|
30
|
+
readonly record: IPNSEntry
|
|
31
|
+
|
|
32
|
+
constructor (message: string, record: IPNSEntry) {
|
|
33
|
+
super(message)
|
|
34
|
+
|
|
35
|
+
this.record = record
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
21
39
|
export class SignatureCreationError extends Error {
|
|
22
40
|
static name = 'SignatureCreationError'
|
|
23
41
|
name = 'SignatureCreationError'
|
package/src/index.ts
CHANGED
|
@@ -135,6 +135,46 @@
|
|
|
135
135
|
* console.info(result.record.value)
|
|
136
136
|
* }
|
|
137
137
|
* ```
|
|
138
|
+
*
|
|
139
|
+
* @example Republishing an existing IPNS record
|
|
140
|
+
*
|
|
141
|
+
* It is sometimes useful to be able to republish an existing IPNS record
|
|
142
|
+
* without needing the private key. This allows you to extend the availability
|
|
143
|
+
* of a record that was created elsewhere.
|
|
144
|
+
*
|
|
145
|
+
* There should be only one republisher per IPNS key. Multiple machines
|
|
146
|
+
* republishing the same key flood the routers with redundant writes.
|
|
147
|
+
*
|
|
148
|
+
* ```TypeScript
|
|
149
|
+
* import { createHelia } from 'helia'
|
|
150
|
+
* import { ipns } from '@helia/ipns'
|
|
151
|
+
* import { delegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
|
|
152
|
+
* import { defaultLogger } from 'birnam'
|
|
153
|
+
* import { CID } from 'multiformats/cid'
|
|
154
|
+
*
|
|
155
|
+
* const helia = await createHelia()
|
|
156
|
+
* const name = ipns(helia)
|
|
157
|
+
*
|
|
158
|
+
* const ipnsName = 'k51qzi5uqu5dktsyfv7xz8h631pri4ct7osmb43nibxiojpttxzoft6hdyyzg4'
|
|
159
|
+
* const parsedCid: CID<unknown, 114, 0 | 18, 1> = CID.parse(ipnsName)
|
|
160
|
+
* const delegatedClient = delegatedRoutingV1HttpApiClient({
|
|
161
|
+
* url: 'https://delegated-ipfs.dev'
|
|
162
|
+
* })({
|
|
163
|
+
* logger: defaultLogger()
|
|
164
|
+
* })
|
|
165
|
+
* const record = await delegatedClient.getIPNS(parsedCid)
|
|
166
|
+
*
|
|
167
|
+
* // import the record into the local store (validates and stores it locally,
|
|
168
|
+
* // but does not publish it to the routers)
|
|
169
|
+
* await name.import(parsedCid, record)
|
|
170
|
+
*
|
|
171
|
+
* // start republishing it; throws RecordObsoleteError if the routers
|
|
172
|
+
* // already have a newer record for this key
|
|
173
|
+
* const { record: latestRecord } = await name.republish(parsedCid)
|
|
174
|
+
*
|
|
175
|
+
* // stop republishing a key
|
|
176
|
+
* await name.unpublish(parsedCid)
|
|
177
|
+
* ```
|
|
138
178
|
*/
|
|
139
179
|
|
|
140
180
|
import { CID } from 'multiformats/cid'
|
|
@@ -155,6 +195,7 @@ import type { ProgressEvent, ProgressOptions } from 'progress-events'
|
|
|
155
195
|
|
|
156
196
|
export * from './routing/index.ts'
|
|
157
197
|
export * from './pb/ipns.ts'
|
|
198
|
+
export * from './errors.ts'
|
|
158
199
|
|
|
159
200
|
export {
|
|
160
201
|
multihashFromIPNSRoutingKey,
|
|
@@ -184,6 +225,14 @@ export type DatastoreProgressEvents =
|
|
|
184
225
|
ProgressEvent<'ipns:routing:datastore:list'> |
|
|
185
226
|
ProgressEvent<'ipns:routing:datastore:error', Error>
|
|
186
227
|
|
|
228
|
+
/**
|
|
229
|
+
* The automated upkeep policy for a stored IPNS record. `republish()` accepts
|
|
230
|
+
* every policy except `reissue`, which needs the private key to re-sign.
|
|
231
|
+
*
|
|
232
|
+
* These strings must match the `Upkeep` enum values in `pb/metadata.proto`.
|
|
233
|
+
*/
|
|
234
|
+
export type UpkeepPolicy = 'reissue' | 'rebroadcast' | 'none'
|
|
235
|
+
|
|
187
236
|
export interface PublishOptions extends AbortOptions, ProgressOptions<PublishProgressEvents | IPNSRoutingProgressEvents> {
|
|
188
237
|
/**
|
|
189
238
|
* Time duration of the signature validity in ms - after this many ms have
|
|
@@ -219,6 +268,17 @@ export interface PublishOptions extends AbortOptions, ProgressOptions<PublishPro
|
|
|
219
268
|
*/
|
|
220
269
|
ttl?: number
|
|
221
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Automated record upkeep policy.
|
|
273
|
+
*
|
|
274
|
+
* - `reissue`: re-sign the record with a new validity
|
|
275
|
+
* - `rebroadcast`: re-publish the existing record until it expires
|
|
276
|
+
* - `none`: disable automated publishing
|
|
277
|
+
*
|
|
278
|
+
* @default 'reissue'
|
|
279
|
+
*/
|
|
280
|
+
upkeep?: UpkeepPolicy
|
|
281
|
+
|
|
222
282
|
/**
|
|
223
283
|
* Extensible data that will be added to the IPNS record data and signed to
|
|
224
284
|
* verify it's integrity.
|
|
@@ -273,6 +333,43 @@ export interface IPNSResolveOptions extends AbortOptions, ProgressOptions<Resolv
|
|
|
273
333
|
validate?: boolean
|
|
274
334
|
}
|
|
275
335
|
|
|
336
|
+
export interface RepublishOptions extends AbortOptions, ProgressOptions<IPNSRoutingProgressEvents> {
|
|
337
|
+
/**
|
|
338
|
+
* Skip resolution of latest record before republishing.
|
|
339
|
+
*
|
|
340
|
+
* It's important to resolve the latest record before republishing to routers
|
|
341
|
+
*
|
|
342
|
+
* Resolution should only be skipped when confident the latest record is
|
|
343
|
+
* already known.
|
|
344
|
+
*
|
|
345
|
+
* @default false
|
|
346
|
+
*/
|
|
347
|
+
skipResolution?: boolean
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Automated record upkeep policy.
|
|
351
|
+
*
|
|
352
|
+
* Defaults to `rebroadcast` since `republish()` cannot sign new records
|
|
353
|
+
* without the private key.
|
|
354
|
+
*
|
|
355
|
+
* - `rebroadcast`: re-publish the existing record until it expires
|
|
356
|
+
* - `none`: disable automated publishing
|
|
357
|
+
*
|
|
358
|
+
* @default 'rebroadcast'
|
|
359
|
+
*/
|
|
360
|
+
upkeep?: Exclude<UpkeepPolicy, 'reissue'>
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export interface UnpublishOptions extends AbortOptions {
|
|
364
|
+
/**
|
|
365
|
+
* Also delete the record from the local store, so the node stops serving it
|
|
366
|
+
* immediately instead of keeping it until it expires.
|
|
367
|
+
*
|
|
368
|
+
* @default false
|
|
369
|
+
*/
|
|
370
|
+
removeRecord?: boolean
|
|
371
|
+
}
|
|
372
|
+
|
|
276
373
|
export interface IPNSResolveResult {
|
|
277
374
|
/**
|
|
278
375
|
* The resolved record
|
|
@@ -302,6 +399,18 @@ export interface IPNSPublishResult {
|
|
|
302
399
|
publicKey: PublicKey
|
|
303
400
|
}
|
|
304
401
|
|
|
402
|
+
export interface RepublishResult {
|
|
403
|
+
/**
|
|
404
|
+
* The published record
|
|
405
|
+
*/
|
|
406
|
+
record: IPNSEntry
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* The public key that the record is published under
|
|
410
|
+
*/
|
|
411
|
+
publicKey: PublicKey
|
|
412
|
+
}
|
|
413
|
+
|
|
305
414
|
export interface IPNSResolver {
|
|
306
415
|
/**
|
|
307
416
|
* Accepts a CID with the libp2p-key codec and either the identity hash (for
|
|
@@ -345,7 +454,7 @@ export interface IPNS {
|
|
|
345
454
|
* signal: AbortSignal.timeout(5_000)
|
|
346
455
|
* })
|
|
347
456
|
*
|
|
348
|
-
* console.info(result) // {
|
|
457
|
+
* console.info(result) // { record, name, publicKey }
|
|
349
458
|
* ```
|
|
350
459
|
*/
|
|
351
460
|
publish(keyName: string, value: CID | PublicKey | MultihashDigest | string, options?: PublishOptions): Promise<IPNSPublishResult>
|
|
@@ -357,17 +466,46 @@ export interface IPNS {
|
|
|
357
466
|
* (e.g. the value can be parsed as a string that does not start with
|
|
358
467
|
* `/ipns/`).
|
|
359
468
|
*/
|
|
360
|
-
resolve(name: CID | PublicKey | MultihashDigest | string, options?: IPNSResolveOptions): AsyncGenerator<IPNSResolveResult>
|
|
469
|
+
resolve(name: CID<unknown, 0x72> | PublicKey | MultihashDigest | string, options?: IPNSResolveOptions): AsyncGenerator<IPNSResolveResult>
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Stop automatically republishing an IPNS record
|
|
473
|
+
*
|
|
474
|
+
* By default this removes only the republishing metadata, keeping the record
|
|
475
|
+
* in the datastore so it is still served until it expires. Pass
|
|
476
|
+
* `removeRecord: true` to also delete the record so the node stops serving it.
|
|
477
|
+
* If a key name is passed, the key remains in the keychain.
|
|
478
|
+
*/
|
|
479
|
+
unpublish(key: CID<unknown, 0x72> | PublicKey | MultihashDigest | string, options?: UnpublishOptions): Promise<void>
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Republish the record already in the local store, setting its upkeep policy.
|
|
483
|
+
*
|
|
484
|
+
* Sets the record's upkeep policy to `options.upkeep` (default `rebroadcast`)
|
|
485
|
+
* so the background republisher keeps it available on the routers.
|
|
486
|
+
*
|
|
487
|
+
* @throws {NotFoundError} when there is no local record to republish
|
|
488
|
+
* @throws {RecordObsoleteError} when the routers already have a newer record
|
|
489
|
+
*/
|
|
490
|
+
republish(key: CID<unknown, 0x72> | PublicKey | MultihashDigest | string, options?: RepublishOptions): Promise<RepublishResult>
|
|
361
491
|
|
|
362
492
|
/**
|
|
363
|
-
*
|
|
493
|
+
* Import an existing IPNS record into the local store without publishing it.
|
|
494
|
+
*
|
|
495
|
+
* The record is validated and stored so this node serves it on a GET, but it
|
|
496
|
+
* is not broadcast to the routers. A newly imported record (for a key with no
|
|
497
|
+
* existing upkeep policy) is not automatically republished; call `republish`
|
|
498
|
+
* with an upkeep policy to start keeping it alive.
|
|
364
499
|
*
|
|
365
|
-
*
|
|
500
|
+
* Overwrites an older record already stored under this key, or rejects with
|
|
501
|
+
* `RecordObsoleteError` if the stored record is newer. Importing never changes
|
|
502
|
+
* the key's upkeep metadata, so a key that already has an upkeep policy keeps
|
|
503
|
+
* it and continues to be republished automatically.
|
|
366
504
|
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
505
|
+
* @throws {RecordExpiredError} (or another validation error) when the record fails validation
|
|
506
|
+
* @throws {RecordObsoleteError} when the stored record is more suitable than the one being imported
|
|
369
507
|
*/
|
|
370
|
-
|
|
508
|
+
import(key: CID<unknown, 0x72> | PublicKey | MultihashDigest | string, record: IPNSEntry | Uint8Array, options?: AbortOptions): Promise<void>
|
|
371
509
|
}
|
|
372
510
|
|
|
373
511
|
export interface IPNSComponents {
|
package/src/ipns/publisher.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { base36 } from 'multiformats/bases/base36'
|
|
|
2
2
|
import { CustomProgressEvent } from 'progress-events'
|
|
3
3
|
import { DEFAULT_LIFETIME_MS } from '../constants.ts'
|
|
4
4
|
import { IPNSEntry } from '../pb/ipns.ts'
|
|
5
|
+
import { Upkeep } from '../pb/metadata.ts'
|
|
5
6
|
import { createIPNSRecord } from '../records.ts'
|
|
6
7
|
import { decodeExtensibleData, multihashToIPNSRoutingKey } from '../utils.ts'
|
|
7
|
-
import type { IPNSPublishResult, PublishOptions } from '../index.ts'
|
|
8
|
+
import type { IPNSPublishResult, PublishOptions, UnpublishOptions } from '../index.ts'
|
|
8
9
|
import type { LocalStore } from '../local-store.ts'
|
|
9
10
|
import type { IPNSRouting } from '../routing/index.ts'
|
|
10
11
|
import type { Keychain, PrivateKey, PublicKey } from '@helia/interface'
|
|
@@ -58,25 +59,14 @@ export class IPNSPublisher {
|
|
|
58
59
|
})
|
|
59
60
|
const marshaledRecord = IPNSEntry.encode(record)
|
|
60
61
|
|
|
62
|
+
const metadata = { keyName, lifetime, upkeep: Upkeep[options.upkeep ?? 'reissue'] }
|
|
61
63
|
if (options.offline === true) {
|
|
62
64
|
// only store record locally
|
|
63
|
-
await this.localStore.put(routingKey, marshaledRecord, {
|
|
64
|
-
...options,
|
|
65
|
-
metadata: {
|
|
66
|
-
keyName,
|
|
67
|
-
lifetime
|
|
68
|
-
}
|
|
69
|
-
})
|
|
65
|
+
await this.localStore.put(routingKey, marshaledRecord, { ...options, metadata })
|
|
70
66
|
} else {
|
|
71
67
|
// publish record to routing (including the local store)
|
|
72
68
|
await Promise.all(this.routers.map(async r => {
|
|
73
|
-
await r.put(routingKey, marshaledRecord, {
|
|
74
|
-
...options,
|
|
75
|
-
metadata: {
|
|
76
|
-
keyName,
|
|
77
|
-
lifetime
|
|
78
|
-
}
|
|
79
|
-
})
|
|
69
|
+
await r.put(routingKey, marshaledRecord, { ...options, metadata })
|
|
80
70
|
}))
|
|
81
71
|
}
|
|
82
72
|
|
|
@@ -108,10 +98,22 @@ export class IPNSPublisher {
|
|
|
108
98
|
}
|
|
109
99
|
}
|
|
110
100
|
|
|
111
|
-
async unpublish (keyName: string, options?:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
101
|
+
async unpublish (keyName: string | MultihashDigest, options?: UnpublishOptions): Promise<void> {
|
|
102
|
+
if (typeof keyName === 'string') {
|
|
103
|
+
const key = await this.keychain.exportKey(keyName, options)
|
|
104
|
+
keyName = key.publicKey.toMultihash()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const routingKey = multihashToIPNSRoutingKey(keyName)
|
|
108
|
+
|
|
109
|
+
if (options?.removeRecord === true) {
|
|
110
|
+
// delete the record and its metadata so this node stops serving it
|
|
111
|
+
await this.localStore.delete(routingKey, options)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// remove only the metadata so the record is still served but no longer
|
|
116
|
+
// automatically republished; it expires naturally at its validity
|
|
117
|
+
await this.localStore.deleteMetadata(routingKey, options)
|
|
116
118
|
}
|
|
117
119
|
}
|