@helia/ipns 6.0.1-a64e5de → 6.0.1-adc5589
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/dist/index.min.js +4 -4
- package/dist/src/dnslink.d.ts +5 -0
- package/dist/src/dnslink.d.ts.map +1 -0
- package/dist/src/dnslink.js +123 -0
- package/dist/src/dnslink.js.map +1 -0
- package/dist/src/index.d.ts +24 -22
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +24 -9
- package/dist/src/index.js.map +1 -1
- package/package.json +3 -6
- package/src/dnslink.ts +141 -0
- package/src/index.ts +50 -36
- package/dist/src/dns-resolvers/default.d.ts +0 -3
- package/dist/src/dns-resolvers/default.d.ts.map +0 -1
- package/dist/src/dns-resolvers/default.js +0 -8
- package/dist/src/dns-resolvers/default.js.map +0 -1
- package/dist/src/dns-resolvers/dns-json-over-https.d.ts +0 -18
- package/dist/src/dns-resolvers/dns-json-over-https.d.ts.map +0 -1
- package/dist/src/dns-resolvers/dns-json-over-https.js +0 -72
- package/dist/src/dns-resolvers/dns-json-over-https.js.map +0 -1
- package/dist/src/dns-resolvers/dns-over-https.d.ts +0 -16
- package/dist/src/dns-resolvers/dns-over-https.d.ts.map +0 -1
- package/dist/src/dns-resolvers/dns-over-https.js +0 -123
- package/dist/src/dns-resolvers/dns-over-https.js.map +0 -1
- package/dist/src/dns-resolvers/index.d.ts +0 -3
- package/dist/src/dns-resolvers/index.d.ts.map +0 -1
- package/dist/src/dns-resolvers/index.js +0 -3
- package/dist/src/dns-resolvers/index.js.map +0 -1
- package/dist/src/dns-resolvers/resolver.browser.d.ts +0 -4
- package/dist/src/dns-resolvers/resolver.browser.d.ts.map +0 -1
- package/dist/src/dns-resolvers/resolver.browser.js +0 -39
- package/dist/src/dns-resolvers/resolver.browser.js.map +0 -1
- package/dist/src/dns-resolvers/resolver.d.ts +0 -4
- package/dist/src/dns-resolvers/resolver.d.ts.map +0 -1
- package/dist/src/dns-resolvers/resolver.js +0 -21
- package/dist/src/dns-resolvers/resolver.js.map +0 -1
- package/dist/src/utils/dns.d.ts +0 -35
- package/dist/src/utils/dns.d.ts.map +0 -1
- package/dist/src/utils/dns.js +0 -80
- package/dist/src/utils/dns.js.map +0 -1
- package/dist/src/utils/tlru.d.ts +0 -15
- package/dist/src/utils/tlru.d.ts.map +0 -1
- package/dist/src/utils/tlru.js +0 -40
- package/dist/src/utils/tlru.js.map +0 -1
- package/src/dns-resolvers/default.ts +0 -9
- package/src/dns-resolvers/dns-json-over-https.ts +0 -90
- package/src/dns-resolvers/dns-over-https.ts +0 -146
- package/src/dns-resolvers/index.ts +0 -2
- package/src/dns-resolvers/resolver.browser.ts +0 -50
- package/src/dns-resolvers/resolver.ts +0 -25
- package/src/utils/dns.ts +0 -127
- package/src/utils/tlru.ts +0 -52
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Logger } from '@libp2p/interface';
|
|
2
|
+
import type { ResolveDNSLinkOptions } from './index.js';
|
|
3
|
+
import type { DNS } from '@multiformats/dns';
|
|
4
|
+
export declare function resolveDNSLink(domain: string, dns: DNS, log: Logger, options?: ResolveDNSLinkOptions): Promise<string>;
|
|
5
|
+
//# sourceMappingURL=dnslink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dnslink.d.ts","sourceRoot":"","sources":["../../src/dnslink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAI1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAqI5C,wBAAsB,cAAc,CAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjI"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { CodeError } from '@libp2p/interface';
|
|
2
|
+
import { peerIdFromString } from '@libp2p/peer-id';
|
|
3
|
+
import { RecordType } from '@multiformats/dns';
|
|
4
|
+
import { CID } from 'multiformats/cid';
|
|
5
|
+
const MAX_RECURSIVE_DEPTH = 32;
|
|
6
|
+
async function recursiveResolveDnslink(domain, depth, dns, log, options = {}) {
|
|
7
|
+
if (depth === 0) {
|
|
8
|
+
throw new Error('recursion limit exceeded');
|
|
9
|
+
}
|
|
10
|
+
log('query %s for TXT records', domain);
|
|
11
|
+
const txtRecordsResponse = await dns.query(domain, {
|
|
12
|
+
...options,
|
|
13
|
+
types: [
|
|
14
|
+
RecordType.TXT
|
|
15
|
+
]
|
|
16
|
+
});
|
|
17
|
+
// sort the TXT records to ensure deterministic processing
|
|
18
|
+
const txtRecords = txtRecordsResponse.Answer
|
|
19
|
+
.sort((a, b) => a.data.localeCompare(b.data));
|
|
20
|
+
log('found %d TXT records for %s', txtRecords.length, domain);
|
|
21
|
+
for (const answer of txtRecords) {
|
|
22
|
+
try {
|
|
23
|
+
let result = answer.data;
|
|
24
|
+
// strip leading and trailing " characters
|
|
25
|
+
if (result.startsWith('"') && result.endsWith('"')) {
|
|
26
|
+
result = result.substring(1, result.length - 1);
|
|
27
|
+
}
|
|
28
|
+
if (!result.startsWith('dnslink=')) {
|
|
29
|
+
// invalid record?
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
log('%s TXT %s', answer.name, result);
|
|
33
|
+
result = result.replace('dnslink=', '');
|
|
34
|
+
// result is now a `/ipfs/<cid>` or `/ipns/<cid>` string
|
|
35
|
+
const [, protocol, domainOrCID, ...rest] = result.split('/'); // e.g. ["", "ipfs", "<cid>"]
|
|
36
|
+
if (protocol === 'ipfs') {
|
|
37
|
+
try {
|
|
38
|
+
const cid = CID.parse(domainOrCID);
|
|
39
|
+
// if the result is a CID, we've reached the end of the recursion
|
|
40
|
+
return `/ipfs/${cid}${rest.length > 0 ? `/${rest.join('/')}` : ''}`;
|
|
41
|
+
}
|
|
42
|
+
catch { }
|
|
43
|
+
}
|
|
44
|
+
else if (protocol === 'ipns') {
|
|
45
|
+
try {
|
|
46
|
+
const peerId = peerIdFromString(domainOrCID);
|
|
47
|
+
// if the result is a PeerId, we've reached the end of the recursion
|
|
48
|
+
return `/ipns/${peerId}${rest.length > 0 ? `/${rest.join('/')}` : ''}`;
|
|
49
|
+
}
|
|
50
|
+
catch { }
|
|
51
|
+
// if the result was another IPNS domain, try to follow it
|
|
52
|
+
return await recursiveResolveDomain(domainOrCID, depth - 1, dns, log, options);
|
|
53
|
+
}
|
|
54
|
+
else if (protocol === 'dnslink') {
|
|
55
|
+
// if the result was another DNSLink domain, try to follow it
|
|
56
|
+
return await recursiveResolveDomain(domainOrCID, depth - 1, dns, log, options);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
log('unknown protocol "%s" in DNSLink record for domain: %s', protocol, domain);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
log.error('could not parse DNS link record for domain %s, %s', domain, answer.data, err);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// see if there is a CNAME delegation
|
|
68
|
+
log('no DNSLink records found for %s, falling back to CNAME', domain);
|
|
69
|
+
const cnameRecordsResponse = await dns.query(domain, {
|
|
70
|
+
...options,
|
|
71
|
+
types: [
|
|
72
|
+
RecordType.CNAME
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
// sort the CNAME records to ensure deterministic processing
|
|
76
|
+
const cnameRecords = cnameRecordsResponse.Answer
|
|
77
|
+
.sort((a, b) => a.data.localeCompare(b.data));
|
|
78
|
+
log('found %d CNAME records for %s', cnameRecords.length, domain);
|
|
79
|
+
for (const cname of cnameRecords) {
|
|
80
|
+
try {
|
|
81
|
+
return await recursiveResolveDomain(cname.data, depth - 1, dns, log, options);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
log.error('domain %s cname %s had no DNSLink records', domain, cname.data, err);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
throw new CodeError(`No DNSLink records found for domain: ${domain}`, 'ERR_DNSLINK_NOT_FOUND');
|
|
88
|
+
}
|
|
89
|
+
async function recursiveResolveDomain(domain, depth, dns, log, options = {}) {
|
|
90
|
+
if (depth === 0) {
|
|
91
|
+
throw new Error('recursion limit exceeded');
|
|
92
|
+
}
|
|
93
|
+
// the DNSLink spec says records MUST be stored on the `_dnslink.` subdomain
|
|
94
|
+
// so start looking for records there, we will fall back to the bare domain
|
|
95
|
+
// if none are found
|
|
96
|
+
if (!domain.startsWith('_dnslink.')) {
|
|
97
|
+
domain = `_dnslink.${domain}`;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
return await recursiveResolveDnslink(domain, depth, dns, log, options);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
// If the code is not ENOTFOUND or ERR_DNSLINK_NOT_FOUND or ENODATA then throw the error
|
|
104
|
+
if (err.code !== 'ENOTFOUND' && err.code !== 'ERR_DNSLINK_NOT_FOUND' && err.code !== 'ENODATA') {
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
if (domain.startsWith('_dnslink.')) {
|
|
108
|
+
// The supplied domain contains a _dnslink component
|
|
109
|
+
// Check the non-_dnslink domain
|
|
110
|
+
domain = domain.replace('_dnslink.', '');
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// Check the _dnslink subdomain
|
|
114
|
+
domain = `_dnslink.${domain}`;
|
|
115
|
+
}
|
|
116
|
+
// If this throws then we propagate the error
|
|
117
|
+
return await recursiveResolveDnslink(domain, depth, dns, log, options);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export async function resolveDNSLink(domain, dns, log, options = {}) {
|
|
121
|
+
return recursiveResolveDomain(domain, options.maxRecursiveDepth ?? MAX_RECURSIVE_DEPTH, dns, log, options);
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=dnslink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dnslink.js","sourceRoot":"","sources":["../../src/dnslink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAItC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AAE9B,KAAK,UAAU,uBAAuB,CAAE,MAAc,EAAE,KAAa,EAAE,GAAQ,EAAE,GAAW,EAAE,UAAiC,EAAE;IAC/H,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;IAC7C,CAAC;IAED,GAAG,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAA;IACvC,MAAM,kBAAkB,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE;QACjD,GAAG,OAAO;QACV,KAAK,EAAE;YACL,UAAU,CAAC,GAAG;SACf;KACF,CAAC,CAAA;IAEF,0DAA0D;IAC1D,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM;SACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAE/C,GAAG,CAAC,6BAA6B,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE7D,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,IAAI,MAAM,GAAG,MAAM,CAAC,IAAI,CAAA;YAExB,0CAA0C;YAC1C,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YACjD,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACnC,kBAAkB;gBAClB,SAAQ;YACV,CAAC;YAED,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;YAErC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;YAEvC,wDAAwD;YACxD,MAAM,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA,CAAC,6BAA6B;YAE1F,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;oBAElC,iEAAiE;oBACjE,OAAO,SAAS,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;gBACrE,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;iBAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;oBAE5C,oEAAoE;oBACpE,OAAO,SAAS,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;gBACxE,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBAEV,0DAA0D;gBAC1D,OAAO,MAAM,sBAAsB,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;YAChF,CAAC;iBAAM,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAClC,6DAA6D;gBAC7D,OAAO,MAAM,sBAAsB,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;YAChF,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,wDAAwD,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;gBAC/E,SAAQ;YACV,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,KAAK,CAAC,mDAAmD,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,GAAG,CAAC,wDAAwD,EAAE,MAAM,CAAC,CAAA;IACrE,MAAM,oBAAoB,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE;QACnD,GAAG,OAAO;QACV,KAAK,EAAE;YACL,UAAU,CAAC,KAAK;SACjB;KACF,CAAC,CAAA;IAEF,4DAA4D;IAC5D,MAAM,YAAY,GAAG,oBAAoB,CAAC,MAAM;SAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAE/C,GAAG,CAAC,+BAA+B,EAAE,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEjE,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,MAAM,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAC/E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,KAAK,CAAC,2CAA2C,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACjF,CAAC;IACH,CAAC;IAED,MAAM,IAAI,SAAS,CAAC,wCAAwC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAA;AAChG,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAE,MAAc,EAAE,KAAa,EAAE,GAAQ,EAAE,GAAW,EAAE,UAAiC,EAAE;IAC9H,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;IAC7C,CAAC;IAED,4EAA4E;IAC5E,2EAA2E;IAC3E,oBAAoB;IACpB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACpC,MAAM,GAAG,YAAY,MAAM,EAAE,CAAA;IAC/B,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACxE,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,wFAAwF;QACxF,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,uBAAuB,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/F,MAAM,GAAG,CAAA;QACX,CAAC;QAED,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACnC,oDAAoD;YACpD,gCAAgC;YAChC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QAC1C,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,MAAM,GAAG,YAAY,MAAM,EAAE,CAAA;QAC/B,CAAC;QAED,6CAA6C;QAC7C,OAAO,MAAM,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACxE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAE,MAAc,EAAE,GAAQ,EAAE,GAAW,EAAE,UAAiC,EAAE;IAC9G,OAAO,sBAAsB,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,IAAI,mBAAmB,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;AAC5G,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -229,9 +229,9 @@
|
|
|
229
229
|
import { ipnsValidator } from 'ipns/validator';
|
|
230
230
|
import { CID } from 'multiformats/cid';
|
|
231
231
|
import type { IPNSRouting, IPNSRoutingEvents } from './routing/index.js';
|
|
232
|
-
import type { DNSResponse } from './utils/dns.js';
|
|
233
232
|
import type { Routing } from '@helia/interface';
|
|
234
|
-
import type { AbortOptions, PeerId } from '@libp2p/interface';
|
|
233
|
+
import type { AbortOptions, ComponentLogger, PeerId } from '@libp2p/interface';
|
|
234
|
+
import type { DNS, ResolveDnsProgressEvents } from '@multiformats/dns';
|
|
235
235
|
import type { Datastore } from 'interface-datastore';
|
|
236
236
|
import type { IPNSRecord } from 'ipns';
|
|
237
237
|
import type { ProgressEvent, ProgressOptions } from 'progress-events';
|
|
@@ -241,7 +241,7 @@ export type RepublishProgressEvents = ProgressEvent<'ipns:republish:start', unkn
|
|
|
241
241
|
record: IPNSRecord;
|
|
242
242
|
err: Error;
|
|
243
243
|
}>;
|
|
244
|
-
export type
|
|
244
|
+
export type ResolveDNSLinkProgressEvents = ResolveProgressEvents | IPNSRoutingEvents | ResolveDnsProgressEvents;
|
|
245
245
|
export interface PublishOptions extends AbortOptions, ProgressOptions<PublishProgressEvents | IPNSRoutingEvents> {
|
|
246
246
|
/**
|
|
247
247
|
* Time duration of the record in ms (default: 24hrs)
|
|
@@ -263,31 +263,32 @@ export interface ResolveOptions extends AbortOptions, ProgressOptions<ResolvePro
|
|
|
263
263
|
*/
|
|
264
264
|
offline?: boolean;
|
|
265
265
|
}
|
|
266
|
-
export interface
|
|
266
|
+
export interface ResolveDNSLinkOptions extends AbortOptions, ProgressOptions<ResolveDNSLinkProgressEvents> {
|
|
267
267
|
/**
|
|
268
|
-
* Do not
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
export interface DNSResolver {
|
|
273
|
-
(domain: string, options?: ResolveDnsLinkOptions): Promise<string>;
|
|
274
|
-
}
|
|
275
|
-
export interface ResolveDNSOptions extends AbortOptions, ProgressOptions<ResolveProgressEvents | IPNSRoutingEvents | ResolveDnsLinkProgressEvents> {
|
|
276
|
-
/**
|
|
277
|
-
* Do not query the network for the IPNS record (default: false)
|
|
268
|
+
* Do not query the network for the IPNS record
|
|
269
|
+
*
|
|
270
|
+
* @default false
|
|
278
271
|
*/
|
|
279
272
|
offline?: boolean;
|
|
280
273
|
/**
|
|
281
|
-
* Do not use cached DNS entries
|
|
274
|
+
* Do not use cached DNS entries
|
|
275
|
+
*
|
|
276
|
+
* @default false
|
|
282
277
|
*/
|
|
283
278
|
nocache?: boolean;
|
|
284
279
|
/**
|
|
285
|
-
*
|
|
286
|
-
*
|
|
280
|
+
* When resolving DNSLink records that resolve to other DNSLink records, limit
|
|
281
|
+
* how many times we will recursively resolve them.
|
|
282
|
+
*
|
|
283
|
+
* @default 32
|
|
284
|
+
*/
|
|
285
|
+
maxRecursiveDepth?: number;
|
|
286
|
+
/**
|
|
287
|
+
* Retry in case of transport error
|
|
287
288
|
*
|
|
288
|
-
* @
|
|
289
|
+
* @default 3
|
|
289
290
|
*/
|
|
290
|
-
|
|
291
|
+
retries?: number;
|
|
291
292
|
}
|
|
292
293
|
export interface RepublishOptions extends AbortOptions, ProgressOptions<RepublishProgressEvents | IPNSRoutingEvents> {
|
|
293
294
|
/**
|
|
@@ -314,7 +315,7 @@ export interface IPNS {
|
|
|
314
315
|
/**
|
|
315
316
|
* Resolve a CID from a dns-link style IPNS record
|
|
316
317
|
*/
|
|
317
|
-
|
|
318
|
+
resolveDNSLink(domain: string, options?: ResolveDNSLinkOptions): Promise<ResolveResult>;
|
|
318
319
|
/**
|
|
319
320
|
* Periodically republish all IPNS records found in the datastore
|
|
320
321
|
*/
|
|
@@ -324,12 +325,13 @@ export type { IPNSRouting } from './routing/index.js';
|
|
|
324
325
|
export interface IPNSComponents {
|
|
325
326
|
datastore: Datastore;
|
|
326
327
|
routing: Routing;
|
|
328
|
+
dns: DNS;
|
|
329
|
+
logger: ComponentLogger;
|
|
327
330
|
}
|
|
328
331
|
export interface IPNSOptions {
|
|
329
332
|
routers?: IPNSRouting[];
|
|
330
|
-
resolvers?: DNSResolver[];
|
|
331
333
|
}
|
|
332
|
-
export declare function ipns(components: IPNSComponents, { routers
|
|
334
|
+
export declare function ipns(components: IPNSComponents, { routers }?: IPNSOptions): IPNS;
|
|
333
335
|
export { ipnsValidator, type IPNSRoutingEvents };
|
|
334
336
|
export { ipnsSelector } from 'ipns/selector';
|
|
335
337
|
//# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmOG;AAOH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAKtC,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACxE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -234,7 +234,7 @@ import { ipnsSelector } from 'ipns/selector';
|
|
|
234
234
|
import { ipnsValidator } from 'ipns/validator';
|
|
235
235
|
import { CID } from 'multiformats/cid';
|
|
236
236
|
import { CustomProgressEvent } from 'progress-events';
|
|
237
|
-
import {
|
|
237
|
+
import { resolveDNSLink } from './dnslink.js';
|
|
238
238
|
import { helia } from './routing/helia.js';
|
|
239
239
|
import { localStore } from './routing/local-store.js';
|
|
240
240
|
const log = logger('helia:ipns');
|
|
@@ -242,18 +242,21 @@ const MINUTE = 60 * 1000;
|
|
|
242
242
|
const HOUR = 60 * MINUTE;
|
|
243
243
|
const DEFAULT_LIFETIME_MS = 24 * HOUR;
|
|
244
244
|
const DEFAULT_REPUBLISH_INTERVAL_MS = 23 * HOUR;
|
|
245
|
+
const DEFAULT_DNSLINK_RETRIES = 3;
|
|
245
246
|
class DefaultIPNS {
|
|
246
247
|
routers;
|
|
247
248
|
localStore;
|
|
248
249
|
timeout;
|
|
249
|
-
|
|
250
|
-
|
|
250
|
+
dns;
|
|
251
|
+
log;
|
|
252
|
+
constructor(components, routers = []) {
|
|
251
253
|
this.routers = [
|
|
252
254
|
helia(components.routing),
|
|
253
255
|
...routers
|
|
254
256
|
];
|
|
255
257
|
this.localStore = localStore(components.datastore);
|
|
256
|
-
this.
|
|
258
|
+
this.dns = components.dns;
|
|
259
|
+
this.log = components.logger.forComponent('helia:ipns');
|
|
257
260
|
}
|
|
258
261
|
async publish(key, value, options = {}) {
|
|
259
262
|
try {
|
|
@@ -285,9 +288,21 @@ class DefaultIPNS {
|
|
|
285
288
|
const record = await this.#findIpnsRecord(routingKey, options);
|
|
286
289
|
return this.#resolve(record.value, options);
|
|
287
290
|
}
|
|
288
|
-
async
|
|
289
|
-
|
|
290
|
-
const
|
|
291
|
+
async resolveDNSLink(domain, options = {}) {
|
|
292
|
+
let dnslink = '';
|
|
293
|
+
const retries = options.retries ?? DEFAULT_DNSLINK_RETRIES;
|
|
294
|
+
for (let i = 0; i < retries; i++) {
|
|
295
|
+
try {
|
|
296
|
+
dnslink = await resolveDNSLink(domain, this.dns, this.log, options);
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
if (i === (retries - 1)) {
|
|
301
|
+
throw err;
|
|
302
|
+
}
|
|
303
|
+
log.error('error resolving %s attempt %d of %d', domain, i + 1, retries, err);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
291
306
|
return this.#resolve(dnslink, options);
|
|
292
307
|
}
|
|
293
308
|
republish(options = {}) {
|
|
@@ -395,8 +410,8 @@ class DefaultIPNS {
|
|
|
395
410
|
return unmarshal(record);
|
|
396
411
|
}
|
|
397
412
|
}
|
|
398
|
-
export function ipns(components, { routers = []
|
|
399
|
-
return new DefaultIPNS(components, routers
|
|
413
|
+
export function ipns(components, { routers = [] } = {}) {
|
|
414
|
+
return new DefaultIPNS(components, routers);
|
|
400
415
|
}
|
|
401
416
|
export { ipnsValidator };
|
|
402
417
|
export { ipnsSelector } from 'ipns/selector';
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/ipns",
|
|
3
|
-
"version": "6.0.1-
|
|
3
|
+
"version": "6.0.1-adc5589",
|
|
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",
|
|
@@ -164,18 +164,15 @@
|
|
|
164
164
|
"release": "aegir release"
|
|
165
165
|
},
|
|
166
166
|
"dependencies": {
|
|
167
|
-
"@helia/interface": "4.0.1-
|
|
167
|
+
"@helia/interface": "4.0.1-adc5589",
|
|
168
168
|
"@libp2p/interface": "^1.1.4",
|
|
169
169
|
"@libp2p/kad-dht": "^12.0.8",
|
|
170
170
|
"@libp2p/logger": "^4.0.7",
|
|
171
171
|
"@libp2p/peer-id": "^4.0.7",
|
|
172
|
-
"dns
|
|
173
|
-
"dns-packet": "^5.6.1",
|
|
174
|
-
"hashlru": "^2.3.0",
|
|
172
|
+
"@multiformats/dns": "^1.0.1",
|
|
175
173
|
"interface-datastore": "^8.2.11",
|
|
176
174
|
"ipns": "^9.0.0",
|
|
177
175
|
"multiformats": "^13.1.0",
|
|
178
|
-
"p-queue": "^8.0.1",
|
|
179
176
|
"progress-events": "^1.0.0",
|
|
180
177
|
"uint8arrays": "^5.0.2"
|
|
181
178
|
},
|
package/src/dnslink.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { CodeError, type Logger } from '@libp2p/interface'
|
|
2
|
+
import { peerIdFromString } from '@libp2p/peer-id'
|
|
3
|
+
import { RecordType } from '@multiformats/dns'
|
|
4
|
+
import { CID } from 'multiformats/cid'
|
|
5
|
+
import type { ResolveDNSLinkOptions } from './index.js'
|
|
6
|
+
import type { DNS } from '@multiformats/dns'
|
|
7
|
+
|
|
8
|
+
const MAX_RECURSIVE_DEPTH = 32
|
|
9
|
+
|
|
10
|
+
async function recursiveResolveDnslink (domain: string, depth: number, dns: DNS, log: Logger, options: ResolveDNSLinkOptions = {}): Promise<string> {
|
|
11
|
+
if (depth === 0) {
|
|
12
|
+
throw new Error('recursion limit exceeded')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
log('query %s for TXT records', domain)
|
|
16
|
+
const txtRecordsResponse = await dns.query(domain, {
|
|
17
|
+
...options,
|
|
18
|
+
types: [
|
|
19
|
+
RecordType.TXT
|
|
20
|
+
]
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
// sort the TXT records to ensure deterministic processing
|
|
24
|
+
const txtRecords = txtRecordsResponse.Answer
|
|
25
|
+
.sort((a, b) => a.data.localeCompare(b.data))
|
|
26
|
+
|
|
27
|
+
log('found %d TXT records for %s', txtRecords.length, domain)
|
|
28
|
+
|
|
29
|
+
for (const answer of txtRecords) {
|
|
30
|
+
try {
|
|
31
|
+
let result = answer.data
|
|
32
|
+
|
|
33
|
+
// strip leading and trailing " characters
|
|
34
|
+
if (result.startsWith('"') && result.endsWith('"')) {
|
|
35
|
+
result = result.substring(1, result.length - 1)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!result.startsWith('dnslink=')) {
|
|
39
|
+
// invalid record?
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
log('%s TXT %s', answer.name, result)
|
|
44
|
+
|
|
45
|
+
result = result.replace('dnslink=', '')
|
|
46
|
+
|
|
47
|
+
// result is now a `/ipfs/<cid>` or `/ipns/<cid>` string
|
|
48
|
+
const [, protocol, domainOrCID, ...rest] = result.split('/') // e.g. ["", "ipfs", "<cid>"]
|
|
49
|
+
|
|
50
|
+
if (protocol === 'ipfs') {
|
|
51
|
+
try {
|
|
52
|
+
const cid = CID.parse(domainOrCID)
|
|
53
|
+
|
|
54
|
+
// if the result is a CID, we've reached the end of the recursion
|
|
55
|
+
return `/ipfs/${cid}${rest.length > 0 ? `/${rest.join('/')}` : ''}`
|
|
56
|
+
} catch {}
|
|
57
|
+
} else if (protocol === 'ipns') {
|
|
58
|
+
try {
|
|
59
|
+
const peerId = peerIdFromString(domainOrCID)
|
|
60
|
+
|
|
61
|
+
// if the result is a PeerId, we've reached the end of the recursion
|
|
62
|
+
return `/ipns/${peerId}${rest.length > 0 ? `/${rest.join('/')}` : ''}`
|
|
63
|
+
} catch {}
|
|
64
|
+
|
|
65
|
+
// if the result was another IPNS domain, try to follow it
|
|
66
|
+
return await recursiveResolveDomain(domainOrCID, depth - 1, dns, log, options)
|
|
67
|
+
} else if (protocol === 'dnslink') {
|
|
68
|
+
// if the result was another DNSLink domain, try to follow it
|
|
69
|
+
return await recursiveResolveDomain(domainOrCID, depth - 1, dns, log, options)
|
|
70
|
+
} else {
|
|
71
|
+
log('unknown protocol "%s" in DNSLink record for domain: %s', protocol, domain)
|
|
72
|
+
continue
|
|
73
|
+
}
|
|
74
|
+
} catch (err: any) {
|
|
75
|
+
log.error('could not parse DNS link record for domain %s, %s', domain, answer.data, err)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// see if there is a CNAME delegation
|
|
80
|
+
log('no DNSLink records found for %s, falling back to CNAME', domain)
|
|
81
|
+
const cnameRecordsResponse = await dns.query(domain, {
|
|
82
|
+
...options,
|
|
83
|
+
types: [
|
|
84
|
+
RecordType.CNAME
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// sort the CNAME records to ensure deterministic processing
|
|
89
|
+
const cnameRecords = cnameRecordsResponse.Answer
|
|
90
|
+
.sort((a, b) => a.data.localeCompare(b.data))
|
|
91
|
+
|
|
92
|
+
log('found %d CNAME records for %s', cnameRecords.length, domain)
|
|
93
|
+
|
|
94
|
+
for (const cname of cnameRecords) {
|
|
95
|
+
try {
|
|
96
|
+
return await recursiveResolveDomain(cname.data, depth - 1, dns, log, options)
|
|
97
|
+
} catch (err: any) {
|
|
98
|
+
log.error('domain %s cname %s had no DNSLink records', domain, cname.data, err)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
throw new CodeError(`No DNSLink records found for domain: ${domain}`, 'ERR_DNSLINK_NOT_FOUND')
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function recursiveResolveDomain (domain: string, depth: number, dns: DNS, log: Logger, options: ResolveDNSLinkOptions = {}): Promise<string> {
|
|
106
|
+
if (depth === 0) {
|
|
107
|
+
throw new Error('recursion limit exceeded')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// the DNSLink spec says records MUST be stored on the `_dnslink.` subdomain
|
|
111
|
+
// so start looking for records there, we will fall back to the bare domain
|
|
112
|
+
// if none are found
|
|
113
|
+
if (!domain.startsWith('_dnslink.')) {
|
|
114
|
+
domain = `_dnslink.${domain}`
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
return await recursiveResolveDnslink(domain, depth, dns, log, options)
|
|
119
|
+
} catch (err: any) {
|
|
120
|
+
// If the code is not ENOTFOUND or ERR_DNSLINK_NOT_FOUND or ENODATA then throw the error
|
|
121
|
+
if (err.code !== 'ENOTFOUND' && err.code !== 'ERR_DNSLINK_NOT_FOUND' && err.code !== 'ENODATA') {
|
|
122
|
+
throw err
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (domain.startsWith('_dnslink.')) {
|
|
126
|
+
// The supplied domain contains a _dnslink component
|
|
127
|
+
// Check the non-_dnslink domain
|
|
128
|
+
domain = domain.replace('_dnslink.', '')
|
|
129
|
+
} else {
|
|
130
|
+
// Check the _dnslink subdomain
|
|
131
|
+
domain = `_dnslink.${domain}`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// If this throws then we propagate the error
|
|
135
|
+
return await recursiveResolveDnslink(domain, depth, dns, log, options)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export async function resolveDNSLink (domain: string, dns: DNS, log: Logger, options: ResolveDNSLinkOptions = {}): Promise<string> {
|
|
140
|
+
return recursiveResolveDomain(domain, options.maxRecursiveDepth ?? MAX_RECURSIVE_DEPTH, dns, log, options)
|
|
141
|
+
}
|