@multiformats/multiaddr
Version:
multiaddr implementation (binary + string representation of network addresses)
692 lines • 20.7 kB
TypeScript
/**
* @packageDocumentation
*
* 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
*
* @example
*
* ```TypeScript
* import { multiaddr } from '@multiformats/multiaddr'
*
* const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
*
* addr.bytes
* // <Uint8Array 04 7f 00 00 01 11 04 d2>
*
* addr.toString()
* // '/ip4/127.0.0.1/udp/1234'
*
* addr.protos()
* // [
* // {code: 4, name: 'ip4', size: 32},
* // {code: 273, name: 'udp', size: 16}
* // ]
*
* // 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
* to the protocol registry:
*
* ```ts
* import { registry, V, multiaddr } from '@multiformats/multiaddr'
* import type { ProtocolCodec } from '@multiformats/multiaddr'
*
* const maWithCustomTuple = '/custom-protocol/hello'
*
* // throws UnknownProtocolError
* multiaddr(maWithCustomTuple)
*
* const protocol: ProtocolCodec = {
* code: 2059,
* name: 'custom-protocol',
* size: V
* // V means variable length, can also be 0, a positive integer (e.g. a fixed
* // length or omitted
* }
*
* registry.addProtocol(protocol)
*
* // does not throw UnknownProtocolError
* multiaddr(maWithCustomTuple)
*
* // protocols can also be removed
* registry.removeProtocol(protocol.code)
* ```
*/
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
* multiaddr tuples from bytes to string and back again, and also validation of
* the address values.
*/
export interface Registry {
/**
* Retrieve a protocol definition by it's code or name
*/
getProtocol(key: string | number): ProtocolCodec;
/**
* Add a new protocol definition
*/
addProtocol(codec: ProtocolCodec): void;
/**
* Remove a protocol definition by it's code
*/
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 declare const resolvers: Map<string, Resolver<AbortOptions>>;
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.
*
* Component names/codes are defined in the protocol table.
*
* @see https://github.com/multiformats/multiaddr/blob/master/protocols.csv
*/
export interface Component {
/**
* The code of the component as defined in the protocol table
*/
code: number;
/**
* The name of the component as defined in the protocol table
*/
name: string;
/**
* The component value, if one is present
*/
value?: string;
/**
* The bytes that make up the component. This will be set if the multiaddr
* was parsed from a `Uint8Array`, or if `.bytes` has been accessed on it.
*/
bytes?: Uint8Array;
}
export interface Multiaddr {
bytes: Uint8Array;
/**
* Returns Multiaddr as a String
*
* @example
* ```js
* import { multiaddr } from '@multiformats/multiaddr'
*
* multiaddr('/ip4/127.0.0.1/tcp/4001').toString()
* // '/ip4/127.0.0.1/tcp/4001'
* ```
*/
toString(): string;
/**
* Returns Multiaddr as a JSON encoded object
*
* @example
* ```js
* import { multiaddr } from '@multiformats/multiaddr'
*
* JSON.stringify(multiaddr('/ip4/127.0.0.1/tcp/4001'))
* // '/ip4/127.0.0.1/tcp/4001'
* ```
*/
toJSON(): string;
/**
* Returns the components that make up this Multiaddr
*
* @example
* ```ts
* import { multiaddr } from '@multiformats/multiaddr'
*
* multiaddr('/ip4/127.0.0.1/tcp/4001').getComponents()
* // [{ name: 'ip4', code: 4, value: '127.0.0.1' }, { name: 'tcp', code: 6, value: '4001' }]
* ```
*/
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, <Buffer 7f 00 00 01> ], [ 6, <Buffer 0f a1> ] ]
* ```
*
* @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
*
* @example
* ```js
* import { multiaddr } from '@multiformats/multiaddr'
*
* const mh1 = multiaddr('/ip4/8.8.8.8/tcp/1080')
* // Multiaddr(/ip4/8.8.8.8/tcp/1080)
*
* const mh2 = multiaddr('/ip4/127.0.0.1/tcp/4001')
* // Multiaddr(/ip4/127.0.0.1/tcp/4001)
*
* const mh3 = mh1.encapsulate(mh2)
* // Multiaddr(/ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001)
*
* mh3.toString()
* // '/ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001'
* ```
*
* @param {MultiaddrInput} addr - Multiaddr to add into this Multiaddr
*/
encapsulate(addr: MultiaddrInput): Multiaddr;
/**
* Decapsulates a Multiaddr from another Multiaddr
*
* @example
* ```js
* import { multiaddr } from '@multiformats/multiaddr'
*
* const mh1 = multiaddr('/ip4/8.8.8.8/tcp/1080')
* // Multiaddr(/ip4/8.8.8.8/tcp/1080)
*
* const mh2 = multiaddr('/ip4/127.0.0.1/tcp/4001')
* // Multiaddr(/ip4/127.0.0.1/tcp/4001)
*
* const mh3 = mh1.encapsulate(mh2)
* // Multiaddr(/ip4/8.8.8.8/tcp/1080/ip4/127.0.0.1/tcp/4001)
*
* mh3.decapsulate(mh2).toString()
* // '/ip4/8.8.8.8/tcp/1080'
* ```
*
* @param {Multiaddr | string} addr - Multiaddr to remove from this Multiaddr
*/
decapsulate(addr: Multiaddr | string): Multiaddr;
/**
* A more reliable version of `decapsulate` if you are targeting a specific
* code, such as 421 (the `p2p` protocol code). The last index of the code
* will be removed from the `Multiaddr`, and a new instance will be returned.
* If the code is not present, the original `Multiaddr` is returned.
*
* @example
* ```js
* import { multiaddr } from '@multiformats/multiaddr'
*
* const addr = multiaddr('/ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC')
* // Multiaddr(/ip4/0.0.0.0/tcp/8080/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC)
*
* addr.decapsulateCode(421).toString()
* // '/ip4/0.0.0.0/tcp/8080'
*
* multiaddr('/ip4/127.0.0.1/tcp/8080').decapsulateCode(421).toString()
* // '/ip4/127.0.0.1/tcp/8080'
* ```
*/
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
*
* @example
* ```js
* import { multiaddr } from '@multiformats/multiaddr'
*
* const mh1 = multiaddr('/ip4/8.8.8.8/tcp/1080')
* // Multiaddr(/ip4/8.8.8.8/tcp/1080)
*
* const mh2 = multiaddr('/ip4/127.0.0.1/tcp/4001')
* // Multiaddr(/ip4/127.0.0.1/tcp/4001)
*
* mh1.equals(mh1)
* // true
*
* mh1.equals(mh2)
* // false
* ```
*/
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<Multiaddr[]>;
/**
* 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 declare function fromNodeAddress(addr: NodeAddress, transport: string): Multiaddr;
/**
* 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 declare function fromTuples(tuples: Tuple[]): Multiaddr;
/**
* 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 declare function fromStringTuples(tuples: StringTuple[]): Multiaddr;
/**
* 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 declare function isName(addr: Multiaddr): boolean;
/**
* Check if object is a {@link Multiaddr} instance
*
* @example
*
* ```js
* import { isMultiaddr, multiaddr } from '@multiformats/multiaddr'
*
* isMultiaddr(5)
* // false
* isMultiaddr(multiaddr('/ip4/127.0.0.1'))
* // true
* ```
*/
export declare function isMultiaddr(value: any): value is Multiaddr;
/**
* A function that takes a {@link MultiaddrInput} and returns a {@link Multiaddr}
*
* @example
* ```js
* import { multiaddr } from '@libp2p/multiaddr'
*
* multiaddr('/ip4/127.0.0.1/tcp/4001')
* // Multiaddr(/ip4/127.0.0.1/tcp/4001)
* ```
*
* @param {MultiaddrInput} [addr] - If String or Uint8Array, needs to adhere to the address format of a [multiaddr](https://github.com/multiformats/multiaddr#string-format)
*/
export declare function multiaddr(addr?: MultiaddrInput): Multiaddr;
/**
* 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 declare function protocols(proto: number | string): Protocol;
/**
* Export all table.csv codes. These are all named exports so can be tree-shaken
* out by bundlers.
*/
export * from './constants.ts';
export { registry, V };
export type { ProtocolCodec };
//# sourceMappingURL=index.d.ts.map