diff --git a/README.md b/README.md
index 76f5cfb0..05592756 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
[](https://codecov.io/gh/multiformats/js-multiaddr)
[](https://github.com/multiformats/js-multiaddr/actions/workflows/js-test-and-release.yml?query=branch%3Amain)
-> multiaddr implementation (binary + string representation of network addresses)
+> The JavaScript implementation of the Multiaddr spec
# About
@@ -26,7 +26,6 @@ repo and examine the changes made.
A standard way to represent addresses that
- support any standard network protocol
-- are self-describing
- have a binary packed format
- have a nice string representation
- encapsulate well
@@ -45,75 +44,16 @@ addr.bytes
addr.toString()
// '/ip4/127.0.0.1/udp/1234'
-addr.protos()
+addr.getComponents()
// [
-// {code: 4, name: 'ip4', size: 32},
-// {code: 273, name: 'udp', size: 16}
+// { code: 4, name: 'ip4', value: '127.0.0.1' },
+// { code: 273, name: 'udp', value: '1234' }
// ]
-// gives you an object that is friendly with what Node.js core modules expect for addresses
-addr.nodeAddress()
-// {
-// family: 4,
-// port: 1234,
-// address: "127.0.0.1"
-// }
-
addr.encapsulate('/sctp/5678')
// Multiaddr(/ip4/127.0.0.1/udp/1234/sctp/5678)
```
-## Resolving DNSADDR addresses
-
-[DNSADDR](https://github.com/multiformats/multiaddr/blob/master/protocols/DNSADDR.md) is a spec that allows storing a TXT DNS record that contains a Multiaddr.
-
-To resolve DNSADDR addresses, call the `.resolve()` function the multiaddr, optionally passing a `DNS` resolver.
-
-DNSADDR addresses can resolve to multiple multiaddrs, since there is no limit to the number of TXT records that can be stored.
-
-## Example - Resolving DNSADDR Multiaddrs
-
-```TypeScript
-import { multiaddr, resolvers } from '@multiformats/multiaddr'
-import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
-
-resolvers.set('dnsaddr', dnsaddrResolver)
-
-const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
-
-// resolve with a 5s timeout
-const resolved = await ma.resolve({
- signal: AbortSignal.timeout(5000)
-})
-
-console.info(resolved)
-// [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
-```
-
-## Example - Using a custom DNS resolver to resolve DNSADDR Multiaddrs
-
-See the docs for [@multiformats/dns](https://www.npmjs.com/package/@multiformats/dns) for a full breakdown of how to specify multiple resolvers or resolvers that can be used for specific TLDs.
-
-```TypeScript
-import { multiaddr } from '@multiformats/multiaddr'
-import { dns } from '@multiformats/dns'
-import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
-
-const resolver = dns({
- resolvers: {
- '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
- }
-})
-
-const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
-const resolved = await ma.resolve({
- dns: resolver
-})
-
-console.info(resolved)
-// [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
-```
-
## Example - Adding custom protocols
To add application-specific or experimental protocols, add a protocol codec
@@ -145,20 +85,6 @@ multiaddr(maWithCustomTuple)
registry.removeProtocol(protocol.code)
```
-# Install
-
-```console
-$ npm i @multiformats/multiaddr
-```
-
-## Browser `
-```
-
# API Docs
-
diff --git a/benchmarks/operations/package.json b/benchmarks/operations/package.json
index b97da0ba..9f4c797e 100644
--- a/benchmarks/operations/package.json
+++ b/benchmarks/operations/package.json
@@ -15,7 +15,7 @@
"devDependencies": {
"@multiformats/multiaddr-12.4.0": "npm:@multiformats/multiaddr@12.4.0",
"@multiformats/multiaddr": "../../",
- "aegir": "^47.0.7",
+ "aegir": "^47.0.16",
"tinybench": "^4.0.1"
}
}
diff --git a/package.json b/package.json
index da393dad..d90d16ba 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "@multiformats/multiaddr",
"version": "12.5.1",
- "description": "multiaddr implementation (binary + string representation of network addresses)",
+ "description": "The JavaScript implementation of the Multiaddr spec",
"license": "Apache-2.0 OR MIT",
"homepage": "https://github.com/multiformats/js-multiaddr#readme",
"repository": {
@@ -22,22 +22,6 @@
],
"type": "module",
"types": "./dist/src/index.d.ts",
- "typesVersions": {
- "*": {
- "*": [
- "*",
- "dist/*",
- "dist/src/*",
- "dist/src/*/index"
- ],
- "src/*": [
- "*",
- "dist/*",
- "dist/src/*",
- "dist/src/*/index"
- ]
- }
- },
"files": [
"src",
"dist",
@@ -48,14 +32,6 @@
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/src/index.js"
- },
- "./convert": {
- "types": "./dist/src/convert.d.ts",
- "import": "./dist/src/convert.js"
- },
- "./resolvers": {
- "types": "./dist/src/resolvers/index.d.ts",
- "import": "./dist/src/resolvers/index.js"
}
},
"release": {
@@ -169,18 +145,12 @@
},
"dependencies": {
"@chainsafe/is-ip": "^2.0.1",
- "@chainsafe/netmask": "^2.0.0",
- "@multiformats/dns": "^1.0.3",
- "abort-error": "^1.0.1",
"multiformats": "^13.0.0",
"uint8-varint": "^2.0.1",
"uint8arrays": "^5.0.0"
},
"devDependencies": {
- "@types/sinon": "^17.0.2",
- "aegir": "^47.0.16",
- "sinon": "^21.0.0",
- "sinon-ts": "^2.0.0"
+ "aegir": "^47.0.16"
},
"browser": {
"./dist/src/resolvers/dns.js": "./dist/src/resolvers/dns.browser.js"
diff --git a/src/convert.ts b/src/convert.ts
deleted file mode 100644
index 451ee411..00000000
--- a/src/convert.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { IpNet } from '@chainsafe/netmask'
-import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
-import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
-import { registry } from './registry.js'
-import type { Multiaddr } from './index.ts'
-
-export function convertToIpNet (multiaddr: Multiaddr): IpNet {
- let mask: string | undefined
- let addr: string | undefined
-
- multiaddr.getComponents().forEach(component => {
- if (component.name === 'ip4' || component.name === 'ip6') {
- addr = component.value
- }
- if (component.name === 'ipcidr') {
- mask = component.value
- }
- })
-
- if (mask == null || addr == null) {
- throw new Error('Invalid multiaddr')
- }
-
- return new IpNet(addr, mask)
-}
-
-/**
- * converts (serializes) addresses
- *
- * @deprecated Will be removed in a future release
- */
-export function convert (proto: string, a: string): Uint8Array
-export function convert (proto: string, a: Uint8Array): string
-export function convert (proto: string, a: string | Uint8Array): Uint8Array | string {
- if (a instanceof Uint8Array) {
- return convertToString(proto, a)
- } else {
- return convertToBytes(proto, a)
- }
-}
-
-/**
- * Convert [code, Uint8Array] to string
- *
- * @deprecated Will be removed in a future release
- */
-export function convertToString (proto: number | string, buf: Uint8Array): string {
- const protocol = registry.getProtocol(proto)
-
- return protocol.bytesToValue?.(buf) ?? uint8ArrayToString(buf, 'base16') // no clue. convert to hex
-}
-
-/**
- * Convert [code, string] to Uint8Array
- *
- * @deprecated Will be removed in a future release
- */
-export function convertToBytes (proto: string | number, str: string): Uint8Array {
- const protocol = registry.getProtocol(proto)
-
- return protocol.valueToBytes?.(str) ?? uint8ArrayFromString(str, 'base16') // no clue. convert from hex
-}
diff --git a/src/filter/multiaddr-filter.ts b/src/filter/multiaddr-filter.ts
deleted file mode 100644
index 66977a75..00000000
--- a/src/filter/multiaddr-filter.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { convertToIpNet } from '../convert.js'
-import { multiaddr } from '../index.js'
-import type { Multiaddr, MultiaddrInput } from '../index.js'
-import type { IpNet } from '@chainsafe/netmask'
-
-/**
- * A utility class to determine if a Multiaddr contains another
- * multiaddr.
- *
- * This can be used with ipcidr ranges to determine if a given
- * multiaddr is in a ipcidr range.
- *
- * @example
- *
- * ```js
- * import { multiaddr, MultiaddrFilter } from '@multiformats/multiaddr'
- *
- * const range = multiaddr('/ip4/192.168.10.10/ipcidr/24')
- * const filter = new MultiaddrFilter(range)
- *
- * const input = multiaddr('/ip4/192.168.10.2/udp/60')
- * console.info(filter.contains(input)) // true
- * ```
- */
-export class MultiaddrFilter {
- private readonly multiaddr: Multiaddr
- private readonly netmask: IpNet
-
- public constructor (input: MultiaddrInput) {
- this.multiaddr = multiaddr(input)
- this.netmask = convertToIpNet(this.multiaddr)
- }
-
- public contains (input: MultiaddrInput): boolean {
- if (input == null) { return false }
- const m = multiaddr(input)
- let ip
- for (const [code, value] of m.stringTuples()) {
- if (code === 4 || code === 41) {
- ip = value
- break
- }
- }
- if (ip === undefined) { return false }
- return this.netmask.contains(ip)
- }
-}
diff --git a/src/index.ts b/src/index.ts
index fa120e92..eed4ab3c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,7 +4,6 @@
* A standard way to represent addresses that
*
* - support any standard network protocol
- * - are self-describing
* - have a binary packed format
* - have a nice string representation
* - encapsulate well
@@ -23,75 +22,16 @@
* addr.toString()
* // '/ip4/127.0.0.1/udp/1234'
*
- * addr.protos()
+ * addr.getComponents()
* // [
- * // {code: 4, name: 'ip4', size: 32},
- * // {code: 273, name: 'udp', size: 16}
+ * // { code: 4, name: 'ip4', value: '127.0.0.1' },
+ * // { code: 273, name: 'udp', value: '1234' }
* // ]
*
- * // gives you an object that is friendly with what Node.js core modules expect for addresses
- * addr.nodeAddress()
- * // {
- * // family: 4,
- * // port: 1234,
- * // address: "127.0.0.1"
- * // }
- *
* addr.encapsulate('/sctp/5678')
* // Multiaddr(/ip4/127.0.0.1/udp/1234/sctp/5678)
* ```
*
- * ## Resolving DNSADDR addresses
- *
- * [DNSADDR](https://github.com/multiformats/multiaddr/blob/master/protocols/DNSADDR.md) is a spec that allows storing a TXT DNS record that contains a Multiaddr.
- *
- * To resolve DNSADDR addresses, call the `.resolve()` function the multiaddr, optionally passing a `DNS` resolver.
- *
- * DNSADDR addresses can resolve to multiple multiaddrs, since there is no limit to the number of TXT records that can be stored.
- *
- * @example Resolving DNSADDR Multiaddrs
- *
- * ```TypeScript
- * import { multiaddr, resolvers } from '@multiformats/multiaddr'
- * import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
- *
- * resolvers.set('dnsaddr', dnsaddrResolver)
- *
- * const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
- *
- * // resolve with a 5s timeout
- * const resolved = await ma.resolve({
- * signal: AbortSignal.timeout(5000)
- * })
- *
- * console.info(resolved)
- * // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
- * ```
- *
- * @example Using a custom DNS resolver to resolve DNSADDR Multiaddrs
- *
- * See the docs for [@multiformats/dns](https://www.npmjs.com/package/@multiformats/dns) for a full breakdown of how to specify multiple resolvers or resolvers that can be used for specific TLDs.
- *
- * ```TypeScript
- * import { multiaddr } from '@multiformats/multiaddr'
- * import { dns } from '@multiformats/dns'
- * import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
- *
- * const resolver = dns({
- * resolvers: {
- * '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
- * }
- * })
- *
- * const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
- * const resolved = await ma.resolve({
- * dns: resolver
- * })
- *
- * console.info(resolved)
- * // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
- * ```
- *
* @example Adding custom protocols
*
* To add application-specific or experimental protocols, add a protocol codec
@@ -124,37 +64,9 @@
* ```
*/
-import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
-import { InvalidParametersError } from './errors.ts'
import { Multiaddr as MultiaddrClass, symbol } from './multiaddr.js'
import { registry, V } from './registry.ts'
import type { ProtocolCodec } from './registry.ts'
-import type { Resolver } from './resolvers/index.js'
-import type { DNS } from '@multiformats/dns'
-import type { AbortOptions } from 'abort-error'
-
-/**
- * Protocols are present in the protocol table
- *
- * @deprecated
- */
-export interface Protocol {
- code: number
- size: number
- name: string
- resolvable?: boolean | undefined
- path?: boolean | undefined
-}
-
-/**
- * A plain JavaScript object representation of a {@link Multiaddr}
- */
-export interface MultiaddrObject {
- family: 4 | 6
- host: string
- transport: 'tcp' | 'udp'
- port: number
-}
/**
* The protocol registry stores protocol codecs that allow transformation of
@@ -178,70 +90,11 @@ export interface Registry {
removeProtocol (code: number): void
}
-/**
- * A NodeAddress is an IPv4/IPv6 address/TCP port combination
- */
-export interface NodeAddress {
- family: 4 | 6
- address: string
- port: number
-}
-
/**
* These types can be parsed into a {@link Multiaddr} object
*/
export type MultiaddrInput = string | Multiaddr | Uint8Array | null | Component[]
-/**
- * A code/value pair
- *
- * @deprecated Use Component instead
- */
-export type Tuple = [number, Uint8Array?]
-
-/**
- * A code/value pair with the value as a string
- *
- * @deprecated Use Component instead
- */
-export type StringTuple = [number, string?]
-
-/**
- * Allows aborting long-lived operations
- *
- * @deprecated Import from `abort-error` instead
- */
-export type { AbortOptions }
-
-/**
- * All configured {@link Resolver}s
- *
- * @deprecated DNS resolving will be removed in a future release
- */
-export const resolvers = new Map()
-
-export type { Resolver }
-
-export { MultiaddrFilter } from './filter/multiaddr-filter.js'
-
-/**
- * @deprecated DNS resolving will be removed in a future release
- */
-export interface ResolveOptions extends AbortOptions {
- /**
- * An optional DNS resolver
- */
- dns?: DNS
-
- /**
- * When resolving DNSADDR Multiaddrs that resolve to other DNSADDR Multiaddrs,
- * limit how many times we will recursively resolve them.
- *
- * @default 32
- */
- maxRecursiveDepth?: number
-}
-
/**
* A Component is a section of a multiaddr with a name/code, possibly with a
* value.
@@ -315,103 +168,6 @@ export interface Multiaddr {
*/
getComponents(): Component[]
- /**
- * Returns Multiaddr as a convenient options object to be used with
- * `createConnection` from `node:net`
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * multiaddr('/ip4/127.0.0.1/tcp/4001').toOptions()
- * // { family: 4, host: '127.0.0.1', transport: 'tcp', port: 4001 }
- * ```
- */
- toOptions(): MultiaddrObject
-
- /**
- * Returns the protocols the Multiaddr is defined with, as an array of
- * objects, in left-to-right order. Each object contains the protocol code,
- * protocol name, and the size of its address space in bits.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * multiaddr('/ip4/127.0.0.1/tcp/4001').protos()
- * // [ { code: 4, size: 32, name: 'ip4' },
- * // { code: 6, size: 16, name: 'tcp' } ]
- * ```
- *
- * @deprecated Use `getComponents()` instead
- */
- protos(): Protocol[]
-
- /**
- * Returns the codes of the protocols in left-to-right order.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * multiaddr('/ip4/127.0.0.1/tcp/4001').protoCodes()
- * // [ 4, 6 ]
- * ```
- *
- * @deprecated Use `getComponents()` instead
- */
- protoCodes(): number[]
-
- /**
- * Returns the names of the protocols in left-to-right order.
- * [See list of protocols](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * multiaddr('/ip4/127.0.0.1/tcp/4001').protoNames()
- * // [ 'ip4', 'tcp' ]
- * ```
- *
- * @deprecated Use `getComponents()` instead
- */
- protoNames(): string[]
-
- /**
- * Returns a tuple of parts
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * multiaddr('/ip4/127.0.0.1/tcp/4001').tuples()
- * // [ [ 4, ], [ 6, ] ]
- * ```
- *
- * @deprecated Use `getComponents()` instead
- */
- tuples(): Tuple[]
-
- /**
- * Returns a tuple of string/number parts
- * - tuples[][0] = code of protocol
- * - tuples[][1] = contents of address
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * multiaddr('/ip4/127.0.0.1/tcp/4001').stringTuples()
- * // [ [ 4, '127.0.0.1' ], [ 6, '4001' ] ]
- * ```
- *
- * @deprecated Use `getComponents()` instead
- */
- stringTuples(): StringTuple[]
-
/**
* Encapsulates a Multiaddr in another Multiaddr
*
@@ -482,42 +238,6 @@ export interface Multiaddr {
*/
decapsulateCode(code: number): Multiaddr
- /**
- * Extract the peerId if the multiaddr contains one
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * const mh1 = multiaddr('/ip4/8.8.8.8/tcp/1080/ipfs/QmValidBase58string')
- * // Multiaddr(/ip4/8.8.8.8/tcp/1080/ipfs/QmValidBase58string)
- *
- * // should return QmValidBase58string or null if the id is missing or invalid
- * const peerId = mh1.getPeerId()
- * ```
- *
- * @deprecated A multiaddr can contain multiple PeerIds, use stringTuples() to get a specific one
- */
- getPeerId(): string | null
-
- /**
- * Extract the path if the multiaddr contains one
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * const mh1 = multiaddr('/ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock')
- * // Multiaddr(/ip4/8.8.8.8/tcp/1080/unix/tmp/p2p.sock)
- *
- * // should return utf8 string or null if the id is missing or invalid
- * const path = mh1.getPath()
- * ```
- *
- * @deprecated A multiaddr can contain multiple tuples that could be interpreted as paths, use stringTuples() to get a specific one
- */
- getPath(): string | null
-
/**
* Checks if two Multiaddrs are the same
*
@@ -539,218 +259,6 @@ export interface Multiaddr {
* ```
*/
equals(addr: { bytes: Uint8Array }): boolean
-
- /**
- * Resolve multiaddr if containing resolvable hostname.
- *
- * @example
- * ```js
- * import { multiaddr, resolvers } from '@multiformats/multiaddr'
- *
- * resolvers.set('dnsaddr', resolverFunction)
- * const mh1 = multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
- * const resolvedMultiaddrs = await mh1.resolve()
- * // [
- * // Multiaddr(/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb),
- * // Multiaddr(/ip4/147.75.83.83/tcp/443/wss/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb),
- * // Multiaddr(/ip4/147.75.83.83/udp/4001/quic/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb)
- * // ]
- * ```
- *
- * @deprecated If you need to resolve `dnsaddr` addresses, use `getComponents()` to extract them and perform the resolution yourself
- */
- resolve(options?: ResolveOptions): Promise
-
- /**
- * Gets a Multiaddrs node-friendly address object. Note that protocol
- * information is left out: in Node (and most network systems) the protocol is
- * unknowable given only the address.
- *
- * Has to be a ThinWaist Address, otherwise throws error
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * multiaddr('/ip4/127.0.0.1/tcp/4001').nodeAddress()
- * // {family: 4, address: '127.0.0.1', port: 4001}
- * ```
- */
- nodeAddress(): NodeAddress
-
- /**
- * Returns if a Multiaddr is a Thin Waist address or not.
- *
- * Thin Waist is if a Multiaddr adheres to the standard combination of:
- *
- * `{IPv4, IPv6}/{TCP, UDP}`
- *
- * @example
- * ```js
- * import { multiaddr } from '@multiformats/multiaddr'
- *
- * const mh1 = multiaddr('/ip4/127.0.0.1/tcp/4001')
- * // Multiaddr(/ip4/127.0.0.1/tcp/4001)
- * const mh2 = multiaddr('/ip4/192.168.2.1/tcp/5001')
- * // Multiaddr(/ip4/192.168.2.1/tcp/5001)
- * const mh3 = mh1.encapsulate(mh2)
- * // Multiaddr(/ip4/127.0.0.1/tcp/4001/ip4/192.168.2.1/tcp/5001)
- * const mh4 = multiaddr('/ip4/127.0.0.1/tcp/2000/wss/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a')
- * // Multiaddr(/ip4/127.0.0.1/tcp/2000/wss/p2p-webrtc-star/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooo2a)
- * mh1.isThinWaistAddress()
- * // true
- * mh2.isThinWaistAddress()
- * // true
- * mh3.isThinWaistAddress()
- * // false
- * mh4.isThinWaistAddress()
- * // false
- * ```
- */
- isThinWaistAddress(addr?: Multiaddr): boolean
-}
-
-/**
- * Creates a Multiaddr from a node-friendly address object
- *
- * @example
- * ```js
- * import { fromNodeAddress } from '@multiformats/multiaddr'
- *
- * fromNodeAddress({address: '127.0.0.1', port: '4001'}, 'tcp')
- * // Multiaddr(/ip4/127.0.0.1/tcp/4001)
- * ```
- */
-export function fromNodeAddress (addr: NodeAddress, transport: string): Multiaddr {
- if (addr == null) {
- throw new InvalidParametersError('requires node address object')
- }
- if (transport == null) {
- throw new InvalidParametersError('requires transport protocol')
- }
- let ip: string | undefined
- let host = addr.address
- switch (addr.family) {
- case 4:
- ip = 'ip4'
- break
- case 6:
- ip = 'ip6'
-
- if (host.includes('%')) {
- const parts = host.split('%')
-
- if (parts.length !== 2) {
- throw Error('Multiple ip6 zones in multiaddr')
- }
-
- host = parts[0]
- const zone = parts[1]
- ip = `ip6zone/${zone}/ip6`
- }
- break
- default:
- throw Error('Invalid addr family, should be 4 or 6.')
- }
-
- return new MultiaddrClass('/' + [ip, host, transport, addr.port].join('/'))
-}
-
-/**
- * Create a {@link Multiaddr} from an array of {@link Tuple}s
- *
- * @example
- *
- * ```ts
- * import { fromTuples, multiaddr } from '@multiformats/multiaddr'
- *
- * const ma = multiaddr('/ip4/127.0.0.1')
- * const tuples = ma.tuples()
- *
- * const ma2 = fromTuples(tuples)
- *
- * console.info(ma2)
- * // '/ip4/127.0.0.1'
- * ```
- *
- * @deprecated Will be removed in a future release
- */
-export function fromTuples (tuples: Tuple[]): Multiaddr {
- return multiaddr(tuples.map(([code, value]) => {
- const codec = registry.getProtocol(code)
-
- const component: Component = {
- code,
- name: codec.name
- }
-
- if (value != null) {
- component.value = codec.bytesToValue?.(value) ?? uint8ArrayToString(value)
- }
-
- return component
- }))
-}
-
-/**
- * Create a {@link Multiaddr} from an array of {@link StringTuple}s
- *
- * @example
- *
- * ```ts
- * import { fromStringTuples, multiaddr } from '@multiformats/multiaddr'
- *
- * const ma = multiaddr('/ip4/127.0.0.1')
- * const tuples = ma.stringTuples()
- *
- * const ma2 = fromStringTuples(tuples)
- *
- * console.info(ma2)
- * // '/ip4/127.0.0.1'
- * ```
- *
- * @deprecated Will be removed in a future release
- */
-export function fromStringTuples (tuples: StringTuple[]): Multiaddr {
- return multiaddr(tuples.map(([code, value]) => {
- const codec = registry.getProtocol(code)
-
- const component: Component = {
- code,
- name: codec.name
- }
-
- if (value != null) {
- component.value = value
- }
-
- return component
- }))
-}
-
-/**
- * Returns if something is a {@link Multiaddr} that is a resolvable name
- *
- * @example
- *
- * ```js
- * import { isName, multiaddr } from '@multiformats/multiaddr'
- *
- * isName(multiaddr('/ip4/127.0.0.1'))
- * // false
- * isName(multiaddr('/dns/ipfs.io'))
- * // true
- * ```
- *
- * @deprecated DNS resolving will be removed in a future release
- */
-export function isName (addr: Multiaddr): boolean {
- if (!isMultiaddr(addr)) {
- return false
- }
-
- // if a part of the multiaddr is resolvable, then return true
- return addr.protos().some((proto) => proto.resolvable)
}
/**
@@ -788,32 +296,6 @@ export function multiaddr (addr?: MultiaddrInput): Multiaddr {
return new MultiaddrClass(addr)
}
-/**
- * For the passed proto string or number, return a {@link Protocol}
- *
- * @example
- *
- * ```js
- * import { protocol } from '@multiformats/multiaddr'
- *
- * console.info(protocol(4))
- * // { code: 4, size: 32, name: 'ip4', resolvable: false, path: false }
- * ```
- *
- * @deprecated This will be removed in a future version
- */
-export function protocols (proto: number | string): Protocol {
- const codec = registry.getProtocol(proto)
-
- return {
- code: codec.code,
- size: codec.size ?? 0,
- name: codec.name,
- resolvable: Boolean(codec.resolvable),
- path: Boolean(codec.path)
- }
-}
-
/**
* Export all table.csv codes. These are all named exports so can be tree-shaken
* out by bundlers.
diff --git a/src/multiaddr.ts b/src/multiaddr.ts
index 1964dc12..919a194b 100644
--- a/src/multiaddr.ts
+++ b/src/multiaddr.ts
@@ -1,32 +1,13 @@
-import { base58btc } from 'multiformats/bases/base58'
-import { CID } from 'multiformats/cid'
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
-import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
-import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
import { bytesToComponents, componentsToBytes, componentsToString, stringToComponents } from './components.js'
-import { CODE_DNS, CODE_DNS4, CODE_DNS6, CODE_DNSADDR, CODE_IP4, CODE_IP6, CODE_IP6ZONE, CODE_P2P, CODE_P2P_CIRCUIT, CODE_TCP, CODE_UDP } from './constants.ts'
import { InvalidMultiaddrError, InvalidParametersError } from './errors.ts'
import { registry } from './registry.ts'
-import { isMultiaddr, multiaddr, resolvers } from './index.js'
-import type { MultiaddrInput, Multiaddr as MultiaddrInterface, MultiaddrObject, Protocol, Tuple, NodeAddress, ResolveOptions, Component } from './index.js'
+import { isMultiaddr } from './index.js'
+import type { MultiaddrInput, Multiaddr as MultiaddrInterface, Component } from './index.js'
const inspect = Symbol.for('nodejs.util.inspect.custom')
export const symbol = Symbol.for('@multiformats/multiaddr')
-const DNS_CODES = [
- CODE_DNS,
- CODE_DNS4,
- CODE_DNS6,
- CODE_DNSADDR
-]
-
-class NoAvailableResolverError extends Error {
- constructor (message = 'No available resolver') {
- super(message)
- this.name = 'NoAvailableResolverError'
- }
-}
-
function toComponents (addr: MultiaddrInput): Component[] {
if (addr == null) {
addr = '/'
@@ -103,107 +84,12 @@ export class Multiaddr implements MultiaddrInterface {
return this.toString()
}
- toOptions (): MultiaddrObject {
- let family: 4 | 6 | undefined
- let transport: 'tcp' | 'udp' | undefined
- let host: string | undefined
- let port: number | undefined
- let zone = ''
-
- for (const { code, name, value } of this.#components) {
- if (code === CODE_IP6ZONE) {
- zone = `%${value ?? ''}`
- }
-
- // default to https when protocol & port are omitted from DNS addrs
- if (DNS_CODES.includes(code)) {
- transport = 'tcp'
- port = 443
- host = `${value ?? ''}${zone}`
- family = code === CODE_DNS6 ? 6 : 4
- }
-
- if (code === CODE_TCP || code === CODE_UDP) {
- transport = name === 'tcp' ? 'tcp' : 'udp'
- port = parseInt(value ?? '')
- }
-
- if (code === CODE_IP4 || code === CODE_IP6) {
- transport = 'tcp'
- host = `${value ?? ''}${zone}`
- family = code === CODE_IP6 ? 6 : 4
- }
- }
-
- if (family == null || transport == null || host == null || port == null) {
- throw new Error('multiaddr must have a valid format: "/{ip4, ip6, dns4, dns6, dnsaddr}/{address}/{tcp, udp}/{port}".')
- }
-
- const opts: MultiaddrObject = {
- family,
- host,
- transport,
- port
- }
-
- return opts
- }
-
getComponents (): Component[] {
return [
...this.#components
]
}
- protos (): Protocol[] {
- return this.#components.map(({ code, value }) => {
- const codec = registry.getProtocol(code)
-
- return {
- code,
- size: codec.size ?? 0,
- name: codec.name,
- resolvable: Boolean(codec.resolvable),
- path: Boolean(codec.path)
- }
- })
- }
-
- protoCodes (): number[] {
- return this.#components.map(({ code }) => code)
- }
-
- protoNames (): string[] {
- return this.#components.map(({ name }) => name)
- }
-
- tuples (): Tuple[] {
- return this.#components.map(({ code, value }) => {
- if (value == null) {
- return [code]
- }
-
- const codec = registry.getProtocol(code)
- const output: Tuple = [code]
-
- if (value != null) {
- output.push(codec.valueToBytes?.(value) ?? uint8ArrayFromString(value))
- }
-
- return output
- })
- }
-
- stringTuples (): Array<[number, string?]> {
- return this.#components.map(({ code, value }) => {
- if (value == null) {
- return [code]
- }
-
- return [code, value]
- })
- }
-
encapsulate (addr: MultiaddrInput): MultiaddrInterface {
const ma = new Multiaddr(addr)
@@ -221,7 +107,7 @@ export class Multiaddr implements MultiaddrInterface {
const i = s.lastIndexOf(addrString)
if (i < 0) {
- throw new InvalidParametersError(`Address ${this.toString()} does not contain subaddress: ${addr.toString()}`)
+ throw new InvalidParametersError(`Address ${this.toString()} does not contain subaddress: ${addrString}`)
}
return new Multiaddr(s.slice(0, i), {
@@ -244,109 +130,10 @@ export class Multiaddr implements MultiaddrInterface {
})
}
- getPeerId (): string | null {
- try {
- let tuples: Array<[number, string | undefined]> = []
-
- this.#components.forEach(({ code, value }) => {
- if (code === CODE_P2P) {
- tuples.push([code, value])
- }
-
- // if this is a p2p-circuit address, return the target peer id if present
- // not the peer id of the relay
- if (code === CODE_P2P_CIRCUIT) {
- tuples = []
- }
- })
-
- // Get the last ipfs tuple ['p2p', 'peerid string']
- const tuple = tuples.pop()
- if (tuple?.[1] != null) {
- const peerIdStr = tuple[1]
-
- // peer id is base58btc encoded string but not multibase encoded so add the `z`
- // prefix so we can validate that it is correctly encoded
- if (peerIdStr[0] === 'Q' || peerIdStr[0] === '1') {
- return uint8ArrayToString(base58btc.decode(`z${peerIdStr}`), 'base58btc')
- }
-
- // try to parse peer id as CID
- return uint8ArrayToString(CID.parse(peerIdStr).multihash.bytes, 'base58btc')
- }
-
- return null
- } catch (e) {
- return null
- }
- }
-
- getPath (): string | null {
- for (const component of this.#components) {
- const codec = registry.getProtocol(component.code)
-
- if (!codec.path) {
- continue
- }
-
- return component.value ?? null
- }
-
- return null
- }
-
equals (addr: { bytes: Uint8Array }): boolean {
return uint8ArrayEquals(this.bytes, addr.bytes)
}
- async resolve (options?: ResolveOptions): Promise {
- const resolvableProto = this.protos().find((p) => p.resolvable)
-
- // Multiaddr is not resolvable?
- if (resolvableProto == null) {
- return [this]
- }
-
- const resolver = resolvers.get(resolvableProto.name)
- if (resolver == null) {
- throw new NoAvailableResolverError(`no available resolver for ${resolvableProto.name}`)
- }
-
- const result = await resolver(this, options)
-
- return result.map(str => multiaddr(str))
- }
-
- nodeAddress (): NodeAddress {
- const options = this.toOptions()
-
- if (options.transport !== 'tcp' && options.transport !== 'udp') {
- throw new Error(`multiaddr must have a valid format - no protocol with name: "${options.transport}". Must have a valid transport protocol: "{tcp, udp}"`)
- }
-
- return {
- family: options.family,
- address: options.host,
- port: options.port
- }
- }
-
- isThinWaistAddress (): boolean {
- if (this.#components.length !== 2) {
- return false
- }
-
- if (this.#components[0].code !== CODE_IP4 && this.#components[0].code !== CODE_IP6) {
- return false
- }
-
- if (this.#components[1].code !== CODE_TCP && this.#components[1].code !== CODE_UDP) {
- return false
- }
-
- return true
- }
-
/**
* Returns Multiaddr as a human-readable string
* https://nodejs.org/api/util.html#utilinspectcustom
diff --git a/src/protocols-table.ts b/src/protocols-table.ts
deleted file mode 100644
index 82105da5..00000000
--- a/src/protocols-table.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import type { Protocol } from './index.js'
-
-const V = -1
-export const names: Record = {}
-export const codes: Record = {}
-
-export const table: Array<[number, number, string, boolean?, boolean?]> = [
- [4, 32, 'ip4'],
- [6, 16, 'tcp'],
- [33, 16, 'dccp'],
- [41, 128, 'ip6'],
- [42, V, 'ip6zone'],
- [43, 8, 'ipcidr'],
- [53, V, 'dns', true],
- [54, V, 'dns4', true],
- [55, V, 'dns6', true],
- [56, V, 'dnsaddr', true],
- [132, 16, 'sctp'],
- [273, 16, 'udp'],
- [275, 0, 'p2p-webrtc-star'],
- [276, 0, 'p2p-webrtc-direct'],
- [277, 0, 'p2p-stardust'],
- [280, 0, 'webrtc-direct'],
- [281, 0, 'webrtc'],
- [290, 0, 'p2p-circuit'],
- [301, 0, 'udt'],
- [302, 0, 'utp'],
- [400, V, 'unix', false, true],
- // `ipfs` is added before `p2p` for legacy support.
- // All text representations will default to `p2p`, but `ipfs` will
- // still be supported
- [421, V, 'ipfs'],
- // `p2p` is the preferred name for 421, and is now the default
- [421, V, 'p2p'],
- [443, 0, 'https'],
- [444, 96, 'onion'],
- [445, 296, 'onion3'],
- [446, V, 'garlic64'],
- [448, 0, 'tls'],
- [449, V, 'sni'],
- [460, 0, 'quic'],
- [461, 0, 'quic-v1'],
- [465, 0, 'webtransport'],
- [466, V, 'certhash'],
- [477, 0, 'ws'],
- [478, 0, 'wss'],
- [479, 0, 'p2p-websocket-star'],
- [480, 0, 'http'],
- [481, V, 'http-path'],
- [777, V, 'memory']
-]
-
-// populate tables
-table.forEach(row => {
- const proto = createProtocol(...row)
- codes[proto.code] = proto
- names[proto.name] = proto
-})
-
-export function createProtocol (code: number, size: number, name: string, resolvable?: any, path?: any): Protocol {
- return {
- code,
- size,
- name,
- resolvable: Boolean(resolvable),
- path: Boolean(path)
- }
-}
-
-/**
- * For the passed proto string or number, return a {@link Protocol}
- *
- * @example
- *
- * ```js
- * import { protocol } from '@multiformats/multiaddr'
- *
- * console.info(protocol(4))
- * // { code: 4, size: 32, name: 'ip4', resolvable: false, path: false }
- * ```
- *
- * @deprecated This will be removed in a future version
- */
-export function getProtocol (proto: number | string): Protocol {
- if (typeof proto === 'number') {
- if (codes[proto] != null) {
- return codes[proto]
- }
-
- throw new Error(`no protocol with code: ${proto}`)
- } else if (typeof proto === 'string') {
- if (names[proto] != null) {
- return names[proto]
- }
-
- throw new Error(`no protocol with name: ${proto}`)
- }
-
- throw new Error(`invalid protocol id type: ${typeof proto}`)
-}
diff --git a/src/registry.ts b/src/registry.ts
index bd8662d9..1c345467 100644
--- a/src/registry.ts
+++ b/src/registry.ts
@@ -28,20 +28,6 @@ export interface ProtocolCodec {
*/
size?: number
- /**
- * If this protocol is a path protocol.
- *
- * @deprecated This will be removed in a future release
- */
- path?: boolean
-
- /**
- * If this protocol can be resolved using configured resolvers.
- *
- * @deprecated This will be removed in a future release
- */
- resolvable?: boolean
-
/**
* If specified this protocol codec will also be used to decode tuples with
* these names from string multiaddrs.
@@ -179,23 +165,19 @@ const codecs: ProtocolCodec[] = [{
}, {
code: CODE_DNS,
name: 'dns',
- size: V,
- resolvable: true
+ size: V
}, {
code: CODE_DNS4,
name: 'dns4',
- size: V,
- resolvable: true
+ size: V
}, {
code: CODE_DNS6,
name: 'dns6',
- size: V,
- resolvable: true
+ size: V
}, {
code: CODE_DNSADDR,
name: 'dnsaddr',
- size: V,
- resolvable: true
+ size: V
}, {
code: CODE_SCTP,
name: 'sctp',
@@ -213,7 +195,6 @@ const codecs: ProtocolCodec[] = [{
code: CODE_UNIX,
name: 'unix',
size: V,
- path: true,
stringToValue: (str) => decodeURIComponent(str),
valueToString: (val) => encodeURIComponent(val)
}, {
diff --git a/src/resolvers/dnsaddr.ts b/src/resolvers/dnsaddr.ts
deleted file mode 100644
index e5db8581..00000000
--- a/src/resolvers/dnsaddr.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { dns, RecordType } from '@multiformats/dns'
-import { multiaddr } from '../index.js'
-import { getProtocol } from '../protocols-table.js'
-import type { Resolver } from './index.js'
-import type { AbortOptions, Multiaddr } from '../index.js'
-import type { DNS } from '@multiformats/dns'
-
-const MAX_RECURSIVE_DEPTH = 32
-const { code: dnsaddrCode } = getProtocol('dnsaddr')
-
-class RecursionLimitError extends Error {
- constructor (message = 'Max recursive depth reached') {
- super(message)
- this.name = 'RecursionLimitError'
- }
-}
-
-/**
- * @deprecated DNS resolving will be removed in a future release
- */
-export interface DNSADDROptions extends AbortOptions {
- /**
- * An optional DNS resolver
- */
- dns?: DNS
-
- /**
- * When resolving DNSADDR Multiaddrs that resolve to other DNSADDR Multiaddrs,
- * limit how many times we will recursively resolve them.
- *
- * @default 32
- */
- maxRecursiveDepth?: number
-}
-
-/**
- * @deprecated DNS resolving will be removed in a future release
- */
-export const dnsaddrResolver: Resolver = async function dnsaddrResolver (ma: Multiaddr, options: DNSADDROptions = {}): Promise {
- const recursionLimit = options.maxRecursiveDepth ?? MAX_RECURSIVE_DEPTH
-
- if (recursionLimit === 0) {
- throw new RecursionLimitError('Max recursive depth reached')
- }
-
- const [, hostname] = ma.stringTuples().find(([proto]) => proto === dnsaddrCode) ?? []
-
- const resolver = options?.dns ?? dns()
- const result = await resolver.query(`_dnsaddr.${hostname}`, {
- signal: options?.signal,
- types: [
- RecordType.TXT
- ]
- })
-
- const peerId = ma.getPeerId()
- const output: string[] = []
-
- for (const answer of result.Answer) {
- const addr = answer.data
- .replace(/["']/g, '')
- .trim()
- .split('=')[1]
-
- if (addr == null) {
- continue
- }
-
- if (peerId != null && !addr.includes(peerId)) {
- continue
- }
-
- const ma = multiaddr(addr)
-
- if (addr.startsWith('/dnsaddr')) {
- const resolved = await ma.resolve({
- ...options,
- maxRecursiveDepth: recursionLimit - 1
- })
-
- output.push(...resolved.map(ma => ma.toString()))
- } else {
- output.push(ma.toString())
- }
- }
-
- return output
-}
diff --git a/src/resolvers/index.ts b/src/resolvers/index.ts
deleted file mode 100644
index 66d8320b..00000000
--- a/src/resolvers/index.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import type { AbortOptions, Multiaddr } from '../index.js'
-
-/**
- * @deprecated DNS resolving will be removed in a future release
- */
-export interface Resolver {
- (ma: Multiaddr, options?: ResolveOptions): Promise
-}
-
-export { dnsaddrResolver } from './dnsaddr.js'
-export type { DNSADDROptions } from './dnsaddr.js'
diff --git a/test/convert.spec.ts b/test/convert.spec.ts
deleted file mode 100644
index 642776df..00000000
--- a/test/convert.spec.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/* eslint-env mocha */
-import { expect } from 'aegir/chai'
-import { convertToIpNet } from '../src/convert.ts'
-import { multiaddr } from '../src/index.js'
-
-describe('convert', () => {
- it('convertToIpNet ip4', function () {
- const ipnet = convertToIpNet(multiaddr('/ip4/192.0.2.0/ipcidr/24'))
- expect(ipnet.toString()).equal('192.0.2.0/24')
- })
-
- it('convertToIpNet ip6', function () {
- const ipnet = convertToIpNet(multiaddr('/ip6/2001:0db8:85a3:0000:0000:8a2e:0370:7334/ipcidr/64'))
- expect(ipnet.toString()).equal('2001:0db8:85a3:0000:0000:0000:0000:0000/64')
- })
-
- it('convertToIpNet not ipcidr', function () {
- expect(() => convertToIpNet(multiaddr('/ip6/2001:0db8:85a3:0000:0000:8a2e:0370:7334/tcp/64'))).to.throw()
- })
-
- it('convertToIpNet not ipv6', function () {
- expect(() => convertToIpNet(multiaddr('/dns6/foo.com/ipcidr/64'))).to.throw()
- })
-})
diff --git a/test/filter/multiaddr-filter.spec.ts b/test/filter/multiaddr-filter.spec.ts
deleted file mode 100644
index dbf7f55e..00000000
--- a/test/filter/multiaddr-filter.spec.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/* eslint-env mocha */
-import { expect } from 'aegir/chai'
-import { MultiaddrFilter, multiaddr } from '../../src/index.js'
-import type { MultiaddrInput } from '../../src/index.js'
-
-describe('MultiaddrFilter', () => {
- const cases: Array<[MultiaddrInput, MultiaddrInput, boolean]> = [
- ['/ip4/192.168.10.10/ipcidr/24', '/ip4/192.168.10.2/tcp/60', true],
- [multiaddr('/ip4/192.168.10.10/ipcidr/24'), '/ip4/192.168.10.2/tcp/60', true],
- [multiaddr('/ip4/192.168.10.10/ipcidr/24').bytes, '/ip4/192.168.10.2/tcp/60', true],
- ['/ip4/192.168.10.10/ipcidr/24', '/ip4/192.168.10.2/udp/60', true],
- ['/ip4/192.168.10.10/ipcidr/24', multiaddr('/ip4/192.168.11.2/tcp/60'), false],
- ['/ip4/192.168.10.10/ipcidr/24', null, false],
- ['/ip4/192.168.10.10/ipcidr/24', multiaddr('/ip4/192.168.11.2/udp/60').bytes, false],
- ['/ip4/192.168.10.10/ipcidr/24', '/ip4/192.168.11.2/udp/60', false],
- ['/ip4/192.168.10.10/ipcidr/24', '/ip6/2001:db8:3333:4444:5555:6666:7777:8888/tcp/60', false],
- ['/ip6/2001:db8:3333:4444:5555:6666:7777:8888/ipcidr/60', '/ip6/2001:0db8:3333:4440:0000:0000:0000:0000/tcp/60', true],
- ['/ip6/2001:db8:3333:4444:5555:6666:7777:8888/ipcidr/60', '/ip6/2001:0db8:3333:4450:0000:0000:0000:0000/tcp/60', false],
- ['/ip6/2001:db8:3333:4444:5555:6666:7777:8888/ipcidr/128', '/ip6/2001:db8:3333:4444:5555:6666:7777:8888/tcp/60', true],
- ['/ip6/2001:db8:3333:4444:5555:6666:7777:8888/ipcidr/128', '/ip6/2001:db8:3333:4444:5555:6666:7777:8880/tcp/60', false]
- ]
-
- cases.forEach(([cidr, ip, result]) => {
- it(`multiaddr filter cidr=${cidr} ip=${ip} result=${String(result)}`, function () {
- expect(new MultiaddrFilter(cidr).contains(ip)).to.be.equal(result)
- })
- })
-})
diff --git a/test/index.spec.ts b/test/index.spec.ts
index d37b983f..f73f274a 100644
--- a/test/index.spec.ts
+++ b/test/index.spec.ts
@@ -2,8 +2,7 @@
/* eslint-env mocha */
import { expect } from 'aegir/chai'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
-import { multiaddr, isMultiaddr, fromNodeAddress, isName, fromTuples, fromStringTuples } from '../src/index.js'
-import { codes } from '../src/protocols-table.js'
+import { multiaddr, isMultiaddr, CODE_IP4 } from '../src/index.js'
import type { Multiaddr } from '../src/index.js'
function roundTrip (str: string): void {
@@ -140,10 +139,17 @@ describe('manipulation', () => {
expect(udpAddr.toString()).to.equal(udpAddrStr)
expect(udpAddr.bytes).to.equalBytes(udpAddrBuf)
- expect(udpAddr.protoCodes()).to.deep.equal([4, 273])
- expect(udpAddr.protoNames()).to.deep.equal(['ip4', 'udp'])
- expect(udpAddr.protos()).to.deep.equal([codes[4], codes[273]])
- expect(udpAddr.protos()[0] === codes[4]).to.equal(false)
+ expect(udpAddr.getComponents()).to.deep.equal([{
+ bytes: Uint8Array.from([4, 127, 0, 0, 1]),
+ code: 4,
+ name: 'ip4',
+ value: '127.0.0.1'
+ }, {
+ bytes: Uint8Array.from([145, 2, 4, 210]),
+ code: 273,
+ name: 'udp',
+ value: '1234'
+ }])
const udpAddrbytes2 = udpAddr.encapsulate('/udp/5678')
expect(udpAddrbytes2.toString()).to.equal('/ip4/127.0.0.1/udp/1234/udp/5678')
@@ -331,560 +337,144 @@ describe('normalize', () => {
}
})
-describe('helpers', () => {
- describe('.toOptions', () => {
- it('returns a well formed options object', () => {
- expect(multiaddr('/ip4/0.0.0.0/tcp/1234').toOptions())
- .to.eql({
- family: 4,
- host: '0.0.0.0',
- transport: 'tcp',
- port: 1234
- })
- })
-
- it('returns an options object from a DNS addr', () => {
- expect(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(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(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(multiaddr('/dnsaddr/google.net/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').toOptions())
- .to.eql({
- family: 4,
- host: 'google.net',
- transport: 'tcp',
- port: 443
- })
- })
-
- it('returns an options object from an address with an ip6 zone', () => {
- expect(
- multiaddr('/ip6zone/x/ip6/fe80::1/tcp/1234').toOptions()
- ).to.be.eql({
- family: 6,
- host: 'fe80::1%x',
- transport: 'tcp',
- port: 1234
- })
- })
- })
-
- describe('.protos', () => {
- it('returns a list of all protocols in the address', () => {
- expect(multiaddr('/ip4/0.0.0.0/utp').protos())
- .to.eql([{
- code: 4,
- name: 'ip4',
- path: false,
- size: 32,
- resolvable: false
- }, {
- code: 302,
- name: 'utp',
- path: false,
- size: 0,
- resolvable: false
- }])
- })
-
- it('works with ipfs', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/utp/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').protos()
- ).to.be.eql([{
- code: 4,
- name: 'ip4',
- path: false,
- size: 32,
- resolvable: false
- }, {
- code: 302,
- name: 'utp',
- path: false,
- size: 0,
- resolvable: false
- }, {
- code: 421,
- name: 'p2p',
- path: false,
- size: -1,
- resolvable: false
- }])
- })
-
- it('works with p2p', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/utp/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').protos()
- ).to.be.eql([{
+describe('.getComponents', () => {
+ it('returns a list of all protocols in the address', () => {
+ expect(multiaddr('/ip4/0.0.0.0/utp').getComponents())
+ .to.eql([{
code: 4,
name: 'ip4',
- path: false,
- size: 32,
- resolvable: false
+ value: '0.0.0.0'
}, {
code: 302,
- name: 'utp',
- path: false,
- size: 0,
- resolvable: false
- }, {
- code: 421,
- name: 'p2p',
- path: false,
- size: -1,
- resolvable: false
- }])
- })
-
- it('works with unix', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/tcp/8000/unix/tmp%2Fp2p.sock').protos()
- ).to.be.eql([{
- code: 4,
- name: 'ip4',
- path: false,
- size: 32,
- resolvable: false
- }, {
- code: 6,
- name: 'tcp',
- path: false,
- size: 16,
- resolvable: false
- }, {
- code: 400,
- name: 'unix',
- path: true,
- size: -1,
- resolvable: false
- }])
- })
-
- it('works with memory', () => {
- expect(
- multiaddr('/memory/test/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6').protos()
- ).to.be.eql([{
- code: 777,
- name: 'memory',
- path: false,
- size: -1,
- resolvable: false
- }, {
- code: 421,
- name: 'p2p',
- path: false,
- size: -1,
- resolvable: false
+ name: 'utp'
}])
- })
- })
-
- describe('.tuples', () => {
- it('returns the tuples', () => {
- expect(multiaddr('/ip4/0.0.0.0/utp').tuples())
- .to.eql([
- [4, Uint8Array.from([0, 0, 0, 0])],
- [302]
- ])
- })
-
- it('does not allow modifying parts', () => {
- const ma = multiaddr('/ip4/0.0.0.0/tcp/1234')
- const tuples = ma.tuples()
- tuples[0][0] = 41
-
- expect(ma.toOptions()).to.have.property('family', 4)
- })
- })
-
- describe('.stringTuples', () => {
- it('returns the string partss', () => {
- expect(multiaddr('/ip4/0.0.0.0/utp').stringTuples())
- .to.eql([
- [4, '0.0.0.0'],
- [302]
- ])
- })
-
- it('does not allow modifying string parts', () => {
- const ma = multiaddr('/ip4/0.0.0.0/tcp/1234')
- const tuples = ma.stringTuples()
- tuples[0][0] = 41
-
- expect(ma.toOptions()).to.have.property('family', 4)
- })
})
- describe('.decapsulate', () => {
- it('throws on address with no matching subaddress', () => {
- expect(
- () => multiaddr('/ip4/127.0.0.1').decapsulate('/ip4/198.168.0.0')
- ).to.throw(
- /does not contain subaddress/
- )
- })
- })
-
- describe('.decapsulateCode', () => {
- it('removes the last occurrence of the code from the multiaddr', () => {
- const relayTCP = multiaddr('/ip4/0.0.0.0/tcp/8080')
- const relay = relayTCP.encapsulate('/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit')
- const target = multiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
- const original = relay.encapsulate(target)
- expect(original.decapsulateCode(421).toJSON()).to.equal(relay.toJSON())
- expect(relay.decapsulateCode(421).toJSON()).to.equal(relayTCP.toJSON())
- })
-
- it('ignores missing codes', () => {
- const tcp = multiaddr('/ip4/0.0.0.0/tcp/8080')
- expect(tcp.decapsulateCode(421).toJSON()).to.equal(tcp.toJSON())
- })
- })
-
- describe('.equals', () => {
- it('returns true for equal addresses', () => {
- const addr1 = multiaddr('/ip4/192.168.0.1')
- const addr2 = multiaddr('/ip4/192.168.0.1')
-
- expect(addr1.equals(addr2)).to.equal(true)
- })
-
- it('returns false for non equal addresses', () => {
- const addr1 = multiaddr('/ip4/192.168.1.1')
- const addr2 = multiaddr('/ip4/192.168.0.1')
-
- expect(addr1.equals(addr2)).to.equal(false)
- })
- })
-
- describe('.nodeAddress', () => {
- it('throws on an invalid node address', () => {
- expect(
- () => multiaddr('/ip4/192.168.0.1/utp').nodeAddress()
- ).to.throw(
- /multiaddr must have a valid format/
- )
- })
-
- it('returns a node friendly address', () => {
- expect(
- multiaddr('/ip4/192.168.0.1/tcp/1234').nodeAddress()
- ).to.be.eql({
- address: '192.168.0.1',
- family: 4,
- port: 1234
- })
- })
-
- it('returns a node friendly address with dns', () => {
- expect(
- multiaddr('/dns/wss0.bootstrap.libp2p.io/tcp/443').nodeAddress()
- ).to.be.eql({
- address: 'wss0.bootstrap.libp2p.io',
- family: 4,
- port: 443
- })
- })
-
- it('returns a node friendly address with dns4', () => {
- expect(
- multiaddr('/dns4/wss0.bootstrap.libp2p.io/tcp/443').nodeAddress()
- ).to.be.eql({
- address: 'wss0.bootstrap.libp2p.io',
- family: 4,
- port: 443
- })
- })
-
- it('returns a node friendly address with dns6', () => {
- expect(
- multiaddr('/dns6/wss0.bootstrap.libp2p.io/tcp/443').nodeAddress()
- ).to.be.eql({
- address: 'wss0.bootstrap.libp2p.io',
- family: 6,
- port: 443
- })
- })
-
- it('returns a node friendly address with dnsaddr', () => {
- expect(
- multiaddr('/dnsaddr/wss0.bootstrap.libp2p.io/tcp/443').nodeAddress()
- ).to.be.eql({
- address: 'wss0.bootstrap.libp2p.io',
- family: 4,
- port: 443
- })
- })
-
- it('should transform a p2p dnsaddr without a tcp port into a node address', () => {
- expect(
- multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN').nodeAddress()
- ).to.be.eql({
- address: 'bootstrap.libp2p.io',
- family: 4,
- port: 443
- })
- })
-
- it('transforms an address with an ip6 zone', () => {
- expect(
- multiaddr('/ip6zone/x/ip6/fe80::1/tcp/1234').nodeAddress()
- ).to.be.eql({
- address: 'fe80::1%x',
- family: 6,
- port: 1234
- })
- })
-
- it('throws on an invalid format address when the addr is not prefixed with a /', () => {
- expect(
- () => multiaddr('ip4/192.168.0.1/udp').nodeAddress()
- ).to.throw()
- .with.property('name', 'InvalidMultiaddrError')
- })
-
- it('throws on an invalid protocol name when the addr has an invalid one', () => {
- expect(
- () => multiaddr('/ip5/127.0.0.1/udp/5000')
- ).to.throw()
- .with.property('name', 'UnknownProtocolError')
- })
-
- it('throws on an invalid protocol name when the transport protocol is not valid', () => {
- expect(
- () => multiaddr('/ip4/127.0.0.1/utp/5000')
- ).to.throw()
- .with.property('name', 'UnknownProtocolError')
- })
+ it('works with ipfs', () => {
+ expect(
+ multiaddr('/ip4/0.0.0.0/utp/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getComponents()
+ ).to.deep.equal([{
+ code: 4,
+ name: 'ip4',
+ value: '0.0.0.0'
+ }, {
+ code: 302,
+ name: 'utp'
+ }, {
+ code: 421,
+ name: 'p2p',
+ value: 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
+ }])
+ })
+
+ it('works with p2p', () => {
+ expect(
+ multiaddr('/ip4/0.0.0.0/utp/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getComponents()
+ ).to.deep.equal([{
+ code: 4,
+ name: 'ip4',
+ value: '0.0.0.0'
+ }, {
+ code: 302,
+ name: 'utp'
+ }, {
+ code: 421,
+ name: 'p2p',
+ value: 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'
+ }])
+ })
+
+ it('works with unix', () => {
+ expect(
+ multiaddr('/ip4/0.0.0.0/tcp/8000/unix/tmp%2Fp2p.sock').getComponents()
+ ).to.deep.equal([{
+ code: 4,
+ name: 'ip4',
+ value: '0.0.0.0'
+ }, {
+ code: 6,
+ name: 'tcp',
+ value: '8000'
+ }, {
+ code: 400,
+ name: 'unix',
+ value: 'tmp/p2p.sock'
+ }])
+ })
+
+ it('works with memory', () => {
+ expect(
+ multiaddr('/memory/test/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6').getComponents()
+ ).to.deep.equal([{
+ code: 777,
+ name: 'memory',
+ value: 'test'
+ }, {
+ code: 421,
+ name: 'p2p',
+ value: 'QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6'
+ }])
})
- describe('.fromNodeAddress', () => {
- it('throws on missing address object', () => {
- expect(
- // @ts-expect-error incorrect parameters
- () => fromNodeAddress()
- ).to.throw()
- .with.property('name', 'InvalidParametersError')
- })
-
- it('throws on missing transport', () => {
- expect(
- // @ts-expect-error incorrect parameters
- () => fromNodeAddress({ address: '0.0.0.0' })
- ).to.throw()
- .with.property('name', 'InvalidParametersError')
- })
-
- it('parses a node address', () => {
- expect(
- fromNodeAddress({
- address: '192.168.0.1',
- family: 4,
- port: 1234
- }, 'tcp').toString()
- ).to.equal('/ip4/192.168.0.1/tcp/1234')
- })
+ it('does not allow modifying parts', () => {
+ const ma = multiaddr('/ip4/0.0.0.0/tcp/1234')
+ const components = ma.getComponents()
+ components.shift()
- it('parses a node address with an ip6zone', () => {
- expect(
- fromNodeAddress({
- address: 'fe80::1%x',
- family: 6,
- port: 1234
- }, 'tcp').toString()
- ).to.equal('/ip6zone/x/ip6/fe80::1/tcp/1234')
- })
+ expect(ma.getComponents()).to.have.nested.property('[0].code', CODE_IP4)
})
+})
- describe('.fromTuples', () => {
- it('should create a multiaddr from a list of tuples', () => {
- const ma = multiaddr('/ip4/0.0.0.0')
- const tuples = ma.tuples()
- tuples.push([0x06, Uint8Array.from([0, 100])])
-
- const ma2 = fromTuples(tuples)
- expect(ma2.toString()).to.equal('/ip4/0.0.0.0/tcp/100')
- })
+describe('.decapsulate', () => {
+ it('throws on address with no matching subaddress', () => {
+ expect(
+ () => multiaddr('/ip4/127.0.0.1').decapsulate('/ip4/198.168.0.0')
+ ).to.throw(
+ /does not contain subaddress/
+ )
})
+})
- describe('.fromStringTuples', () => {
- it('should create a multiaddr from a list of string tuples', () => {
- const ma = multiaddr('/ip4/0.0.0.0')
- const tuples = ma.stringTuples()
- tuples.push([0x06, '100'])
-
- const ma2 = fromStringTuples(tuples)
- expect(ma2.toString()).to.equal('/ip4/0.0.0.0/tcp/100')
- })
+describe('.decapsulateCode', () => {
+ it('removes the last occurrence of the code from the multiaddr', () => {
+ const relayTCP = multiaddr('/ip4/0.0.0.0/tcp/8080')
+ const relay = relayTCP.encapsulate('/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit')
+ const target = multiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
+ const original = relay.encapsulate(target)
+ expect(original.decapsulateCode(421).toJSON()).to.equal(relay.toJSON())
+ expect(relay.decapsulateCode(421).toJSON()).to.equal(relayTCP.toJSON())
})
- describe('.isThinWaistAddress', () => {
- const families = ['ip4', 'ip6']
- const transports = ['tcp', 'udp']
- const addresses: Record = {
- ip4: '192.168.0.1',
- ip6: '2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095'
- }
- families.forEach((family) => {
- transports.forEach((transport) => {
- it(`returns true for /${family}-${transport}`, () => {
- expect(
- multiaddr(`/${family}/${addresses[family]}/${transport}/1234`).isThinWaistAddress()
- ).to.equal(true)
- })
- })
- })
-
- it('returns false for two protocols not using {IPv4, IPv6}/{TCP, UDP}', () => {
- expect(
- multiaddr('/ip4/192.168.0.1/utp').isThinWaistAddress()
- ).to.be.false()
-
- expect(
- multiaddr('/ip4/192.168.0.1/sctp/1234').isThinWaistAddress()
- ).to.be.false()
-
- expect(
- multiaddr('/http/utp').isThinWaistAddress()
- ).to.be.false()
- })
-
- it('returns false for more than two protocols', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/utp').isThinWaistAddress()
- ).to.be.false()
- })
+ it('ignores missing codes', () => {
+ const tcp = multiaddr('/ip4/0.0.0.0/tcp/8080')
+ expect(tcp.decapsulateCode(421).toJSON()).to.equal(tcp.toJSON())
})
+})
- describe('.getPeerId should parse id from multiaddr', () => {
- it('extracts the peer Id from a multiaddr, p2p', () => {
- expect(
- multiaddr('/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
- ).to.equal('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
- })
- it('extracts the correct peer Id from a circuit multiaddr', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmZR5a9AAXGqQF2ADqoDdGS8zvqv8n3Pag6TDDnTNMcFW6/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPeerId()
- ).to.equal('QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
- })
- it('extracts the peer Id from a multiaddr, p2p and CIDv1 Base32', () => {
- expect(
- multiaddr('/p2p-circuit/p2p/bafzbeigweq4zr4x4ky2dvv7nanbkw6egutvrrvzw6g3h2rftp7gidyhtt4').getPeerId()
- ).to.equal('QmckZzdVd72h9QUFuJJpQqhsZqGLwjhh81qSvZ9BhB2FQi')
- })
- it('extracts the peer Id from a multiaddr, p2p and CIDv1 Base32, where Id contains non b58 chars', () => {
- expect(
- multiaddr('/p2p-circuit/p2p/bafzbeidt255unskpefjmqb2rc27vjuyxopkxgaylxij6pw35hhys4vnyp4').getPeerId()
- ).to.equal('QmW8rAgaaA6sRydK1k6vonShQME47aDxaFidbtMevWs73t')
- })
- it('extracts the peer Id from a multiaddr, p2p and base58btc encoded identity multihash', () => {
- expect(
- multiaddr('/p2p-circuit/p2p/12D3KooWNvSZnPi3RrhrTwEY4LuuBeB6K6facKUCJcyWG1aoDd2p').getPeerId()
- ).to.equal('12D3KooWNvSZnPi3RrhrTwEY4LuuBeB6K6facKUCJcyWG1aoDd2p')
- })
- it('does not extract a peer Id from a circuit relay multiaddr where only the relay peer id is present', () => {
- expect(
- multiaddr('/ip4/127.0.0.1/tcp/123/p2p/bafzbeigweq4zr4x4ky2dvv7nanbkw6egutvrrvzw6g3h2rftp7gidyhtt4/p2p-circuit').getPeerId()
- ).to.be.null()
- })
- })
+describe('.equals', () => {
+ it('returns true for equal addresses', () => {
+ const addr1 = multiaddr('/ip4/192.168.0.1')
+ const addr2 = multiaddr('/ip4/192.168.0.1')
- describe('.getPeerId should return null on missing peer id in multiaddr', () => {
- it('parses extracts the peer Id from a multiaddr', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/utp').getPeerId()
- ).to.be.null()
- })
+ expect(addr1.equals(addr2)).to.equal(true)
})
- describe('.getPath', () => {
- it('should return a path for unix', () => {
- expect(
- multiaddr('/unix/%2Ftmp%2Fp2p.sock').getPath()
- ).to.eql('/tmp/p2p.sock')
- })
+ it('returns false for non equal addresses', () => {
+ const addr1 = multiaddr('/ip4/192.168.1.1')
+ const addr2 = multiaddr('/ip4/192.168.0.1')
- it('should return a path for unix when other protos exist', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/unix/%2Ftmp%2Fp2p.sock').getPath()
- ).to.eql('/tmp/p2p.sock')
- })
-
- it('should not return a path when no path proto exists', () => {
- expect(
- multiaddr('/ip4/0.0.0.0/tcp/1234/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC').getPath()
- ).to.eql(null)
- })
+ expect(addr1.equals(addr2)).to.equal(false)
})
+})
- describe('multiaddr.isMultiaddr', () => {
- it('handles different inputs', () => {
- expect(isMultiaddr(multiaddr('/'))).to.be.eql(true)
- expect(isMultiaddr(multiaddr('/ip4/192.0.2.0/ipcidr/24'))).to.be.eql(true)
- expect(isMultiaddr('/')).to.be.eql(false)
- expect(isMultiaddr(123)).to.be.eql(false)
+describe('multiaddr.isMultiaddr', () => {
+ it('handles different inputs', () => {
+ expect(isMultiaddr(multiaddr('/'))).to.deep.equal(true)
+ expect(isMultiaddr(multiaddr('/ip4/192.0.2.0/ipcidr/24'))).to.deep.equal(true)
+ expect(isMultiaddr('/')).to.deep.equal(false)
+ expect(isMultiaddr(123)).to.deep.equal(false)
- expect(isMultiaddr(uint8ArrayFromString('/hello'))).to.be.eql(false)
- })
- })
-
- describe('resolvable multiaddrs', () => {
- describe('.isName', () => {
- it('valid name dns', () => {
- const str = '/dns/ipfs.io'
- const addr = multiaddr(str)
- expect(isName(addr)).to.equal(true)
- })
-
- it('valid name dnsaddr', () => {
- const str = '/dnsaddr/ipfs.io'
- const addr = multiaddr(str)
- expect(isName(addr)).to.equal(true)
- })
-
- it('valid name dns4', () => {
- const str = '/dns4/ipfs.io'
- const addr = multiaddr(str)
- expect(isName(addr)).to.equal(true)
- })
-
- it('valid name dns6', () => {
- const str = '/dns6/ipfs.io'
- const addr = multiaddr(str)
- expect(isName(addr)).to.equal(true)
- })
-
- it('invalid name', () => {
- const str = '/ip4/127.0.0.1'
- const addr = multiaddr(str)
- expect(isName(addr)).to.equal(false)
- })
- })
+ expect(isMultiaddr(uint8ArrayFromString('/hello'))).to.deep.equal(false)
})
})
diff --git a/test/protocols.spec.ts b/test/protocols.spec.ts
deleted file mode 100644
index 12c1b519..00000000
--- a/test/protocols.spec.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/* eslint-env mocha */
-import { expect } from 'aegir/chai'
-import { protocols } from '../src/index.js'
-
-describe('protocols', () => {
- describe('throws on non existent protocol', () => {
- it('number', () => {
- expect(
- () => protocols(1234)
- ).to.throw()
- .with.property('name', 'UnknownProtocolError')
- })
-
- it('string', () => {
- expect(
- () => protocols('hello')
- ).to.throw()
- .with.property('name', 'UnknownProtocolError')
- })
-
- it('else', () => {
- expect(
- // @ts-expect-error incorrect parameters
- () => protocols({ hi: 34 })
- ).to.throw()
- .with.property('name', 'UnknownProtocolError')
- })
- })
-})
diff --git a/test/resolvers.spec.ts b/test/resolvers.spec.ts
deleted file mode 100644
index 719b6d10..00000000
--- a/test/resolvers.spec.ts
+++ /dev/null
@@ -1,211 +0,0 @@
-import { RecordType } from '@multiformats/dns'
-import { expect } from 'aegir/chai'
-import sinon from 'sinon'
-import { stubInterface } from 'sinon-ts'
-import { multiaddr, resolvers } from '../src/index.js'
-import { dnsaddrResolver } from '../src/resolvers/index.js'
-import type { DNS } from '@multiformats/dns'
-import type { StubbedInstance } from 'sinon-ts'
-
-const stubs: Record = {
- '_dnsaddr.bootstrap.libp2p.io': [
- 'dnsaddr=/dnsaddr/ams-1.bootstrap.libp2p.io/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
- 'dnsaddr=/dnsaddr/ams-2.bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb'
- ],
- '_dnsaddr.ams-1.bootstrap.libp2p.io': [
- 'dnsaddr=/ip4/147.75.83.83/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
- 'dnsaddr=/ip4/147.75.83.83/tcp/443/wss/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
- 'dnsaddr=/ip4/147.75.83.83/udp/4001/quic/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
- 'dnsaddr=/ip6/2604:1380:2000:7a00::1/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
- 'dnsaddr=/ip6/2604:1380:2000:7a00::1/tcp/443/wss/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd',
- 'dnsaddr=/ip6/2604:1380:2000:7a00::1/udp/4001/quic/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd'
- ],
- '_dnsaddr.ams-2.bootstrap.libp2p.io': [
- 'dnsaddr=/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
- 'dnsaddr=/ip4/147.75.83.83/tcp/443/wss/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
- 'dnsaddr=/ip4/147.75.83.83/udp/4001/quic/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
- 'dnsaddr=/ip6/2604:1380:2000:7a00::1/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
- 'dnsaddr=/ip6/2604:1380:2000:7a00::1/tcp/443/wss/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
- 'dnsaddr=/ip6/2604:1380:2000:7a00::1/udp/4001/quic/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb'
- ],
- '_dnsaddr.bad-addrs.libp2p.io': [
- 'dnsaddr=/dnsaddr/sv15.bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
- 'dnsaddr=/dnsaddr/ny5.bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa',
- 'dnsaddr_record_value',
- 'dnsaddr=/dnsaddr/am6.bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
- 'dnsaddr=/dnsaddr/sg1.bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt'
- ],
- '_dnsaddr.am6.bootstrap.libp2p.io': [
- 'dnsaddr=/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb'
- ],
- '_dnsaddr.self-referential.io': [
- 'dnsaddr=/dnsaddr/self-referential.io'
- ],
- '_dnsaddr.double-quoted-answer.io': [
- '"dnsaddr=/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb"'
- ],
- '_dnsaddr.single-quoted-answer.io': [
- "'dnsaddr=/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb'"
- ],
- '_dnsaddr.mixed-quoted-answer.io': [
- '"\'""" dnsaddr=/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb" "'
- ]
-}
-
-describe('multiaddr resolve', () => {
- let dns: StubbedInstance
-
- beforeEach(() => {
- dns = stubInterface({
- query: sinon.stub().callsFake((domain) => {
- if (stubs[domain] != null) {
- return {
- Answer: stubs[domain].map(data => ({
- name: '_dnsaddr.bootstrap.libp2p.io',
- type: RecordType.TXT,
- ttl: 100,
- data
- }))
- }
- }
-
- throw new Error(`No result stubbed for ${domain}`)
- })
- })
-
- resolvers.set('dnsaddr', dnsaddrResolver)
- })
-
- it('should throw if no resolver is available', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
-
- resolvers.clear()
-
- // Resolve
- await expect(ma.resolve()).to.eventually.be.rejected()
- .and.to.have.property('name', 'NoAvailableResolverError')
- })
-
- describe('dnsaddr', () => {
- afterEach(() => {
- sinon.restore()
- })
-
- it('can resolve dnsaddr without no peerId', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
-
- // Resolve
- const resolvedMas = await ma.resolve({
- dns
- })
-
- expect(resolvedMas).to.deep.equal([
- ...stubs['_dnsaddr.ams-1.bootstrap.libp2p.io'].map(addr => multiaddr(addr.split('=').pop())),
- ...stubs['_dnsaddr.ams-2.bootstrap.libp2p.io'].map(addr => multiaddr(addr.split('=').pop()))
- ])
- })
-
- it('can resolve dnsaddr with peerId', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
-
- // Resolve
- const resolvedMas = await ma.resolve({
- dns
- })
-
- expect(resolvedMas).to.deep.equal([
- ...stubs['_dnsaddr.ams-2.bootstrap.libp2p.io'].map(addr => multiaddr(addr.split('=').pop()))
- ])
- })
-
- it('can resolve dnsaddr with bad record', async () => {
- const ma = multiaddr('/dnsaddr/bad-addrs.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
-
- // Resolve
- const resolvedMas = await ma.resolve({
- dns
- })
-
- // Should only have one address with the same peer id and should ignore the bad record
- expect(resolvedMas).to.have.lengthOf(1)
- expect(resolvedMas[0].toString()).to.equal(stubs['_dnsaddr.am6.bootstrap.libp2p.io'][0].split('=').pop())
- })
-
- it('can cancel resolving', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.ii/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nc')
- const controller = new AbortController()
-
- // Resolve
- const resolvePromise = ma.resolve({
- signal: controller.signal
- })
-
- controller.abort()
-
- await expect(resolvePromise).to.eventually.be.rejected()
- })
-
- it('should abort resolving deeply nested records', async () => {
- const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
-
- // Resolve
- const resolvePromise = ma.resolve({
- dns,
- maxRecursiveDepth: 1
- })
-
- await expect(resolvePromise).to.eventually.be.rejected().with.property('name', 'RecursionLimitError')
- })
-
- it('should handle recursive loops', async () => {
- const ma = multiaddr('/dnsaddr/self-referential.io')
-
- // Resolve
- const resolvePromise = ma.resolve({
- dns,
- maxRecursiveDepth: 1
- })
-
- await expect(resolvePromise).to.eventually.be.rejected().with.property('name', 'RecursionLimitError')
- })
-
- it('should handle double quotes', async () => {
- const ma = multiaddr('/dnsaddr/double-quoted-answer.io')
-
- // Resolve
- const resolvedMas = await ma.resolve({
- dns
- })
-
- // Should ignore double quotes
- expect(resolvedMas).to.have.lengthOf(1)
- expect(resolvedMas[0].toString()).to.equal('/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
- })
-
- it('should handle single quotes', async () => {
- const ma = multiaddr('/dnsaddr/single-quoted-answer.io')
-
- // Resolve
- const resolvedMas = await ma.resolve({
- dns
- })
-
- // Should ignore double quotes
- expect(resolvedMas).to.have.lengthOf(1)
- expect(resolvedMas[0].toString()).to.equal('/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
- })
-
- it('should handle mixed quotes', async () => {
- const ma = multiaddr('/dnsaddr/mixed-quoted-answer.io')
-
- // Resolve
- const resolvedMas = await ma.resolve({
- dns
- })
-
- // Should ignore double quotes
- expect(resolvedMas).to.have.lengthOf(1)
- expect(resolvedMas[0].toString()).to.equal('/ip4/147.75.83.83/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb')
- })
- })
-})
diff --git a/typedoc.json b/typedoc.json
index 41f5560e..db0b0747 100644
--- a/typedoc.json
+++ b/typedoc.json
@@ -1,7 +1,6 @@
{
+ "readme": "none",
"entryPoints": [
- "./src/index.ts",
- "./src/convert.ts",
- "./src/resolvers/index.ts"
+ "./src/index.ts"
]
}