libp2p-hs-0.1.0.0: Haskell implementation of the libp2p networking stack
Safe HaskellNone
LanguageGHC2021

Network.LibP2P

Description

libp2p-hs: Haskell implementation of the libp2p networking stack.

This is the public API facade for the library. Import this module for the common types and functions needed to build a libp2p node:

import Network.LibP2P

main :: IO ()
main = do
  (pid, kp) <- generateAndPeerId
  sw <- newSwitch pid kp
  tcp <- newTCPTransport
  addTransport sw tcp
  registerIdentifyHandlers sw
  registerPingHandler sw
  addrs <- switchListen sw defaultConnectionGater [fromText "ip4127.0.0.1tcp0"]
  print addrs
  -- ... dial other peers, etc.
  switchClose sw
Synopsis

Identity

data PeerId Source #

A Peer ID is a multihash of the serialized public key.

Instances

Instances details
Show PeerId Source # 
Instance details

Defined in Network.LibP2P.Crypto.PeerId

Eq PeerId Source # 
Instance details

Defined in Network.LibP2P.Crypto.PeerId

Methods

(==) :: PeerId -> PeerId -> Bool #

(/=) :: PeerId -> PeerId -> Bool #

Ord PeerId Source # 
Instance details

Defined in Network.LibP2P.Crypto.PeerId

data KeyPair Source #

A key pair containing both public and private keys.

generateKeyPair :: IO (Either String KeyPair) Source #

Generate a new random Ed25519 key pair. Returns Left on cryptographic failure (should not occur with proper RNG).

fromPublicKey :: PublicKey -> PeerId Source #

Derive a Peer ID from a public key.

peerIdBytes :: PeerId -> ByteString Source #

Get the raw multihash bytes of a Peer ID.

toBase58 :: PeerId -> Text Source #

Encode a Peer ID as base58btc text.

parsePeerId :: Text -> Either String PeerId Source #

Parse a Peer ID from text, accepting both base58btc and CIDv1 (base32lower) formats. CIDv1 format: b prefix + base32lower(0x01 || 0x72 || multihash)

toCIDv1 :: PeerId -> Text Source #

Encode a Peer ID as CIDv1 text (base32lower, no padding). Format: b + base32lower(varint(1) + varint(0x72) + multihash_bytes)

Addressing

newtype Multiaddr Source #

A multiaddr is a list of protocol components.

Constructors

Multiaddr [Protocol] 

Instances

Instances details
Show Multiaddr Source # 
Instance details

Defined in Network.LibP2P.Multiaddr.Multiaddr

Eq Multiaddr Source # 
Instance details

Defined in Network.LibP2P.Multiaddr.Multiaddr

data Protocol Source #

A single protocol component within a multiaddr.

Constructors

IP4 !Word32

IPv4 address (4 bytes big-endian)

IP6 !ByteString

IPv6 address (16 bytes)

TCP !Word16

TCP port

UDP !Word16

UDP port

P2P !ByteString

Peer ID as multihash bytes

QuicV1

QUIC v1 (no address)

WS

WebSocket (no address)

WSS

WebSocket Secure (no address)

DNS !Text

DNS hostname

DNS4 !Text

DNS4 hostname

DNS6 !Text

DNS6 hostname

DNSAddr !Text

DNSAddr hostname

P2PCircuit

Circuit relay marker (no address)

WebTransport

WebTransport (no address)

NoiseProto

Noise protocol marker (no address)

YamuxProto

Yamux protocol marker (no address)

Instances

Instances details
Show Protocol Source # 
Instance details

Defined in Network.LibP2P.Multiaddr.Protocol

Eq Protocol Source # 
Instance details

Defined in Network.LibP2P.Multiaddr.Protocol

splitP2P :: Multiaddr -> Maybe (Multiaddr, PeerId) Source #

Split off the trailing p2ppeerId component from a multiaddr. Returns the transport address and the peer ID, or Nothing if the multiaddr does not end with a p2p component.

toText :: Multiaddr -> Text Source #

Render a multiaddr as text.

fromText :: Text -> Either String Multiaddr Source #

Parse a multiaddr from its text representation (e.g. "ip4127.0.0.1tcp4001").

Switch (central coordinator)

data Switch Source #

The Switch: central coordinator of the libp2p networking stack.

Manages transports, connection pool, protocol handlers, and events. All mutable state is STM-based for safe concurrent access.

newSwitch :: PeerId -> KeyPair -> IO Switch Source #

Create a new Switch with the given local identity. All internal state is initialized empty.

addTransport :: Switch -> Transport -> IO () Source #

Register a transport with the switch. Appends to the list of transports; order matters for selectTransport.

switchListen :: Switch -> ConnectionGater -> [Multiaddr] -> IO [Multiaddr] Source #

Start listening on the given addresses.

For each address, selects a matching transport, binds a listener, and spawns an accept loop that handles inbound connections. Returns the actual bound addresses (port 0 resolved to actual port). Fails if the switch is already closed.

switchListenAddrs :: Switch -> IO [Multiaddr] Source #

Get the current listen addresses from all active listeners.

switchClose :: Switch -> IO () Source #

Shut down the switch. Cancels all accept loop threads, closes all listeners, then sets the closed flag.

dial :: Switch -> PeerId -> [Multiaddr] -> IO (Either DialError Connection) Source #

