diff --git a/src/index.ts b/src/index.ts index b8de0017..0ba8a868 100644 --- a/src/index.ts +++ b/src/index.ts @@ -141,13 +141,32 @@ export class Multiaddr { * ``` */ toOptions (): MultiaddrObject { - const parsed = this.toString().split('/') + const codes = this.protoCodes() + const parts = this.toString().split('/').slice(1) + let transport: string + let port: number + + if (parts.length > 2) { + // default to https when protocol & port are omitted from DNS addrs + if (DNS_CODES.includes(codes[0]) && P2P_CODES.includes(codes[1])) { + transport = getProtocol('tcp').name + port = 443 + } else { + transport = getProtocol(parts[2]).name + port = parseInt(parts[3]) + } + } else if (DNS_CODES.includes(codes[0])) { + transport = getProtocol('tcp').name + port = 443 + } else { + throw new Error('multiaddr must have a valid format: "/{ip4, ip6, dns4, dns6, dnsaddr}/{address}/{tcp, udp}/{port}".') + } const opts: MultiaddrObject = { - family: parsed[1] === 'ip4' ? 4 : 6, - host: parsed[2], - transport: parsed[3], - port: parseInt(parsed[4]) + family: (codes[0] === 41 || codes[0] === 55) ? 6 : 4, + host: parts[1], + transport, + port } return opts diff --git a/test/index.spec.ts b/test/index.spec.ts index e423d55a..225a89a0 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -486,6 +486,46 @@ describe('helpers', () => { port: 1234 }) }) + + it('returns an options object from a DNS addr', () => { + expect(new Multiaddr('/dns4/google.net/tcp/8000').toOptions()) + .to.eql({ + family: 4, + host: 'google.net', + transport: 'tcp', + port: 8000 + }) + }) + + it('returns an options object from a DNS6 addr', () => { + expect(new Multiaddr('/dns6/google.net/tcp/8000').toOptions()) + .to.eql({ + family: 6, + host: 'google.net', + transport: 'tcp', + port: 8000 + }) + }) + + it('returns an options object from a DNS addr defaulting to https', () => { + expect(new Multiaddr('/dnsaddr/google.net').toOptions()) + .to.eql({ + family: 4, + host: 'google.net', + transport: 'tcp', + port: 443 + }) + }) + + it('returns an options object from a DNS addr with a PeerID defaulting to https', () => { + expect(new Multiaddr('/dnsaddr/google.net/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').toOptions()) + .to.eql({ + family: 4, + host: 'google.net', + transport: 'tcp', + port: 443 + }) + }) }) describe('.inspect', () => {