API reference
This is the application-facing API guide for Reticulum-Go. It is not a dump of every exported symbol. It is organized the way you build programs: choose an integration path, follow a recipe, then look up types and methods.
Wire behavior matches the Python RNS API reference. Package layout, concurrency rules, and embedder lifecycle are Go-specific and documented here because the Python manual does not cover them.
For generated signatures, use go doc on the import path or browse the module on pkg.go.dev. For package file maps, see Package map.
How this differs from the Python reference
| Python RNS manual | This document |
|---|---|
Class catalog (RNS.Reticulum, Identity, Destination, …) |
Task-first recipes, then API tables |
One process model (RNS.Reticulum(...)) |
Four integration paths with trade-offs |
| Little concurrency guidance | Explicit callback and locking rules |
| No C / WASM / control-plane docs in the same place | Links to Control API, librns, WASM |
| Examples live elsewhere | Recipes point at examples/ |
Choose an integration path
Need Reticulum in my app
|
v
Go process?
/ \
yes no
| |
v v
pkg/node Same machine as daemon?
in-process |
-------+-------
/ | \
yes C/FFI browser
| | |
v v v
Control API librns pkg/wasm
HTTP/WS .so
\ | /
\ | /
v v v
destination + link
| Path | Package / surface | Use when |
|---|---|---|
| In-process Go | pkg/node |
Default for Go services and tools |
| Daemon + JSON | Control API | Python, Rust, scripts, multi-language hosts |
| In-process C | librns | Native hosts that cannot embed Go source |
| In-process Odin | librns | bindings/odin over librns.so |
| Out-of-process Dart / Flutter | Control API | bindings/dart (rns_control) |
| In-process Dart / Flutter FFI | librns Dart FFI | bindings/dart (ffi.dart), Linux / Android / Windows |
| Out-of-process any language | Control API | HTTP and WebSocket |
| Browser | pkg/wasm |
WebSocket gateway clients |
Most of this page describes the pkg/node happy path. Other paths expose the same concepts with different bindings.
Mental model
- Config loads interfaces and storage paths (
pkg/reticulumconfig,pkg/common). - Node starts transport, interfaces, and optional shared instance (
pkg/node). - Identity holds X25519 + Ed25519 keys (
pkg/identity). - Destination is an app endpoint named
app.aspect…(pkg/destination). - Announce publishes reachability. Peers learn paths.
- Path is a cached route (
Transport.HasPath/RequestPath). - Link is an encrypted session to a destination (
pkg/link). - Request / resource move structured replies and large payloads (
Link.Request,pkg/resource).
Packet MTU remains 500 bytes on the wire (pkg/packet.MTU), same as Python.
Quick start recipe (Go)
package main
import (
"log"
"os"
"os/signal"
"syscall"
"quad4/reticulum-go/pkg/destination"
"quad4/reticulum-go/pkg/identity"
"quad4/reticulum-go/pkg/node"
"quad4/reticulum-go/pkg/reticulumconfig"
)
const appName = "example_utilities"
func main() {
cfg, err := reticulumconfig.InitConfig()
if err != nil {
log.Fatal(err)
}
identity.InitKnownDestinationsPersistence(cfg.ConfigPath, cfg.InMemoryKnownDestinations)
n, err := node.New(cfg)
if err != nil {
log.Fatal(err)
}
if err := n.Start(); err != nil {
log.Fatal(err)
}
defer n.Stop()
id, err := identity.New()
if err != nil {
log.Fatal(err)
}
dest, err := destination.New(id, destination.In|destination.Out, destination.Single,
appName, n.Transport(), "minimal")
if err != nil {
log.Fatal(err)
}
if err := dest.Announce(false, nil, nil); err != nil {
log.Fatal(err)
}
log.Printf("listening on %x", dest.GetHash())
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
<-ch
}
For a guide on complete runnable examples, see Examples.
Recipe: inbound link and request handler
dest.AcceptsLinks(true)
dest.SetLinkEstablishedCallback(func(v any) {
l := v.(*link.Link) // import pkg/link
_ = l.SetResourceStrategy(link.AcceptAll)
l.SetPacketCallback(func(data []byte, _ *packet.Packet) {
log.Printf("data: %q", data)
})
})
_ = dest.RegisterRequestHandler("/echo",
func(_ string, data []byte, _ []byte, _ []byte, _ *identity.Identity, _ int64) []byte {
return data
},
destination.AllowAll, nil)
Recipe: outbound link and request
remoteID, err := identity.Recall(peerDestHash)
if err != nil {
log.Fatal(err)
}
out, err := destination.FromHash(peerDestHash, remoteID, destination.Single, n.Transport())
if err != nil {
log.Fatal(err)
}
if !n.Transport().HasPath(peerDestHash) {
_ = n.Transport().RequestPath(peerDestHash, "", nil, false)
// wait until HasPath is true
}
l := link.NewLink(out, n.Transport(), nil, nil, nil)
if err := l.Establish(); err != nil {
log.Fatal(err)
}
receipt, err := l.Request("/echo", []byte("ping"), 15*time.Second)
if err != nil {
log.Fatal(err)
}
// poll receipt.Concluded() or set receipt.SetResponseCallback
Recipe: send a file resource
res, err := resource.New(fileBytes, true)
if err != nil {
log.Fatal(err)
}
_ = res.SetMetadata(map[string]any{"name": []byte("report.bin")})
if err := l.SendResource(res); err != nil {
log.Fatal(err)
}
On the receiver, set AcceptAll or AcceptApp and handle link.IncomingResource (or plain []byte when no metadata). CLI equivalent: rgocp in CLI utilities.
Recipe: network sleep and wake
n.SetPauseMode(node.PauseModeDisable)
_ = n.OnNetworkLost() // pause links, disable interfaces
_ = n.OnNetworkAvailable()
_ = n.RefreshPaths() // re-request watched destinations
Optional: n.EnableLinkAutoReconnect(node.LinkReconnectOptions{MaxAttempts: 5, Backoff: time.Second}) and n.RegisterLink(l).
Core types
Node (pkg/node)
Orchestrates transport, interfaces, shared instance, and lifecycle. Prefer this over constructing transport.Transport by hand.
| Symbol | Role |
|---|---|
New(cfg) (*Node, error) |
Build without starting |
Start() error |
Transport, path handler, shared instance, interfaces |
Stop() error |
Tear down in reverse order |
Transport() *transport.Transport |
Pass to destinations and links |
Config() *common.ReticulumConfig |
Active config |
Interfaces() []interfaces.Interface |
Configured interfaces |
OnNetworkAvailable() error |
Resume after outage |
OnNetworkLost() error |
Pause for sleep / NIC down |
SetPauseMode(PauseMode) |
PauseModeDisable or PauseModeStop |
WatchDestination(hash) |
Include hash in wake refreshes |
RefreshPaths(dests...) |
Force path refresh |
ReloadInterfaces(newCfg) |
Hot-reload interface blocks |
EnableLinkAutoReconnect(opts) |
Re-establish registered links |
RegisterLink(l) |
Track link for reconnect |
StartInterfaceDiscovery() |
rnstransport discovery when configured |
Identity (pkg/identity)
| Symbol | Role |
|---|---|
New() (*Identity, error) |
Generate software identity (preferred) |
NewIdentity() |
Alternate generator |
FromFile / ToFile |
Persist via identity_backend (file, Secret Service, or Linux kernel keyring + RSSI marker) |
FromBytes / FromPublicKey |
Load from bytes |
LoadIdentityFile(path, signer) |
Software or RHB1 hardware-bound (also resolves RSSI markers) |
NewIdentityWithSigner(...) |
External Ed25519 signer (HSM) |
SetIdentityBackend / ApplyIdentityBackendFromConfig |
Select file or secretservice |
Close / Wipe |
Zero locked private key buffers |
Hash() []byte |
16-byte truncated hash |
GetPublicKey() []byte |
64-byte combined public key |
Sign / Verify |
Ed25519 |
Encrypt / Decrypt |
Identity tokens with optional ratchets |
Recall(destHash) |
Public identity from known destinations |
Remember / ValidateAnnounce |
Announce storage |
LoadOrCreateTransportIdentity |
Daemon transport identity |
RotateRatchet / GetRatchets |
Forward secrecy material |
Constants: KeySize (bits), TruncatedHashLength (bits). Hex destination or identity hashes are 32 characters.
Private key material uses pkg/securemem (best-effort mlock, wipe on Close). See Identity and destinations.
Destination (pkg/destination)
| Constant | Meaning |
|---|---|
In / Out |
Direction bit flags (In|Out for both) |
Single / Group / Plain |
Destination types |
ProveNone / ProveAll / ProveApp |
Proof strategy |
AllowNone / AllowAll / AllowList |
Request handler ACL |
| Symbol | Role |
|---|---|
New(id, direction, type, app, transport, aspects...) |
Create and optionally auto-register (In) |
FromHash(hash, id, type, transport) |
Outbound destination for a known peer |
Hash(id, app, aspects...) |
Compute destination hash |
ParseName / ExpandAppName |
Dotted name helpers |
Announce(pathResponse, tag, iface) |
Publish reachability |
AcceptsLinks(bool) |
Accept link requests |
Encrypt / Decrypt / Sign |
Destination crypto |
SetPacketCallback |
Single-packet inbound data |
SetLinkEstablishedCallback |
Inbound link ready (func(any)) |
RegisterRequestHandler / RegisterRequestHandlerAny |
Link request paths |
EnableRatchets / RotateRatchets |
Group ratchet files |
Link (pkg/link)
| Status | Value | Meaning on Link |
|---|---|---|
StatusPending |
0x00 |
Not established |
StatusHandshake |
0x01 |
Handshake |
StatusActive |
0x02 |
Ready |
StatusStale |
0x03 |
Stale |
StatusClosed |
0x04 |
Closed |
StatusFailed |
0x05 |
Failed |
| Symbol | Role |
|---|---|
NewLink(dest, transport, iface, onEst, onClose) |
Outbound link object |
Establish() error |
Initiator handshake |
Teardown() |
Close |
Identify(id) |
Prove local identity to peer |
Send / SendPacket / SendPacketWithContext |
Encrypted data |
Request(path, data, timeout) |
Msgpack request (auto resource if large) |
SendResource(res) |
Outbound resource transfer |
GetChannel() |
Reliable channel over the link |
SetResourceStrategy |
AcceptNone / AcceptAll / AcceptApp |
SetResourceConcludedCallback |
[]byte or IncomingResource |
GetRTT / idle timers / PHY stats |
Link health |
RequestReceipt
| Method | Role |
|---|---|
Concluded() |
Finished (success or failure) |
GetStatus() |
StatusActive means response OK, StatusFailed means timeout or error |
GetResponse() / GetResponseValue() |
Bytes or decoded msgpack |
GetMetadata() |
Resource response metadata |
Progress() |
Bytes received / total for resource replies |
SetResponseCallback / SetFailedCallback |
Async completion |
Do not confuse RequestReceipt.GetStatus() with Link.GetStatus(). Both reuse status byte constants with different meanings.
Resource (pkg/resource)
| Symbol | Role |
|---|---|
New(data, autoCompress) |
[]byte or seekable file |
SetMetadata(map) |
Prepended msgpack metadata (Python-compatible) |
GetProgress / GetStatus / GetHash |
Transfer state |
PrepareOutboundForLink |
Called by Link.SendResource |
Statuses: StatusPending, StatusActive, StatusComplete, StatusFailed, StatusCancelled.
Transport (via Node.Transport())
| Method | Role |
|---|---|
HasPath(hash) |
Cached route present |
RequestPath(hash, iface, tag, recursive) |
Path request (throttled) |
HopsTo / NextHop / NextHopInterface |
Route inspection |
ExpirePath / PrepareFreshPathRequest |
Drop or refresh cache |
RegisterInterface / GetInterfaces |
Interface table |
RegisterDestination |
Usually automatic for In destinations |
SendPacket / HandlePacket |
Low-level inject (advanced) |
RegisterAnnounceHandler |
Observe announces |
Avoid transport.Destination and transport.Link placeholder types. Use destination.Destination and link.Link.
Packet (pkg/packet)
| Symbol | Role |
|---|---|
MTU |
500 |
NewPacket / Pack / Unpack |
Wire encode/decode |
PacketReceipt |
Delivery proofs for data packets |
| Context constants | ContextRequest, ContextResource, link contexts, … |
Config (pkg/reticulumconfig, pkg/common)
| Function | Role |
|---|---|
InitConfig() |
Load or create ~/.reticulum-go/config |
LoadConfig(path) |
Parse INI (unknown keys ignored) |
SaveConfig / DefaultConfig / CreateDefaultConfig |
Persist defaults |
Important ReticulumConfig fields: EnableTransport, ShareInstance, SharedInstanceType, ports, RPCKey, Interfaces, EnableControlAPI, InMemoryPathTable, InMemoryStorage, WatchInterfaces, DiscoverInterfaces, BackboneIO.
Default config directory is ~/.reticulum-go, not ~/.reticulum.
Python to Go map
| Python | Go |
|---|---|
RNS.Reticulum(configdir=...) |
reticulumconfig.LoadConfig + node.New + Start |
RNS.Identity() |
identity.New() |
Identity.from_file / to_file |
FromFile / ToFile |
Identity.recall(hash) |
identity.Recall(hash) |
Destination(identity, IN, SINGLE, app, *aspects) |
destination.New(id, destination.In, destination.Single, app, tr, aspects...) |
Destination(..., OUT, ...) |
destination.Out or FromHash for known peers |
destination.announce() |
dest.Announce(false, nil, nil) |
destination.set_link_established_callback |
SetLinkEstablishedCallback (func(any)) |
destination.register_request_handler |
RegisterRequestHandler / RegisterRequestHandlerAny |
RNS.Link(destination) |
link.NewLink + Establish |
link.identify(identity) |
l.Identify(id) |
link.request(path, data=...) |
l.Request(path, data, timeout) |
RNS.Resource(data, link, metadata=...) |
resource.New + SetMetadata + l.SendResource |
RNS.Transport.has_path / request_path |
tr.HasPath / tr.RequestPath |
| Shared instance master | First share_instance = yes process (daemon or Node) |
~/.reticulum |
~/.reticulum-go |
Concurrency and callbacks
| Component | Rule |
|---|---|
| Transport / interfaces | Packet handlers run on interface or transport goroutines |
| Destination / link callbacks | May fire concurrently. Return quickly. Do heavy work in your own goroutine |
Link.Request receipts |
Timeout and response callbacks run in separate goroutines |
Same Link |
Do not call Establish, Teardown, and Request concurrently without external locking |
Node.ReloadInterfaces / network hooks |
Serialized by an internal mutex |
| Identities / destinations | Internally mutex-protected. Still treat callbacks as re-entrant |
Python RNS is largely single-threaded asyncio. Go is multi-threaded by default. Design for that.
Errors and empty results
| Situation | Typical signal |
|---|---|
| No path yet | HasPath false. Call RequestPath and wait |
| Link not ready | Establish error or GetStatus() != StatusActive |
| Request timeout | RequestReceipt status StatusFailed |
| Recall before announce | identity.Recall error. Wait for announce or seed known destinations |
| Shared instance auth failure | RPC dial / auth error. Align rpc_key or transport identity |
| Hardware-bound identity without signer | ErrHardwareBoundSignerRequired |
Other API surfaces
| Surface | Document |
|---|---|
| Localhost JSON and WebSocket | Control API |
C ABI (include/rns.h) |
librns |
Odin bindings (bindings/odin) |
librns |
Dart FFI and Control API (bindings/dart) |
librns, Control API |
| Browser JS bridge | Embedding and WebAssembly |
| CLI tools | CLI utilities |
| Crypto details | Cryptography |
| Interface types | Interfaces |
Related documents
- Examples
- Package map
- Embedding and WebAssembly
- Compatibility
- Python RNS API reference (wire and semantic authority)