Dial a peer, reusing existing connections or establishing new ones.

Implements the full dial flow from docs/08-switch.md §Dial Flow: 1. Pool reuse: return existing Open connection if available 2. Backoff check: reject if peer recently failed 3. Deduplication: coalesce concurrent dials to same peer via TMVar 4. Staggered parallel dial with 250ms delay (Happy Eyeballs) 5. First success: upgrade, add to pool, return 6. All fail: record backoff, return error

data DialError Source #

Errors that can occur during a dial operation (docs/08-switch.md §Dialing).

Constructors

DialBackoff

Peer is in backoff period (recently failed)

DialNoAddresses

No addresses provided for dialing

DialNoTransport !Multiaddr

No registered transport can handle this address

DialAllFailed ![String]

All dial attempts failed

DialUpgradeFailed !String

Connection upgrade pipeline failed

DialSwitchClosed

Switch has been shut down

DialResourceLimit !ResourceError

Resource limit exceeded

DialPeerIdMismatch !PeerId !PeerId

Expected vs actual remote PeerId

Instances

Instances details
Show DialError Source # 
Instance details

Defined in Network.LibP2P.Switch.Types

Eq DialError Source # 
Instance details

Defined in Network.LibP2P.Switch.Types

setStreamHandler :: Switch -> ProtocolId -> StreamHandler -> IO () Source #

Register a protocol stream handler. Overwrites any existing handler for the same protocol ID.

removeStreamHandler :: Switch -> ProtocolId -> IO () Source #

Remove a protocol stream handler.

data StreamIO Source #

Abstraction for stream I/O to enable testing with in-memory buffers.

Constructors

StreamIO 

Fields

type StreamHandler = StreamIO -> PeerId -> IO () Source #

A protocol stream handler.

Receives the stream I/O and the remote peer's identity.

type ProtocolId = Text Source #

A protocol identifier (e.g. "noise", "yamux/1.0.0").

data Connection Source #

An upgraded (secure + multiplexed) connection to a remote peer.

Constructors

Connection 

Fields

Transport

data Transport Source #

Transport provides dial/listen capabilities for a specific protocol.

Constructors

Transport 

Fields

newTCPTransport :: IO Transport Source #

Create a new TCP transport.

Connection gating

data ConnectionGater Source #

Connection gater: policy-based admission control (docs/08-switch.md §Connection Gating).

Called at multiple points during connection establishment to allow or deny based on policy (IP blocklist, Peer ID allowlist, etc.).

Constructors

ConnectionGater 

Fields

defaultConnectionGater :: ConnectionGater Source #

Default gater that allows all connections.

Identify protocol

registerIdentifyHandlers :: Switch -> IO () Source #

Register Identify protocol handlers on the Switch.

Registers: ipfsid/1.0.0 — respond to Identify requests ipfsidpush1.0.0 — handle Identify Push from remote

requestIdentify :: Connection -> IO (Either String IdentifyInfo) Source #

Request Identify from a remote peer (initiator side).

Opens a new stream, negotiates ipfsid/1.0.0, reads until EOF, then decodes the protobuf message.

Ping protocol

registerPingHandler :: Switch -> IO () Source #

Register the Ping handler on the Switch.

sendPing :: Connection -> IO (Either PingError PingResult) Source #

Send a Ping to a remote peer (initiator side).

Opens a new stream, negotiates ipfsping/1.0.0, sends 32 random bytes, reads 32 bytes back, verifies match, measures RTT.

data PingResult Source #

Successful ping result.

Constructors

PingResult 

Fields

Instances

Instances details
Show PingResult Source # 
Instance details

Defined in Network.LibP2P.Protocol.Ping.Ping

Eq PingResult Source # 
Instance details

Defined in Network.LibP2P.Protocol.Ping.Ping

data PingError Source #

Ping error types.

Constructors

PingTimeout

No response within timeout

PingMismatch

Response doesn't match sent bytes

PingStreamError !String

Stream I/O error

Instances

Instances details
Show PingError Source # 
Instance details

Defined in Network.LibP2P.Protocol.Ping.Ping

Eq PingError Source # 
Instance details

Defined in Network.LibP2P.Protocol.Ping.Ping

GossipSub

data GossipSubNode Source #

A GossipSub node: Router + Switch integration.

Constructors

GossipSubNode 

Fields

data GossipSubParams Source #

GossipSub router parameters.

Constructors

GossipSubParams 

Fields

defaultGossipSubParams :: GossipSubParams Source #

Default GossipSub parameters per spec.

newGossipSubNode :: Switch -> GossipSubParams -> IO GossipSubNode Source #

Create a new GossipSub node with a Router wired to the Switch.

The Router's gsSendRPC callback opens/reuses outbound streams to peers via the Switch's connection pool.

startGossipSub :: GossipSubNode -> IO () Source #

Start the GossipSub node: register stream handler, notifier, and start heartbeat.

stopGossipSub :: GossipSubNode -> IO () Source #

Stop the GossipSub node: cancel heartbeat and unregister handler.

gossipJoin :: GossipSubNode -> Topic -> IO () Source #

Subscribe to a topic.

gossipLeave :: GossipSubNode -> Topic -> IO () Source #

Unsubscribe from a topic.

gossipPublish :: GossipSubNode -> Topic -> ByteString -> IO () Source #

Publish a message to a topic (signed with the Switch's identity key).