Skip to content

Messages

import "github.com/eljojo/nara/messages"

Package messages contains all Nara message payload types.

This is the single source of truth for all message payloads exchanged in the Nara network. Every message kind has its payload defined here.

Each file contains related payload types:

  • stash.go: Distributed encrypted storage
  • social.go: Social interactions (teases, trends)
  • presence.go: Identity announcements, heartbeats
  • checkpoint.go: Consensus checkpoints
  • observation.go: Network state observations
  • gossip.go: Peer-to-peer gossip bundles

When adding a new message type:

  1. Add the payload struct with godoc comments: - What the message does - Flow: who sends to whom - Response: what message comes back (if any) - Transport: MQTT, Mesh, or Local

  2. Add a Validate() method for payload validation

  3. Use ID fields as primary identifiers, names for display only

  4. Document version history in comments

// ExamplePayload demonstrates the pattern.
//
// Kind: example:request
// Flow: Alice → Bob
// Response: ExampleResponse
// Transport: MeshOnly
//
// Version History:
// v1 (2024-01): Initial version
type ExamplePayload struct {
ActorID NaraID `json:"actor_id"` // Primary identifier
Actor NaraName `json:"actor,omitempty"` // Display name only
Data []byte `json:"data"`
}
func (p *ExamplePayload) Validate() error {
if p.ActorID == "" {
return errors.New("actor_id required")
}
return nil
}

StashRefreshPayload triggers stash recovery from confidants.

Kind: stash-refresh Flow: Broadcast via MQTT plaza Transport: MQTT (ephemeral, not stored)

This is sent when a nara starts up and wants to recover its stash from confidants. Confidants who have a stash for this owner will respond via mesh with stash:response.

Version History:

v1 (2026-01): Initial version
type StashRefreshPayload struct {
// OwnerID is who wants their stash back
OwnerID types.NaraID `json:"owner_id"`
// Owner is the display name (optional)
Owner types.NaraName `json:"owner,omitempty"`
}

func (p *StashRefreshPayload) Validate() error

Validate checks if the payload is well-formed.

StashRequestPayload requests stored data from a confidant.

Kind: stash:request Flow: Owner → Confidant Response: StashResponsePayload Transport: MeshOnly

Version History:

v1 (2026-01): Initial version
type StashRequestPayload struct {
// OwnerID is who is requesting their stash back
OwnerID types.NaraID `json:"owner_id"`
// RequestID for correlation (optional, for tracking)
RequestID string `json:"request_id,omitempty"`
}

func (p *StashRequestPayload) Validate() error

Validate checks if the payload is well-formed.

StashResponsePayload returns stored data to the owner.

Kind: stash:response Flow: Confidant → Owner (response to stash:request) Transport: MeshOnly

Version History:

v1 (2026-01): Initial version
type StashResponsePayload struct {
// OwnerID is who the stash belongs to
OwnerID types.NaraID `json:"owner_id"`
// RequestID is echoed from the request (for correlation)
RequestID string `json:"request_id,omitempty"`
// Found indicates if the confidant has a stash for this owner
Found bool `json:"found"`
// Nonce for decryption (only if Found is true)
Nonce []byte `json:"nonce,omitempty"`
// Ciphertext of the stored data (only if Found is true)
Ciphertext []byte `json:"ciphertext,omitempty"`
// StoredAt is when the stash was originally stored (Unix timestamp)
StoredAt int64 `json:"stored_at,omitempty"`
}

StashStoreAck acknowledges successful storage of a stash.

Kind: stash:ack Flow: Confidant → Owner (response to stash:store) Transport: MeshOnly

Version History:

v1 (2026-01): Initial version
type StashStoreAck struct {
// OwnerID is echoed back for correlation
OwnerID types.NaraID `json:"owner_id"`
// StoredAt is when the confidant stored the data (Unix timestamp)
StoredAt int64 `json:"stored_at"`
// Success indicates if the storage was successful
Success bool `json:"success"`
// Reason explains why storage failed (if Success is false)
Reason string `json:"reason,omitempty"`
}

StashStorePayload is sent when storing encrypted data with a confidant.

Kind: stash:store Flow: Owner → Confidant Response: StashStoreAck Transport: MeshOnly (direct HTTP)

Version History:

v1 (2026-01): Initial version
type StashStorePayload struct {
// OwnerID is who the stash belongs to (primary identifier for retrieval)
OwnerID types.NaraID `json:"owner_id"`
// Owner is the display name (optional, for logging/debugging)
Owner types.NaraName `json:"owner,omitempty"`
// Nonce for XChaCha20-Poly1305 decryption (24 bytes)
Nonce []byte `json:"nonce"`
// Ciphertext is the encrypted stash data
Ciphertext []byte `json:"ciphertext"`
// Timestamp when the stash was created (Unix timestamp)
Timestamp int64 `json:"ts"`
}

func (p *StashStorePayload) Validate() error

Validate checks if the payload is well-formed.

Generated by gomarkdoc