LogoPear Docs
ReferenceHelpers

Secretstream

Noise-encrypted duplex stream used for Holepunch peer transports.

stable

Secretstream wraps a transport stream in a Noise handshake plus libsodium secretstream encryption. It is the encrypted stream layer used underneath Hyperswarm and related peer transports. For the upstream package, source, and release notes, see the @hyperswarm/secret-stream repository.

Install

npm i @hyperswarm/secret-stream

Quickstart

import SecretStream from '@hyperswarm/secret-stream'

const a = new SecretStream(true)
const b = new SecretStream(false)

a.rawStream.pipe(b.rawStream).pipe(a.rawStream)

a.write(Buffer.from('hello encrypted world'))

b.on('data', (data) => {
  console.log(data.toString())
})

API Reference

Constructor and lifecycle

const stream = new SecretStream(isInitiator, [rawStream], [options])

API definition on GitHub

  • Signature: const stream = new SecretStream(isInitiator, [rawStream], [options]) (GitHub)
  • Parameters: isInitiator is true for the dialing side and false for the accepting side. rawStream is an optional underlying transport stream. options.pattern overrides the Noise pattern, remotePublicKey pins the remote identity when the pattern requires it, keyPair provides a local key pair or a promise resolving to one, handshake injects an already-computed handshake, enableSend disables unordered UDP-style sends when set to false, keepAlive configures heartbeat writes, and autoStart defaults to true. (GitHub)
  • Returns: A duplex encrypted stream. You can use it like a normal stream for ordered reads and writes once the handshake completes. (GitHub)
  • Example:
const socket = getTransportSocketSomehow()
const stream = new SecretStream(true, socket, {
  keepAlive: 10_000
})

stream.start([rawStream], [options])

API definition on GitHub

  • Signature: stream.start([rawStream], [options]) (GitHub)
  • Parameters: rawStream is the transport to wrap when autoStart: false was used. options accepts the same handshake-related fields as the constructor, including keyPair, handshake, data, and ended. (GitHub)
  • Returns: Nothing. It wires the transport, starts the handshake, and begins pumping encrypted data. (GitHub)
  • Example:
const stream = new SecretStream(true, null, { autoStart: false })
stream.start(socket, { remotePublicKey })

await stream.flush()

API definition on GitHub

  • Signature: await stream.flush() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: A promise resolving to true when pending encrypted writes and the underlying raw stream have flushed successfully, or false if the stream closed before that happened. (GitHub)
  • Example:
stream.write(Buffer.from('hello'))
await stream.flush()

Stream configuration

stream.setTimeout(ms)

API definition on GitHub

  • Signature: stream.setTimeout(ms) (GitHub)
  • Parameters: ms is the idle timeout in milliseconds. Use 0 to disable the timeout. (GitHub)
  • Returns: Nothing. When the timer expires without inbound data, the stream destroys itself with a timeout error. (GitHub)
  • Example:
stream.setTimeout(30_000)

stream.setKeepAlive(ms)

API definition on GitHub

  • Signature: stream.setKeepAlive(ms) (GitHub)
  • Parameters: ms is the heartbeat interval in milliseconds. Use 0 to disable keepalives. (GitHub)
  • Returns: Nothing. The stream will periodically send empty encrypted frames while idle. (GitHub)
  • Example:
stream.setKeepAlive(10_000)

stream.sendKeepAlive()

API definition on GitHub

  • Signature: stream.sendKeepAlive() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: Nothing. Immediately writes one empty encrypted keepalive frame. (GitHub)
  • Example:
stream.sendKeepAlive()

Ordered stream I/O

stream.write(buffer)

API definition on GitHub

  • Signature: stream.write(buffer) (GitHub)
  • Parameters: buffer is the ordered payload to encrypt and send through the duplex stream. (GitHub)
  • Returns: The usual writable-stream backpressure boolean. (GitHub)
  • Example:
stream.write(Buffer.from('ordered payload'))

stream.end([buffer])

API definition on GitHub

  • Signature: stream.end([buffer]) (GitHub)
  • Parameters: buffer is an optional final ordered payload. (GitHub)
  • Returns: The stream instance, following standard writable-stream behavior. (GitHub)
  • Example:
stream.end(Buffer.from('goodbye'))

stream.on('data', listener)

API definition on GitHub

  • Signature: stream.on('data', listener) (GitHub)
  • Parameters: listener receives ordered decrypted payloads as Buffer instances. (GitHub)
  • Returns: The stream itself. (GitHub)
  • Example:
stream.on('data', (data) => {
  console.log(data.toString())
})

Unordered messages

await stream.send(buffer)

API definition on GitHub

  • Signature: await stream.send(buffer) (GitHub)
  • Parameters: buffer is the unordered datagram payload to encrypt. (GitHub)
  • Returns: A promise when the underlying raw stream supports send(...) semantics, or undefined when unordered sending is unavailable. Messages sent before handshake completion are silently dropped. (GitHub)
  • Example:
await stream.opened
await stream.send(Buffer.from('unordered ping'))

stream.trySend(buffer)

