Files
modules/trust-security/hyper-p2p-blind-pair-handoff
Raven ScottandCursor faf152a8ac Add exportState and moduleSnapshot helpers across all module categories.
Fifth pass: complete measurement modules (sla-budget, histogram-gossip) with moduleSnapshot/toJSON; stats-exporter exportSnapshot; exportState() alias on modules with standard snapshot serialization.

Co-authored-by: Cursor <[email protected]>
2026-05-21 04:29:50 -04:00
..
2026-05-20 23:36:32 -04:00
2026-05-20 22:56:32 -04:00
2026-05-20 22:56:32 -04:00
2026-05-21 00:07:44 -04:00
2026-05-20 21:57:50 -04:00
2026-05-20 21:57:50 -04:00
2026-05-20 23:36:32 -04:00

hyper-p2p-blind-pair-handoff

Three-phase blind session handoff state machine (offer → accept → complete) synced over gossip.

Category: trust-security · Protocol: blind-pair-handoff/v1 · Exports: HyperP2PBlindPairHandoff, PROTOCOL

When to use

Coordinate moving a session to targetPeer without exposing pair details in this module.

When not to use

Instant local pairing only (secret-stream-pair).

Quick start

const { HyperP2PBlindPairHandoff } = require('hyper-p2p-blind-pair-handoff')
const h = new HyperP2PBlindPairHandoff({ topic: 'handoff' })
await h.ready()
h.offerHandoff('sess-1', 'target-peer-hex')
h.acceptHandoff('sess-1')
h.completeHandoff('sess-1')
await h.close()

Docs

Test

npm test

API

Member Description
new HyperP2PBlindPairHandoff(opts?) topic, keyPair.
offerHandoff(sessionId, targetPeer) State offered; gossips handoff-offer.
acceptHandoff(sessionId) Requires offered; state accepted.
completeHandoff(sessionId) Requires accepted; state completed.
getHandoff(sessionId) Full record or null.
getStats() { offered, accepted, completed, gossipIn, gossipOut, handoffs, protocol }.
ready() / close() Swarm lifecycle.

Events: offered, accepted, completed, closed. Throws if wrong state or missing handoff.

Architecture

_handoffs Map(sessionId -> { sessionId, targetPeer, state, offeredAt, acceptedAt, completedAt })
Remote: offer creates if missing; accept/complete advance only from valid prior state

Gossip does not emit events on remote—only updates map (listen via polling getHandoff or extend locally).

Wire table

type Fields Direction
handoff-offer sessionId, targetPeer, offeredAt Any → all
handoff-accept sessionId, acceptedAt Any → all
handoff-complete sessionId, completedAt Any → all

Errors

  • acceptHandoff / completeHandoff: missing id → handoff not found; wrong state → handoff not offered / not accepted.
  • Empty sessionId / targetPeer on offer.

Composition

  • sessionId aligns with hyper-p2p-noise-session-wrap ids.
  • targetPeer is hex or app-defined peer string.
  • Use after hyper-p2p-blind-relay-bridge selects a relay path.

Example

const { HyperP2PBlindPairHandoff } = require('hyper-p2p-blind-pair-handoff')

const h = new HyperP2PBlindPairHandoff({ topic: process.argv[2] })
await h.ready()

h.offerHandoff('sess-1', 'target-peer-hex')
h.acceptHandoff('sess-1')
h.completeHandoff('sess-1')
console.log(h.getHandoff('sess-1'))
await h.close()