UNPKG

@libp2p/interface

Version:
870 lines 26.7 kB
/** * @packageDocumentation * * Exports a `Libp2p` type for modules to use as a type argument. * * @example * * ```typescript * import type { Libp2p } from '@libp2p/interface' * * function doSomethingWithLibp2p (node: Libp2p) { * // ... * } * ``` */ import type { Connection, NewStreamOptions } from './connection.js'; import type { ContentRouting } from './content-routing.js'; import type { Ed25519PublicKey, PublicKey, RSAPublicKey, Secp256k1PublicKey } from './keys.js'; import type { Metrics } from './metrics.js'; import type { Ed25519PeerId, PeerId, RSAPeerId, Secp256k1PeerId, URLPeerId } from './peer-id.js'; import type { PeerInfo } from './peer-info.js'; import type { PeerRouting } from './peer-routing.js'; import type { Address, Peer, PeerStore } from './peer-store.js'; import type { Startable } from './startable.js'; import type { StreamHandler, StreamHandlerOptions, StreamMiddleware } from './stream-handler.js'; import type { Stream } from './stream.js'; import type { Topology } from './topology.js'; import type { Listener, OutboundConnectionUpgradeEvents } from './transport.js'; import type { DNS } from '@multiformats/dns'; import type { Multiaddr } from '@multiformats/multiaddr'; import type { TypedEventTarget } from 'main-event'; import type { ProgressOptions, ProgressEvent } from 'progress-events'; /** * Used by the connection manager to sort addresses into order before dialling */ export interface AddressSorter { (a: Address, b: Address): -1 | 0 | 1; } /** * Event detail emitted when peer data changes */ export interface PeerUpdate { peer: Peer; previous?: Peer; } /** * Peer data signed by the remote Peer's public key */ export interface SignedPeerRecord { addresses: Multiaddr[]; seq: bigint; } /** * A certificate that can be used to secure connections */ export interface TLSCertificate { /** * The private key that corresponds to the certificate in PEM format */ key: string; /** * The certificate chain in PEM format */ cert: string; } /** * Data returned from a successful identify response */ export interface IdentifyResult { /** * The remote Peer's PeerId */ peerId: PeerId; /** * The unsigned addresses they are listening on. Note - any multiaddrs present * in the signed peer record should be preferred to the value here. */ listenAddrs: Multiaddr[]; /** * The protocols the remote peer supports */ protocols: string[]; /** * The remote protocol version */ protocolVersion?: string; /** * The remote agent version */ agentVersion?: string; /** * The public key part of the remote PeerId - this is only useful for older * RSA-based PeerIds, the more modern Ed25519 and secp256k1 types have the * public key embedded in them */ publicKey?: Uint8Array; /** * If set this is the address that the remote peer saw the identify request * originate from */ observedAddr?: Multiaddr; /** * If sent by the remote peer this is the deserialized signed peer record */ signedPeerRecord?: SignedPeerRecord; /** * The connection that the identify protocol ran over */ connection: Connection; } /** * Logger component for libp2p */ export interface Logger { /** * Log a message */ (formatter: any, ...args: any[]): void; /** * Log an error message */ error(formatter: any, ...args: any[]): void; /** * Log a trace message */ trace(formatter: any, ...args: any[]): void; /** * `true` if this logger is enabled */ enabled: boolean; /** * Create a logger scoped below this one * * @example * * ```ts * import { defaultLogger } from '@libp2p/logger' * * const log = defaultLogger().forComponent('foo') * * log('hello') * // foo hello * * const subLog = log.newScope('bar') * * subLog('hello') * // foo:bar hello * ``` */ newScope(name: string): Logger; } /** * Peer logger component for libp2p. This can be used to create loggers that are * scoped to individual system components or services. * * To see logs, run your app with `DEBUG` set as an env var or for browsers, in * `localStorage`: * * ```console * $ DEBUG=libp2p* node index.js * libp2p:my-service hello +0ms * ``` */ export interface ComponentLogger { /** * Returns a logger for the specified component. * * @example * * ```TypeScript * import { ComponentLogger, Logger } from '@libp2p/interface' * * interface MyServiceComponents { * logger: ComponentLogger * } * * class MyService { * private readonly log: Logger * * constructor (components) { * this.log = components.logger.forComponent('libp2p:my-service') * * this.log('hello') * // logs: * // libp2p:my-service hello +0ms * } * } * ``` */ forComponent(name: string): Logger; } export interface MultiaddrResolveOptions extends AbortOptions, LoggerOptions { /** * An optional DNS resolver */ dns?: DNS; } /** * `MultiaddrResolver`s perform resolution of multiaddr components that require * translation by external systems (for example DNSADDR to TXT records). */ export interface MultiaddrResolver { /** * Returns true if this resolver can resolve components of this multiaddr */ canResolve(address: Multiaddr): boolean; /** * Returns one or more multiaddrs with components resolved to other values */ resolve(address: Multiaddr, options: MultiaddrResolveOptions): Promise<Multiaddr[]>; } /** * Once you have a libp2p instance, you can listen to several events it emits, * so that you can be notified of relevant network events. * * Event names are `noun:verb` so the first part is the name of the object * being acted on and the second is the action. */ export interface Libp2pEvents<T extends ServiceMap = ServiceMap> { /** * This event is dispatched when a new network peer is discovered. * * @example * * ```TypeScript * libp2p.addEventListener('peer:discovery', (event) => { * const peerInfo = event.detail * // ... * }) * ``` */ 'peer:discovery': CustomEvent<PeerInfo>; /** * This event will be triggered any time a new peer connects. * * @example * * ```TypeScript * libp2p.addEventListener('peer:connect', (event) => { * const peerId = event.detail * // ... * }) * ``` */ 'peer:connect': CustomEvent<PeerId>; /** * This event will be triggered any time we are disconnected from another * peer, regardless of the circumstances of that disconnection. If we happen * to have multiple connections to a peer, this event will **only** be * triggered when the last connection is closed. * * @example * * ```TypeScript * libp2p.addEventListener('peer:disconnect', (event) => { * const peerId = event.detail * // ... * }) * ``` */ 'peer:disconnect': CustomEvent<PeerId>; /** * When a peer tagged with `keep-alive` disconnects, we will make multiple * attempts to reconnect to it with a backoff factor (see the connection * manager settings for details). If these all fail, the `keep-alive` tag will * be removed and this event will be emitted. * * @example * * ```TypeScript * libp2p.addEventListener('peer:reconnect-failure', (event) => { * const peerId = event.detail * // ... * }) * ``` */ 'peer:reconnect-failure': CustomEvent<PeerId>; /** * This event is dispatched after a remote peer has successfully responded to * the identify protocol. Note that for this to be emitted, both peers must * have an identify service configured. * * @example * * ```TypeScript * libp2p.addEventListener('peer:identify', (event) => { * const identifyResult = event.detail * // ... * }) * ``` */ 'peer:identify': CustomEvent<IdentifyResult>; /** * This event is dispatched when the peer store data for a peer has been * updated - e.g. their multiaddrs, protocols etc have changed. * * If they were previously known to this node, the old peer data will be * set in the `previous` field. * * This may be in response to the identify protocol running, a manual * update or some other event. */ 'peer:update': CustomEvent<PeerUpdate>; /** * This event is dispatched when the current node's peer record changes - * for example a transport started listening on a new address or a new * protocol handler was registered. * * @example * * ```TypeScript * libp2p.addEventListener('self:peer:update', (event) => { * const { peer } = event.detail * // ... * }) * ``` */ 'self:peer:update': CustomEvent<PeerUpdate>; /** * This event is dispatched when a transport begins listening on a new address */ 'transport:listening': CustomEvent<Listener>; /** * This event is dispatched when a transport stops listening on an address */ 'transport:close': CustomEvent<Listener>; /** * This event is dispatched when the connection manager has more than the * configured allowable max connections and has closed some connections to * bring the node back under the limit. */ 'connection:prune': CustomEvent<Connection[]>; /** * This event notifies listeners when new incoming or outgoing connections * are opened. */ 'connection:open': CustomEvent<Connection>; /** * This event notifies listeners when incoming or outgoing connections are * closed. */ 'connection:close': CustomEvent<Connection>; /** * This event notifies listeners that a TLS certificate is available for use */ 'certificate:provision': CustomEvent<TLSCertificate>; /** * This event notifies listeners that a new TLS certificate is available for * use. Any previous certificate may no longer be valid. */ 'certificate:renew': CustomEvent<TLSCertificate>; /** * This event notifies listeners that the node has started * * ```TypeScript * libp2p.addEventListener('start', (event) => { * console.info(libp2p.isStarted()) // true * }) * ``` */ start: CustomEvent<Libp2p<T>>; /** * This event notifies listeners that the node has stopped * * ```TypeScript * libp2p.addEventListener('stop', (event) => { * console.info(libp2p.isStarted()) // false * }) * ``` */ stop: CustomEvent<Libp2p<T>>; } /** * A map of user defined services available on the libp2p node via the * `services` key * * @example * * ```TypeScript * const node = await createLibp2p({ * // ...other options * services: { * myService: myService({ * // ...service options * }) * } * }) * * // invoke methods on the service * node.services.myService.anOperation() * ``` */ export type ServiceMap = Record<string, unknown>; export type PendingDialStatus = 'queued' | 'active' | 'error' | 'success'; /** * An item in the dial queue */ export interface PendingDial { /** * A unique identifier for this dial */ id: string; /** * The current status of the dial */ status: PendingDialStatus; /** * If known, this is the peer id that libp2p expects to be dialling */ peerId?: PeerId; /** * The list of multiaddrs that will be dialled. The returned connection will * use the first address that succeeds, all other dials part of this pending * dial will be cancelled. */ multiaddrs: Multiaddr[]; } export type Libp2pStatus = 'starting' | 'started' | 'stopping' | 'stopped'; export interface IsDialableOptions extends AbortOptions { /** * If the dial attempt would open a protocol, and the multiaddr being dialed * is a circuit relay address, passing true here would cause the test to fail * because that protocol would not be allowed to run over a data/time limited * connection. */ runOnLimitedConnection?: boolean; } export type TransportManagerDialProgressEvents = ProgressEvent<'transport-manager:selected-transport', string>; export type OpenConnectionProgressEvents = TransportManagerDialProgressEvents | ProgressEvent<'dial-queue:already-connected'> | ProgressEvent<'dial-queue:already-in-dial-queue'> | ProgressEvent<'dial-queue:add-to-dial-queue'> | ProgressEvent<'dial-queue:start-dial'> | ProgressEvent<'dial-queue:calculated-addresses', Address[]> | OutboundConnectionUpgradeEvents; export interface DialOptions extends AbortOptions, ProgressOptions { /** * If true, open a new connection to the remote even if one already exists */ force?: boolean; } export interface DialProtocolOptions extends NewStreamOptions { } /** * Libp2p nodes implement this interface. */ export interface Libp2p<T extends ServiceMap = ServiceMap> extends Startable, TypedEventTarget<Libp2pEvents<T>> { /** * The PeerId is a unique identifier for a node on the network. * * It is the hash of an RSA public key or, for Ed25519 or secp256k1 keys, * the key itself. * * @example * * ```TypeScript * console.info(libp2p.peerId) * // PeerId(12D3Foo...) * ```` */ peerId: PeerId; /** * The peer store holds information we know about other peers on the network. * - multiaddrs, supported protocols, etc. * * @example * * ```TypeScript * const peer = await libp2p.peerStore.get(peerId) * console.info(peer) * // { id: PeerId(12D3Foo...), addresses: [] ... } * ``` */ peerStore: PeerStore; /** * The peer routing subsystem allows the user to find peers on the network * or to find peers close to binary keys. * * @example * * ```TypeScript * const peerInfo = await libp2p.peerRouting.findPeer(peerId) * console.info(peerInfo) * // { id: PeerId(12D3Foo...), multiaddrs: [] ... } * ``` * * @example * * ```TypeScript * for await (const peerInfo of libp2p.peerRouting.getClosestPeers(key)) { * console.info(peerInfo) * // { id: PeerId(12D3Foo...), multiaddrs: [] ... } * } * ``` */ peerRouting: PeerRouting; /** * The content routing subsystem allows the user to find providers for content, * let the network know they are providers for content, and get/put values to * the DHT. * * @example * * ```TypeScript * for await (const peerInfo of libp2p.contentRouting.findProviders(cid)) { * console.info(peerInfo) * // { id: PeerId(12D3Foo...), multiaddrs: [] ... } * } * ``` */ contentRouting: ContentRouting; /** * The metrics subsystem allows recording values to assess the health/performance * of the running node. * * @example * * ```TypeScript * const metric = libp2p.metrics.registerMetric({ * 'my-metric' * }) * * // later * metric.update(5) * ``` */ metrics?: Metrics; /** * The logger used by this libp2p node */ logger: ComponentLogger; /** * The current status of the libp2p node */ status: Libp2pStatus; /** * Get a deduplicated list of peer advertising multiaddrs by concatenating * the listen addresses used by transports with any configured * announce addresses as well as observed addresses reported by peers. * * If Announce addrs are specified, configured listen addresses will be * ignored though observed addresses will still be included. * * @example * * ```TypeScript * const listenMa = libp2p.getMultiaddrs() * // [ <Multiaddr 047f00000106f9ba - /ip4/127.0.0.1/tcp/63930> ] * ``` */ getMultiaddrs(): Multiaddr[]; /** * Returns a list of supported protocols * * @example * * ```TypeScript * const protocols = libp2p.getProtocols() * // [ '/ipfs/ping/1.0.0', '/ipfs/id/1.0.0' ] * ``` */ getProtocols(): string[]; /** * Return a list of all connections this node has open, optionally filtering * by a PeerId * * @example * * ```TypeScript * for (const connection of libp2p.getConnections()) { * console.log(peerId, connection.remoteAddr.toString()) * // Logs the PeerId string and the observed remote multiaddr of each Connection * } * ``` */ getConnections(peerId?: PeerId): Connection[]; /** * Return the list of dials currently in progress or queued to start * * @example * * ```TypeScript * for (const pendingDial of libp2p.getDialQueue()) { * console.log(pendingDial) * } * ``` */ getDialQueue(): PendingDial[]; /** * Return a list of all peers we currently have a connection open to */ getPeers(): PeerId[]; /** * Dials to the provided peer. If successful, the known metadata of the * peer will be added to the nodes `peerStore`. * * If a PeerId is passed as the first argument, the peer will need to have known multiaddrs for it in the PeerStore. * * @example * * ```TypeScript * const conn = await libp2p.dial(remotePeerId) * * // create a new stream within the connection * const stream = await conn.newStream(['/echo/1.1.0', '/echo/1.0.0']) * * // protocol negotiated: 'echo/1.0.0' means that the other party only supports the older version * * // ... * await conn.close() * ``` */ dial(peer: PeerId | Multiaddr | Multiaddr[], options?: DialOptions): Promise<Connection>; /** * Dials to the provided peer and tries to handshake with the given protocols in order. * If successful, the known metadata of the peer will be added to the nodes `peerStore`, * and the `MuxedStream` will be returned together with the successful negotiated protocol. * * @example * * ```TypeScript * import { pipe } from 'it-pipe' * * const { stream, protocol } = await libp2p.dialProtocol(remotePeerId, protocols) * * // Use this new stream like any other duplex stream * pipe([1, 2, 3], stream, consume) * ``` */ dialProtocol(peer: PeerId | Multiaddr | Multiaddr[], protocols: string | string[], options?: DialProtocolOptions): Promise<Stream>; /** * Attempts to gracefully close an open connection to the given peer. If the * connection is not closed in the grace period, it will be forcefully closed. * * An AbortSignal can optionally be passed to control when the connection is * forcefully closed. * * @example * * ```TypeScript * await libp2p.hangUp(remotePeerId) * ``` */ hangUp(peer: PeerId | Multiaddr, options?: AbortOptions): Promise<void>; /** * Sets up [multistream-select routing](https://github.com/multiformats/multistream-select) of protocols to their application handlers. Whenever a stream is opened on one of the provided protocols, the handler will be called. `handle` must be called in order to register a handler and support for a given protocol. This also informs other peers of the protocols you support. * * `libp2p.handle(protocols, handler, options)` * * In the event of a new handler for the same protocol being added and error * will be thrown. Pass `force: true` to override this. * * @example * * ```TypeScript * const handler = ({ connection, stream, protocol }) => { * // use stream or connection according to the needs * } * * libp2p.handle('/echo/1.0.0', handler, { * maxInboundStreams: 5, * maxOutboundStreams: 5 * }) * ``` */ handle(protocol: string | string[], handler: StreamHandler, options?: StreamHandlerOptions): Promise<void>; /** * Removes the handler for each protocol. The protocol * will no longer be supported on streams. * * @example * * ```TypeScript * libp2p.unhandle(['/echo/1.0.0']) * ``` */ unhandle(protocols: string[] | string, options?: AbortOptions): Promise<void>; /** * Register a topology to be informed when peers are encountered that * support the specified protocol * * @example * * ```TypeScript * const id = await libp2p.register('/echo/1.0.0', { * onConnect: (peer, connection) => { * // handle connect * }, * onDisconnect: (peer, connection) => { * // handle disconnect * } * }) * ``` */ register(protocol: string, topology: Topology, options?: AbortOptions): Promise<string>; /** * Unregister topology to no longer be informed when peers connect or * disconnect. * * @example * * ```TypeScript * const id = await libp2p.register(...) * * libp2p.unregister(id) * ``` */ unregister(id: string): void; /** * Registers one or more middleware implementations that will be invoked for * incoming and outgoing protocol streams that match the passed protocol. * * @example * * ```TypeScript * libp2p.use('/my/protocol/1.0.0', (stream, connection, next) => { * // do something with stream and/or connection * next(stream, connection) * }) * ``` */ use(protocol: string, middleware: StreamMiddleware | StreamMiddleware[]): void; /** * Deregisters all middleware for the passed protocol. * * @example * * ```TypeScript * libp2p.unuse('/my/protocol/1.0.0') * // any previously registered middleware will no longer be invoked * ``` */ unuse(protocol: string): void; /** * Returns the public key for the passed PeerId. If the PeerId is of the 'RSA' * type this may mean searching the routing if the peer's key is not present * in the peer store. */ getPublicKey(peer: Ed25519PeerId, options?: AbortOptions): Promise<Ed25519PublicKey>; getPublicKey(peer: Secp256k1PeerId, options?: AbortOptions): Promise<Secp256k1PublicKey>; getPublicKey(peer: RSAPeerId, options?: AbortOptions): Promise<RSAPublicKey>; getPublicKey(peer: URLPeerId, options?: AbortOptions): Promise<never>; getPublicKey(peer: PeerId, options?: AbortOptions): Promise<PublicKey>; /** * Given the current node configuration, returns a promise of `true` or * `false` if the node would attempt to dial the passed multiaddr. * * This means a relevant transport is configured, and the connection gater * would not block the dial attempt. * * This may involve resolving DNS addresses so you should pass an AbortSignal. */ isDialable(multiaddr: Multiaddr | Multiaddr[], options?: IsDialableOptions): Promise<boolean>; /** * A set of user defined services */ services: T; } /** * Metadata about the current node */ export interface NodeInfo { /** * The implementation name */ name: string; /** * The implementation version */ version: string; /** * A string that contains information about the implementation and runtime */ userAgent: string; } /** * An object that contains an AbortSignal as * the optional `signal` property. * * @example * * ```TypeScript * const controller = new AbortController() * * aLongRunningOperation({ * signal: controller.signal * }) * * // later * * controller.abort() */ export interface AbortOptions { signal?: AbortSignal; } /** * An object that contains a Logger as the `log` property. */ export interface LoggerOptions { log: Logger; } /** * An object that includes a trace object that is passed onwards. * * This is used by metrics method tracing to link function calls together. */ export interface TraceOptions { trace?: any; } /** * A signal that needs to be cleared when no longer in use */ export interface ClearableSignal extends AbortSignal { clear(): void; } /** * When a routing operation involves reading values, these options allow * controlling where the values are read from. By default libp2p will check * local caches but may not use the network if a valid local value is found, * these options allow tuning that behavior. */ export interface RoutingOptions extends AbortOptions, ProgressOptions, TraceOptions { /** * Pass `false` to not use the network * * @default true */ useNetwork?: boolean; /** * Pass `false` to not use cached values * * @default true */ useCache?: boolean; } /** * This symbol is used by libp2p services to define the capabilities they can * provide to other libp2p services. * * The service should define a property with this symbol as the key and the * value should be a string array of provided capabilities. */ export declare const serviceCapabilities: unique symbol; /** * This symbol is used by libp2p services to define the capabilities they * require from other libp2p services. * * The service should define a property with this symbol as the key and the * value should be a string array of required capabilities. */ export declare const serviceDependencies: unique symbol; export * from './connection.js'; export * from './connection-encrypter.js'; export * from './connection-gater.js'; export * from './connection-protector.js'; export * from './content-routing.js'; export * from './errors.js'; export * from './events.js'; export * from './keys.js'; export * from './message-stream.js'; export * from './metrics.js'; export * from './multiaddr-connection.js'; export * from './peer-discovery.js'; export * from './peer-id.js'; export * from './peer-info.js'; export * from './peer-routing.js'; export * from './peer-store.js'; export * from './record.js'; export * from './startable.js'; export * from './stream-handler.js'; export * from './stream-muxer.js'; export * from './stream.js'; export * from './topology.js'; export * from './transport.js'; export * from 'main-event'; //# sourceMappingURL=index.d.ts.map