API definition on GitHub

  • Signature: stream.trySend(buffer) (GitHub)
  • Parameters: buffer is the unordered datagram payload to encrypt. (GitHub)
  • Returns: Nothing. It attempts a best-effort unordered send when the underlying transport supports trySend(...). (GitHub)
  • Example:
stream.trySend(Buffer.from('fire-and-forget'))

stream.on('message', listener)

API definition on GitHub

  • Signature: stream.on('message', listener) (GitHub)
  • Parameters: listener receives decrypted unordered messages as Buffer instances. (GitHub)
  • Returns: The stream itself. (GitHub)
  • Example:
stream.on('message', (message) => {
  console.log(message.toString())
})

Utility methods

const buffer = stream.alloc(length)

API definition on GitHub

  • Signature: const buffer = stream.alloc(length) (GitHub)
  • Parameters: length is the ordered payload size you want to write next. (GitHub)
  • Returns: A writable payload slice backed by a preallocated encrypted output buffer. Write into it, then pass it to stream.write(...). (GitHub)
  • Example:
const payload = stream.alloc(5)
payload.set(Buffer.from('hello'))
stream.write(payload)

const json = stream.toJSON()

API definition on GitHub

  • Signature: const json = stream.toJSON() (GitHub)
  • Parameters: None. (GitHub)
  • Returns: A diagnostic object containing connection state, keys, and any serializable raw-stream metadata. (GitHub)
  • Example:
console.log(stream.toJSON())

Static helpers

const keyPair = SecretStream.keyPair([seed])

API definition on GitHub

  • Signature: const keyPair = SecretStream.keyPair([seed]) (GitHub)
  • Parameters: seed is an optional 32-byte seed for deterministic key generation. (GitHub)
  • Returns: An ed25519 { publicKey, secretKey } pair suitable for the Noise handshake. (GitHub)
  • Example:
const keyPair = SecretStream.keyPair()

const id = SecretStream.id(handshakeHash, isInitiator, [out])

API definition on GitHub

  • Signature: const id = SecretStream.id(handshakeHash, isInitiator, [out]) (GitHub)
  • Parameters: handshakeHash is the completed handshake hash, isInitiator chooses the initiator/responder namespace, and out optionally supplies an output buffer. (GitHub)
  • Returns: A 32-byte stream identity derived from the handshake. (GitHub)
  • Example:
await stream.opened
const id = SecretStream.id(stream.handshakeHash, stream.isInitiator)

Public properties

stream.isInitiator

API definition on GitHub

  • Returns: true on the dialing side and false on the accepting side. (GitHub)

stream.rawStream

API definition on GitHub

  • Returns: The wrapped transport stream, or a bridge stream when no raw stream was supplied up front. (GitHub)

stream.publicKey

API definition on GitHub

  • Returns: The local public key used in the handshake. (GitHub)

stream.remotePublicKey

API definition on GitHub

  • Returns: The remote peer's public key after the handshake succeeds. (GitHub)

stream.handshakeHash

API definition on GitHub

  • Returns: The Noise handshake hash after the encrypted session is established. (GitHub)

stream.connected

API definition on GitHub

  • Returns: true once the handshake is complete and the stream has emitted connect. (GitHub)

stream.keepAlive

API definition on GitHub

  • Returns: The configured keepalive interval in milliseconds. (GitHub)

stream.timeout

API definition on GitHub

  • Returns: The configured idle-timeout interval in milliseconds. (GitHub)

stream.enableSend

API definition on GitHub

  • Returns: true when unordered send(...) and trySend(...) support is enabled. (GitHub)

stream.opened

API definition on GitHub

  • Returns: A promise that resolves to true when the handshake succeeds, or false if the stream closes before opening. (GitHub)

stream.rawBytesWritten

API definition on GitHub

  • Returns: The total encrypted byte count written to the raw stream. (GitHub)

stream.rawBytesRead

API definition on GitHub

  • Returns: The total encrypted byte count read from the raw stream before decryption. (GitHub)

stream.userData

API definition on GitHub

  • Returns: An arbitrary user-controlled field that higher-level protocols often use to attach transport metadata. (GitHub)

Events

stream.on('connect', listener)

API definition on GitHub

  • Signature: stream.on('connect', listener) (GitHub)
  • Parameters: listener fires once the handshake is complete and ordered writes are fully active. (GitHub)
  • Returns: The stream itself. (GitHub)
  • Example:
stream.on('connect', () => {
  console.log(stream.remotePublicKey)
})

stream.on('handshake', listener)

API definition on GitHub

  • Signature: stream.on('handshake', listener) (GitHub)
  • Parameters: listener fires when the Noise handshake keys and hash have been established. (GitHub)
  • Returns: The stream itself. (GitHub)
  • Example:
stream.on('handshake', () => {
  console.log(stream.handshakeHash)
})

See also

  • Hyperswarm — the peer-discovery and connection layer that typically hands sockets to Secretstream.
  • HyperDHT — lower-level DHT whose direct keyed connections are also wrapped in Secretstream.
  • Protomux — multiplex higher-level protocols across one framed encrypted stream.
  • Upstream @hyperswarm/secret-stream repository — source, releases, and implementation details.

On this page