@helia/ipns 8.2.4 → 9.0.0-4d51f16d
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 +31 -135
- package/dist/index.min.js +11 -11
- package/dist/index.min.js.map +4 -4
- package/dist/src/constants.d.ts +17 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +19 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/errors.d.ts +0 -4
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +0 -7
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +131 -207
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +49 -416
- package/dist/src/index.js.map +1 -1
- package/dist/src/ipns/publisher.d.ts +29 -0
- package/dist/src/ipns/publisher.d.ts.map +1 -0
- package/dist/src/ipns/publisher.js +73 -0
- package/dist/src/ipns/publisher.js.map +1 -0
- package/dist/src/ipns/republisher.d.ts +30 -0
- package/dist/src/ipns/republisher.d.ts.map +1 -0
- package/dist/src/ipns/republisher.js +112 -0
- package/dist/src/ipns/republisher.js.map +1 -0
- package/dist/src/ipns/resolver.d.ts +26 -0
- package/dist/src/ipns/resolver.d.ts.map +1 -0
- package/dist/src/ipns/resolver.js +165 -0
- package/dist/src/ipns/resolver.js.map +1 -0
- package/dist/src/ipns.d.ts +20 -0
- package/dist/src/ipns.d.ts.map +1 -0
- package/dist/src/ipns.js +70 -0
- package/dist/src/ipns.js.map +1 -0
- package/dist/src/local-store.d.ts +42 -0
- package/dist/src/local-store.d.ts.map +1 -0
- package/dist/src/local-store.js +119 -0
- package/dist/src/local-store.js.map +1 -0
- package/dist/src/pb/metadata.d.ts +12 -0
- package/dist/src/pb/metadata.d.ts.map +1 -0
- package/dist/src/pb/metadata.js +57 -0
- package/dist/src/pb/metadata.js.map +1 -0
- package/dist/src/routing/index.d.ts +5 -3
- package/dist/src/routing/index.d.ts.map +1 -1
- package/dist/src/routing/index.js.map +1 -1
- package/dist/src/routing/local-store.d.ts +4 -19
- package/dist/src/routing/local-store.d.ts.map +1 -1
- package/dist/src/routing/local-store.js +7 -62
- package/dist/src/routing/local-store.js.map +1 -1
- package/dist/src/routing/pubsub.d.ts +21 -1
- package/dist/src/routing/pubsub.d.ts.map +1 -1
- package/dist/src/routing/pubsub.js +2 -2
- package/dist/src/routing/pubsub.js.map +1 -1
- package/dist/src/utils.d.ts +24 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +56 -0
- package/dist/src/utils.js.map +1 -1
- package/package.json +21 -23
- package/src/constants.ts +24 -0
- package/src/errors.ts +0 -9
- package/src/index.ts +154 -548
- package/src/ipns/publisher.ts +97 -0
- package/src/ipns/republisher.ts +144 -0
- package/src/ipns/resolver.ts +217 -0
- package/src/ipns.ts +87 -0
- package/src/local-store.ts +162 -0
- package/src/pb/metadata.proto +9 -0
- package/src/pb/metadata.ts +74 -0
- package/src/routing/index.ts +5 -4
- package/src/routing/local-store.ts +9 -87
- package/src/routing/pubsub.ts +28 -4
- package/src/utils.ts +70 -0
- package/dist/src/dnslink.d.ts +0 -9
- package/dist/src/dnslink.d.ts.map +0 -1
- package/dist/src/dnslink.js +0 -138
- package/dist/src/dnslink.js.map +0 -1
- package/dist/typedoc-urls.json +0 -48
- package/src/dnslink.ts +0 -163
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const DEFAULT_LIFETIME_MS: number;
|
|
2
|
+
/**
|
|
3
|
+
* The default DHT record expiry
|
|
4
|
+
*/
|
|
5
|
+
export declare const DHT_EXPIRY_MS: number;
|
|
6
|
+
/**
|
|
7
|
+
* How often to run the republish loop
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_REPUBLISH_INTERVAL_MS: number;
|
|
10
|
+
/**
|
|
11
|
+
* Republish IPNS records when the expiry of our provider records is within this
|
|
12
|
+
* threshold
|
|
13
|
+
*/
|
|
14
|
+
export declare const REPUBLISH_THRESHOLD: number;
|
|
15
|
+
export declare const DEFAULT_TTL_NS: bigint;
|
|
16
|
+
export declare const DEFAULT_REPUBLISH_CONCURRENCY = 5;
|
|
17
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,QAAY,CAAA;AAE5C;;GAEG;AACH,eAAO,MAAM,aAAa,QAAY,CAAA;AAEtC;;GAEG;AACH,eAAO,MAAM,6BAA6B,QAAO,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAAY,CAAA;AAE5C,eAAO,MAAM,cAAc,QAA8B,CAAA;AAEzD,eAAO,MAAM,6BAA6B,IAAI,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const MINUTE = 60 * 1000;
|
|
2
|
+
const HOUR = 60 * MINUTE;
|
|
3
|
+
export const DEFAULT_LIFETIME_MS = 48 * HOUR;
|
|
4
|
+
/**
|
|
5
|
+
* The default DHT record expiry
|
|
6
|
+
*/
|
|
7
|
+
export const DHT_EXPIRY_MS = 48 * HOUR;
|
|
8
|
+
/**
|
|
9
|
+
* How often to run the republish loop
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_REPUBLISH_INTERVAL_MS = HOUR;
|
|
12
|
+
/**
|
|
13
|
+
* Republish IPNS records when the expiry of our provider records is within this
|
|
14
|
+
* threshold
|
|
15
|
+
*/
|
|
16
|
+
export const REPUBLISH_THRESHOLD = 24 * HOUR;
|
|
17
|
+
export const DEFAULT_TTL_NS = BigInt(MINUTE) * 5000000n; // 5 minutes
|
|
18
|
+
export const DEFAULT_REPUBLISH_CONCURRENCY = 5;
|
|
19
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,CAAA;AACxB,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAA;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,IAAI,CAAA;AAE5C;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,CAAA;AAEtC;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAA;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,IAAI,CAAA;AAE5C,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,QAAU,CAAA,CAAC,YAAY;AAEtE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAA"}
|
package/dist/src/errors.d.ts
CHANGED
package/dist/src/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,MAAM,CAAC,IAAI,SAAiC;gBAE/B,OAAO,SAA8B;CAInD;AAED,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,MAAM,CAAC,IAAI,SAAoC;gBAElC,OAAO,SAAiC;CAItD;AAED,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,MAAM,CAAC,IAAI,SAAmC;gBAEjC,OAAO,SAAgC;CAIrD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,MAAM,CAAC,IAAI,SAAsB;gBAEpB,OAAO,SAAkB;CAIvC;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,MAAM,CAAC,IAAI,SAAsB;gBAEpB,OAAO,SAAkB;CAIvC"}
|
package/dist/src/errors.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
export class DNSLinkNotFoundError extends Error {
|
|
2
|
-
static name = 'DNSLinkNotFoundError';
|
|
3
|
-
constructor(message = 'DNSLink not found') {
|
|
4
|
-
super(message);
|
|
5
|
-
this.name = 'DNSLinkNotFoundError';
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
1
|
export class RecordsFailedValidationError extends Error {
|
|
9
2
|
static name = 'RecordsFailedValidationError';
|
|
10
3
|
constructor(message = 'Records failed validation') {
|
package/dist/src/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACrD,MAAM,CAAC,IAAI,GAAG,8BAA8B,CAAA;IAE5C,YAAa,OAAO,GAAG,2BAA2B;QAChD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAA;IAC5C,CAAC;;AAGH,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IACxD,MAAM,CAAC,IAAI,GAAG,iCAAiC,CAAA;IAE/C,YAAa,OAAO,GAAG,8BAA8B;QACnD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAA;IAC/C,CAAC;;AAGH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD,MAAM,CAAC,IAAI,GAAG,gCAAgC,CAAA;IAE9C,YAAa,OAAO,GAAG,6BAA6B;QAClD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAA;IAC9C,CAAC;;AAGH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,MAAM,CAAC,IAAI,GAAG,mBAAmB,CAAA;IAEjC,YAAa,OAAO,GAAG,eAAe;QACpC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IACjC,CAAC;;AAGH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,MAAM,CAAC,IAAI,GAAG,mBAAmB,CAAA;IAEjC,YAAa,OAAO,GAAG,eAAe;QACpC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IACjC,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
*
|
|
4
|
-
* IPNS operations using a Helia node
|
|
4
|
+
* [IPNS](https://docs.ipfs.tech/concepts/ipns/) operations using a Helia node
|
|
5
5
|
*
|
|
6
6
|
* @example Getting started
|
|
7
7
|
*
|
|
@@ -11,23 +11,19 @@
|
|
|
11
11
|
* import { createHelia } from 'helia'
|
|
12
12
|
* import { ipns } from '@helia/ipns'
|
|
13
13
|
* import { unixfs } from '@helia/unixfs'
|
|
14
|
-
* import { generateKeyPair } from '@libp2p/crypto/keys'
|
|
15
14
|
*
|
|
16
15
|
* const helia = await createHelia()
|
|
17
16
|
* const name = ipns(helia)
|
|
18
17
|
*
|
|
19
|
-
* // create a keypair to publish an IPNS name
|
|
20
|
-
* const privateKey = await generateKeyPair('Ed25519')
|
|
21
|
-
*
|
|
22
18
|
* // store some data to publish
|
|
23
19
|
* const fs = unixfs(helia)
|
|
24
20
|
* const cid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
|
|
25
21
|
*
|
|
26
22
|
* // publish the name
|
|
27
|
-
* await name.publish(
|
|
23
|
+
* const { publicKey } = await name.publish('key-1', cid)
|
|
28
24
|
*
|
|
29
25
|
* // resolve the name
|
|
30
|
-
* const result = await name.resolve(
|
|
26
|
+
* const result = await name.resolve(publicKey)
|
|
31
27
|
*
|
|
32
28
|
* console.info(result.cid, result.path)
|
|
33
29
|
* ```
|
|
@@ -46,24 +42,18 @@
|
|
|
46
42
|
* const helia = await createHelia()
|
|
47
43
|
* const name = ipns(helia)
|
|
48
44
|
*
|
|
49
|
-
* // create a keypair to publish an IPNS name
|
|
50
|
-
* const privateKey = await generateKeyPair('Ed25519')
|
|
51
|
-
*
|
|
52
45
|
* // store some data to publish
|
|
53
46
|
* const fs = unixfs(helia)
|
|
54
47
|
* const cid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
|
|
55
48
|
*
|
|
56
49
|
* // publish the name
|
|
57
|
-
* await name.publish(
|
|
58
|
-
*
|
|
59
|
-
* // create another keypair to re-publish the original record
|
|
60
|
-
* const recursivePrivateKey = await generateKeyPair('Ed25519')
|
|
50
|
+
* const { publicKey } = await name.publish('key-1', cid)
|
|
61
51
|
*
|
|
62
52
|
* // publish the recursive name
|
|
63
|
-
* await name.publish(
|
|
53
|
+
* const { publicKey: recursivePublicKey } = await name.publish('key-2', publicKey)
|
|
64
54
|
*
|
|
65
55
|
* // resolve the name recursively - it resolves until a CID is found
|
|
66
|
-
* const result = await name.resolve(
|
|
56
|
+
* const result = await name.resolve(recursivePublicKey)
|
|
67
57
|
* console.info(result.cid.toString() === cid.toString()) // true
|
|
68
58
|
* ```
|
|
69
59
|
*
|
|
@@ -80,9 +70,6 @@
|
|
|
80
70
|
* const helia = await createHelia()
|
|
81
71
|
* const name = ipns(helia)
|
|
82
72
|
*
|
|
83
|
-
* // create a keypair to publish an IPNS name
|
|
84
|
-
* const privateKey = await generateKeyPair('Ed25519')
|
|
85
|
-
*
|
|
86
73
|
* // store some data to publish
|
|
87
74
|
* const fs = unixfs(helia)
|
|
88
75
|
* const fileCid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
|
|
@@ -92,10 +79,10 @@
|
|
|
92
79
|
* const finalDirCid = await fs.cp(fileCid, dirCid, '/foo.txt')
|
|
93
80
|
*
|
|
94
81
|
* // publish the name
|
|
95
|
-
* await name.publish(
|
|
82
|
+
* const { publicKey } = await name.publish('key-1', `/ipfs/${finalDirCid}/foo.txt`)
|
|
96
83
|
*
|
|
97
84
|
* // resolve the name
|
|
98
|
-
* const result = await name.resolve(
|
|
85
|
+
* const result = await name.resolve(publicKey)
|
|
99
86
|
*
|
|
100
87
|
* console.info(result.cid, result.path) // QmFoo.. 'foo.txt'
|
|
101
88
|
* ```
|
|
@@ -121,13 +108,14 @@
|
|
|
121
108
|
* import { ipns } from '@helia/ipns'
|
|
122
109
|
* import { pubsub } from '@helia/ipns/routing'
|
|
123
110
|
* import { unixfs } from '@helia/unixfs'
|
|
124
|
-
* import {
|
|
111
|
+
* import { floodsub } from '@libp2p/floodsub'
|
|
125
112
|
* import { generateKeyPair } from '@libp2p/crypto/keys'
|
|
126
|
-
* import type {
|
|
113
|
+
* import type { PubSub } from '@helia/ipns/routing'
|
|
114
|
+
* import type { Libp2p } from '@libp2p/interface'
|
|
127
115
|
* import type { DefaultLibp2pServices } from 'helia'
|
|
128
116
|
*
|
|
129
117
|
* const libp2pOptions = libp2pDefaults()
|
|
130
|
-
* libp2pOptions.services.pubsub =
|
|
118
|
+
* libp2pOptions.services.pubsub = floodsub()
|
|
131
119
|
*
|
|
132
120
|
* const helia = await createHelia<Libp2p<DefaultLibp2pServices & { pubsub: PubSub }>>({
|
|
133
121
|
* libp2p: libp2pOptions
|
|
@@ -138,133 +126,30 @@
|
|
|
138
126
|
* ]
|
|
139
127
|
* })
|
|
140
128
|
*
|
|
141
|
-
* // create a keypair to publish an IPNS name
|
|
142
|
-
* const privateKey = await generateKeyPair('Ed25519')
|
|
143
129
|
*
|
|
144
130
|
* // store some data to publish
|
|
145
131
|
* const fs = unixfs(helia)
|
|
146
132
|
* const cid = await fs.addBytes(Uint8Array.from([0, 1, 2, 3, 4]))
|
|
147
133
|
*
|
|
148
134
|
* // publish the name
|
|
149
|
-
* await name.publish(
|
|
135
|
+
* const { publicKey } = await name.publish('key-1', cid)
|
|
150
136
|
*
|
|
151
137
|
* // resolve the name
|
|
152
|
-
* const result = await name.resolve(
|
|
153
|
-
* ```
|
|
154
|
-
*
|
|
155
|
-
* @example Using custom DNS over HTTPS resolvers
|
|
156
|
-
*
|
|
157
|
-
* To use custom resolvers, configure Helia's `dns` option:
|
|
158
|
-
*
|
|
159
|
-
* ```TypeScript
|
|
160
|
-
* import { createHelia } from 'helia'
|
|
161
|
-
* import { ipns } from '@helia/ipns'
|
|
162
|
-
* import { dns } from '@multiformats/dns'
|
|
163
|
-
* import { dnsOverHttps } from '@multiformats/dns/resolvers'
|
|
164
|
-
* import { helia } from '@helia/ipns/routing'
|
|
165
|
-
*
|
|
166
|
-
* const node = await createHelia({
|
|
167
|
-
* dns: dns({
|
|
168
|
-
* resolvers: {
|
|
169
|
-
* '.': dnsOverHttps('https://private-dns-server.me/dns-query')
|
|
170
|
-
* }
|
|
171
|
-
* })
|
|
172
|
-
* })
|
|
173
|
-
* const name = ipns(node, {
|
|
174
|
-
* routers: [
|
|
175
|
-
* helia(node.routing)
|
|
176
|
-
* ]
|
|
177
|
-
* })
|
|
178
|
-
*
|
|
179
|
-
* const result = name.resolveDNSLink('some-domain-with-dnslink-entry.com')
|
|
180
|
-
* ```
|
|
181
|
-
*
|
|
182
|
-
* @example Resolving a domain with a dnslink entry
|
|
183
|
-
*
|
|
184
|
-
* Calling `resolveDNSLink` with the `@helia/ipns` instance:
|
|
185
|
-
*
|
|
186
|
-
* ```TypeScript
|
|
187
|
-
* // resolve a CID from a TXT record in a DNS zone file, using the default
|
|
188
|
-
* // resolver for the current platform eg:
|
|
189
|
-
* // > dig _dnslink.ipfs.io TXT
|
|
190
|
-
* // ;; ANSWER SECTION:
|
|
191
|
-
* // _dnslink.ipfs.io. 60 IN TXT "dnslink=/ipns/website.ipfs.io"
|
|
192
|
-
* // > dig _dnslink.website.ipfs.io TXT
|
|
193
|
-
* // ;; ANSWER SECTION:
|
|
194
|
-
* // _dnslink.website.ipfs.io. 60 IN TXT "dnslink=/ipfs/QmWebsite"
|
|
195
|
-
*
|
|
196
|
-
* import { createHelia } from 'helia'
|
|
197
|
-
* import { ipns } from '@helia/ipns'
|
|
198
|
-
*
|
|
199
|
-
* const node = await createHelia()
|
|
200
|
-
* const name = ipns(node)
|
|
201
|
-
*
|
|
202
|
-
* const { answer } = await name.resolveDNSLink('ipfs.io')
|
|
203
|
-
*
|
|
204
|
-
* console.info(answer)
|
|
205
|
-
* // { data: '/ipfs/QmWebsite' }
|
|
206
|
-
* ```
|
|
207
|
-
*
|
|
208
|
-
* @example Using DNS-Over-HTTPS
|
|
209
|
-
*
|
|
210
|
-
* This example uses the Mozilla provided RFC 1035 DNS over HTTPS service. This
|
|
211
|
-
* uses binary DNS records so requires extra dependencies to process the
|
|
212
|
-
* response which can increase browser bundle sizes.
|
|
213
|
-
*
|
|
214
|
-
* If this is a concern, use the DNS-JSON-Over-HTTPS resolver instead.
|
|
215
|
-
*
|
|
216
|
-
* ```TypeScript
|
|
217
|
-
* import { createHelia } from 'helia'
|
|
218
|
-
* import { ipns } from '@helia/ipns'
|
|
219
|
-
* import { dns } from '@multiformats/dns'
|
|
220
|
-
* import { dnsOverHttps } from '@multiformats/dns/resolvers'
|
|
221
|
-
*
|
|
222
|
-
* const node = await createHelia({
|
|
223
|
-
* dns: dns({
|
|
224
|
-
* resolvers: {
|
|
225
|
-
* '.': dnsOverHttps('https://mozilla.cloudflare-dns.com/dns-query')
|
|
226
|
-
* }
|
|
227
|
-
* })
|
|
228
|
-
* })
|
|
229
|
-
* const name = ipns(node)
|
|
230
|
-
*
|
|
231
|
-
* const result = await name.resolveDNSLink('ipfs.io')
|
|
232
|
-
* ```
|
|
233
|
-
*
|
|
234
|
-
* @example Using DNS-JSON-Over-HTTPS
|
|
235
|
-
*
|
|
236
|
-
* DNS-JSON-Over-HTTPS resolvers use the RFC 8427 `application/dns-json` and can
|
|
237
|
-
* result in a smaller browser bundle due to the response being plain JSON.
|
|
238
|
-
*
|
|
239
|
-
* ```TypeScript
|
|
240
|
-
* import { createHelia } from 'helia'
|
|
241
|
-
* import { ipns } from '@helia/ipns'
|
|
242
|
-
* import { dns } from '@multiformats/dns'
|
|
243
|
-
* import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
|
244
|
-
*
|
|
245
|
-
* const node = await createHelia({
|
|
246
|
-
* dns: dns({
|
|
247
|
-
* resolvers: {
|
|
248
|
-
* '.': dnsJsonOverHttps('https://mozilla.cloudflare-dns.com/dns-query')
|
|
249
|
-
* }
|
|
250
|
-
* })
|
|
251
|
-
* })
|
|
252
|
-
* const name = ipns(node)
|
|
253
|
-
*
|
|
254
|
-
* const result = await name.resolveDNSLink('ipfs.io')
|
|
138
|
+
* const result = await name.resolve(publicKey)
|
|
255
139
|
* ```
|
|
256
140
|
*
|
|
257
141
|
* @example Republishing an existing IPNS record
|
|
258
142
|
*
|
|
259
|
-
*
|
|
260
|
-
* needing the private key. This
|
|
261
|
-
*
|
|
143
|
+
* It is sometimes useful to be able to republish an existing IPNS record
|
|
144
|
+
* without needing the private key. This allows you to extend the availability
|
|
145
|
+
* of a record that was created elsewhere.
|
|
262
146
|
*
|
|
263
147
|
* ```TypeScript
|
|
264
148
|
* import { createHelia } from 'helia'
|
|
265
|
-
* import { ipns } from '@helia/ipns'
|
|
149
|
+
* import { ipns, ipnsValidator } from '@helia/ipns'
|
|
266
150
|
* import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
|
|
267
151
|
* import { CID } from 'multiformats/cid'
|
|
152
|
+
* import { multihashToIPNSRoutingKey, marshalIPNSRecord } from 'ipns'
|
|
268
153
|
*
|
|
269
154
|
* const helia = await createHelia()
|
|
270
155
|
* const name = ipns(helia)
|
|
@@ -274,28 +159,35 @@
|
|
|
274
159
|
* const delegatedClient = createDelegatedRoutingV1HttpApiClient('https://delegated-ipfs.dev')
|
|
275
160
|
* const record = await delegatedClient.getIPNS(parsedCid)
|
|
276
161
|
*
|
|
277
|
-
*
|
|
162
|
+
* const routingKey = multihashToIPNSRoutingKey(parsedCid.multihash)
|
|
163
|
+
* const marshaledRecord = marshalIPNSRecord(record)
|
|
164
|
+
*
|
|
165
|
+
* // validate that they key corresponds to the record
|
|
166
|
+
* await ipnsValidator(routingKey, marshaledRecord)
|
|
167
|
+
*
|
|
168
|
+
* // publish record to routing
|
|
169
|
+
* await Promise.all(
|
|
170
|
+
* name.routers.map(async r => {
|
|
171
|
+
* await r.put(routingKey, marshaledRecord)
|
|
172
|
+
* })
|
|
173
|
+
* )
|
|
278
174
|
* ```
|
|
279
175
|
*/
|
|
280
176
|
import { ipnsValidator } from 'ipns/validator';
|
|
281
177
|
import { CID } from 'multiformats/cid';
|
|
282
|
-
import type {
|
|
283
|
-
import type {
|
|
284
|
-
import type {
|
|
285
|
-
import type {
|
|
178
|
+
import type { IPNSResolverComponents } from './ipns/resolver.js';
|
|
179
|
+
import type { IPNSRouting, IPNSRoutingProgressEvents } from './routing/index.js';
|
|
180
|
+
import type { Routing, HeliaEvents } from '@helia/interface';
|
|
181
|
+
import type { AbortOptions, ComponentLogger, Libp2p, PeerId, PublicKey, TypedEventEmitter } from '@libp2p/interface';
|
|
182
|
+
import type { Keychain } from '@libp2p/keychain';
|
|
286
183
|
import type { Datastore } from 'interface-datastore';
|
|
287
184
|
import type { IPNSRecord } from 'ipns';
|
|
288
185
|
import type { MultihashDigest } from 'multiformats/hashes/interface';
|
|
289
186
|
import type { ProgressEvent, ProgressOptions } from 'progress-events';
|
|
290
187
|
export type PublishProgressEvents = ProgressEvent<'ipns:publish:start'> | ProgressEvent<'ipns:publish:success', IPNSRecord> | ProgressEvent<'ipns:publish:error', Error>;
|
|
291
188
|
export type ResolveProgressEvents = ProgressEvent<'ipns:resolve:start', unknown> | ProgressEvent<'ipns:resolve:success', IPNSRecord> | ProgressEvent<'ipns:resolve:error', Error>;
|
|
292
|
-
export type
|
|
293
|
-
|
|
294
|
-
record: IPNSRecord;
|
|
295
|
-
err: Error;
|
|
296
|
-
}>;
|
|
297
|
-
export type ResolveDNSLinkProgressEvents = ResolveProgressEvents | IPNSRoutingEvents | ResolveDnsProgressEvents;
|
|
298
|
-
export interface PublishOptions extends AbortOptions, ProgressOptions<PublishProgressEvents | IPNSRoutingEvents> {
|
|
189
|
+
export type DatastoreProgressEvents = ProgressEvent<'ipns:routing:datastore:put'> | ProgressEvent<'ipns:routing:datastore:get'> | ProgressEvent<'ipns:routing:datastore:list'> | ProgressEvent<'ipns:routing:datastore:error', Error>;
|
|
190
|
+
export interface PublishOptions extends AbortOptions, ProgressOptions<PublishProgressEvents | IPNSRoutingProgressEvents> {
|
|
299
191
|
/**
|
|
300
192
|
* Time duration of the signature validity in ms (default: 48hrs)
|
|
301
193
|
*/
|
|
@@ -314,7 +206,11 @@ export interface PublishOptions extends AbortOptions, ProgressOptions<PublishPro
|
|
|
314
206
|
*/
|
|
315
207
|
ttl?: number;
|
|
316
208
|
}
|
|
317
|
-
export interface
|
|
209
|
+
export interface IPNSRecordMetadata {
|
|
210
|
+
keyName: string;
|
|
211
|
+
lifetime: number;
|
|
212
|
+
}
|
|
213
|
+
export interface ResolveOptions extends AbortOptions, ProgressOptions<ResolveProgressEvents | IPNSRoutingProgressEvents> {
|
|
318
214
|
/**
|
|
319
215
|
* Do not query the network for the IPNS record
|
|
320
216
|
*
|
|
@@ -328,41 +224,6 @@ export interface ResolveOptions extends AbortOptions, ProgressOptions<ResolvePro
|
|
|
328
224
|
*/
|
|
329
225
|
nocache?: boolean;
|
|
330
226
|
}
|
|
331
|
-
export interface ResolveDNSLinkOptions extends AbortOptions, ProgressOptions<ResolveDNSLinkProgressEvents> {
|
|
332
|
-
/**
|
|
333
|
-
* Do not query the network for the IPNS record
|
|
334
|
-
*
|
|
335
|
-
* @default false
|
|
336
|
-
*/
|
|
337
|
-
offline?: boolean;
|
|
338
|
-
/**
|
|
339
|
-
* Do not use cached DNS entries
|
|
340
|
-
*
|
|
341
|
-
* @default false
|
|
342
|
-
*/
|
|
343
|
-
nocache?: boolean;
|
|
344
|
-
/**
|
|
345
|
-
* When resolving DNSLink records that resolve to other DNSLink records, limit
|
|
346
|
-
* how many times we will recursively resolve them.
|
|
347
|
-
*
|
|
348
|
-
* @default 32
|
|
349
|
-
*/
|
|
350
|
-
maxRecursiveDepth?: number;
|
|
351
|
-
}
|
|
352
|
-
export interface RepublishOptions extends AbortOptions, ProgressOptions<RepublishProgressEvents | IPNSRoutingEvents> {
|
|
353
|
-
/**
|
|
354
|
-
* The republish interval in ms (default: 23hrs)
|
|
355
|
-
*/
|
|
356
|
-
interval?: number;
|
|
357
|
-
}
|
|
358
|
-
export interface RepublishRecordOptions extends AbortOptions, ProgressOptions<RepublishProgressEvents | IPNSRoutingEvents> {
|
|
359
|
-
/**
|
|
360
|
-
* Only publish to a local datastore
|
|
361
|
-
*
|
|
362
|
-
* @default false
|
|
363
|
-
*/
|
|
364
|
-
offline?: boolean;
|
|
365
|
-
}
|
|
366
227
|
export interface ResolveResult {
|
|
367
228
|
/**
|
|
368
229
|
* The CID that was resolved
|
|
@@ -370,10 +231,8 @@ export interface ResolveResult {
|
|
|
370
231
|
cid: CID;
|
|
371
232
|
/**
|
|
372
233
|
* Any path component that was part of the resolved record
|
|
373
|
-
*
|
|
374
|
-
* @default ""
|
|
375
234
|
*/
|
|
376
|
-
path
|
|
235
|
+
path?: string;
|
|
377
236
|
}
|
|
378
237
|
export interface IPNSResolveResult extends ResolveResult {
|
|
379
238
|
/**
|
|
@@ -381,52 +240,117 @@ export interface IPNSResolveResult extends ResolveResult {
|
|
|
381
240
|
*/
|
|
382
241
|
record: IPNSRecord;
|
|
383
242
|
}
|
|
384
|
-
export interface
|
|
243
|
+
export interface IPNSPublishResult {
|
|
385
244
|
/**
|
|
386
|
-
* The
|
|
245
|
+
* The published record
|
|
387
246
|
*/
|
|
388
|
-
|
|
247
|
+
record: IPNSRecord;
|
|
248
|
+
/**
|
|
249
|
+
* The public key that was used to publish the record
|
|
250
|
+
*/
|
|
251
|
+
publicKey: PublicKey;
|
|
389
252
|
}
|
|
390
|
-
export interface
|
|
253
|
+
export interface IPNSResolver {
|
|
391
254
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
255
|
+
* Accepts a libp2p public key, a CID with the libp2p-key codec and either the
|
|
256
|
+
* identity hash (for Ed25519 and secp256k1 public keys) or a SHA256 hash (for
|
|
257
|
+
* RSA public keys), or the multihash of a libp2p-key encoded CID, or a
|
|
258
|
+
* Ed25519, secp256k1 or RSA PeerId and recursively resolves the IPNS record
|
|
259
|
+
* corresponding to that key until a value is found.
|
|
395
260
|
*/
|
|
396
|
-
|
|
261
|
+
resolve(key: CID<unknown, 0x72, 0x00 | 0x12, 1> | PublicKey | MultihashDigest<0x00 | 0x12> | PeerId, options?: ResolveOptions): Promise<IPNSResolveResult>;
|
|
262
|
+
}
|
|
263
|
+
export interface IPNS {
|
|
397
264
|
/**
|
|
398
|
-
*
|
|
399
|
-
* corresponding to that public key until a value is found
|
|
265
|
+
* Configured routing subsystems used to publish/resolve IPNS names
|
|
400
266
|
*/
|
|
401
|
-
|
|
267
|
+
routers: IPNSRouting[];
|
|
402
268
|
/**
|
|
403
|
-
*
|
|
269
|
+
* Creates and publishes an IPNS record that will resolve the passed value
|
|
270
|
+
* signed by a key stored in the libp2p keychain under the passed key name.
|
|
271
|
+
*
|
|
272
|
+
* It is possible to create a recursive IPNS record by passing:
|
|
273
|
+
*
|
|
274
|
+
* - A PeerId,
|
|
275
|
+
* - A PublicKey
|
|
276
|
+
* - A CID with the libp2p-key codec and Identity or SHA256 hash algorithms
|
|
277
|
+
* - A Multihash with the Identity or SHA256 hash algorithms
|
|
278
|
+
* - A string IPNS key (e.g. `/ipns/Qmfoo`)
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
*
|
|
282
|
+
* ```TypeScript
|
|
283
|
+
* import { createHelia } from 'helia'
|
|
284
|
+
* import { ipns } from '@helia/ipns'
|
|
285
|
+
*
|
|
286
|
+
* const helia = await createHelia()
|
|
287
|
+
* const name = ipns(helia)
|
|
288
|
+
*
|
|
289
|
+
* const result = await name.publish('my-key-name', cid, {
|
|
290
|
+
* signal: AbortSignal.timeout(5_000)
|
|
291
|
+
* })
|
|
292
|
+
*
|
|
293
|
+
* console.info(result) // { answer: ... }
|
|
294
|
+
* ```
|
|
404
295
|
*/
|
|
405
|
-
|
|
296
|
+
publish(keyName: string, value: CID | PublicKey | MultihashDigest<0x00 | 0x12> | PeerId | string, options?: PublishOptions): Promise<IPNSPublishResult>;
|
|
406
297
|
/**
|
|
407
|
-
*
|
|
298
|
+
* Accepts a libp2p public key, a CID with the libp2p-key codec and either the
|
|
299
|
+
* identity hash (for Ed25519 and secp256k1 public keys) or a SHA256 hash (for
|
|
300
|
+
* RSA public keys), or the multihash of a libp2p-key encoded CID, or a
|
|
301
|
+
* Ed25519, secp256k1 or RSA PeerId and recursively resolves the IPNS record
|
|
302
|
+
* corresponding to that key until a value is found.
|
|
408
303
|
*/
|
|
409
|
-
|
|
304
|
+
resolve(key: CID<unknown, 0x72, 0x00 | 0x12, 1> | PublicKey | MultihashDigest<0x00 | 0x12> | PeerId, options?: ResolveOptions): Promise<IPNSResolveResult>;
|
|
410
305
|
/**
|
|
411
|
-
*
|
|
306
|
+
* Stop republishing of an IPNS record
|
|
412
307
|
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
308
|
+
* This will delete the last signed IPNS record from the datastore, but the
|
|
309
|
+
* key will remain in the keychain.
|
|
310
|
+
*
|
|
311
|
+
* Note that the record may still be resolved by other peers until it expires
|
|
312
|
+
* or is no longer valid.
|
|
415
313
|
*/
|
|
416
|
-
|
|
314
|
+
unpublish(keyName: string, options?: AbortOptions): Promise<void>;
|
|
417
315
|
}
|
|
418
316
|
export type { IPNSRouting } from './routing/index.js';
|
|
419
317
|
export type { IPNSRecord } from 'ipns';
|
|
420
318
|
export interface IPNSComponents {
|
|
421
319
|
datastore: Datastore;
|
|
422
320
|
routing: Routing;
|
|
423
|
-
dns: DNS;
|
|
424
321
|
logger: ComponentLogger;
|
|
322
|
+
libp2p: Libp2p<{
|
|
323
|
+
keychain: Keychain;
|
|
324
|
+
}>;
|
|
325
|
+
events: TypedEventEmitter<HeliaEvents>;
|
|
425
326
|
}
|
|
426
327
|
export interface IPNSOptions {
|
|
328
|
+
/**
|
|
329
|
+
* Different routing systems for IPNS publishing/resolving
|
|
330
|
+
*/
|
|
331
|
+
routers?: IPNSRouting[];
|
|
332
|
+
/**
|
|
333
|
+
* How often to check if published records have expired and need republishing
|
|
334
|
+
* in ms
|
|
335
|
+
*
|
|
336
|
+
* @default 3_600_000
|
|
337
|
+
*/
|
|
338
|
+
republishInterval?: number;
|
|
339
|
+
/**
|
|
340
|
+
* How many IPNS records to republish at once
|
|
341
|
+
*
|
|
342
|
+
* @default 5
|
|
343
|
+
*/
|
|
344
|
+
republishConcurrency?: number;
|
|
345
|
+
}
|
|
346
|
+
export interface IPNSResolverOptions {
|
|
347
|
+
/**
|
|
348
|
+
* Different routing systems for IPNS publishing/resolving
|
|
349
|
+
*/
|
|
427
350
|
routers?: IPNSRouting[];
|
|
428
351
|
}
|
|
429
|
-
export declare function ipns(components: IPNSComponents,
|
|
430
|
-
export
|
|
352
|
+
export declare function ipns(components: IPNSComponents, options?: IPNSOptions): IPNS;
|
|
353
|
+
export declare function ipnsResolver(components: IPNSResolverComponents, options?: IPNSResolverOptions): IPNSResolver;
|
|
354
|
+
export { ipnsValidator, type IPNSRoutingProgressEvents };
|
|
431
355
|
export { ipnsSelector } from 'ipns/selector';
|
|
432
356
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|