Files
waste-go/internal/proto/proto.go

381 lines
17 KiB
Go
Raw Permalink Normal View History

Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// Package proto defines all wire types shared between the daemon and anchor.
// Everything on the wire is newline-delimited JSON.
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// Binary data (keys, signatures) is hex-encoded; signaling boxes are base64.
package proto
import (
"crypto/sha256"
"fmt"
"time"
)
// ── Identity ──────────────────────────────────────────────────────────────────
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// PeerID is a peer's stable identity: lowercase hex of the 32-byte Ed25519 public key (64 chars).
// This IS the peer — display names are advisory only and unauthenticated.
type PeerID string
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// Short returns the first 16 hex chars grouped in 4s: "a1b2 c3d4 e5f6 0718".
func (p PeerID) Short() string {
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
s := string(p)
if len(s) < 16 {
return s
}
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
return s[0:4] + " " + s[4:8] + " " + s[8:12] + " " + s[12:16]
}
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// PeerInfo is a peer's self-description, included in the hello confirmation.
type PeerInfo struct {
ID PeerID `json:"id"`
Alias string `json:"alias"` // advisory, not authenticated
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
PublicKey string `json:"public_key"` // Ed25519 pubkey, hex
CreatedAt time.Time `json:"created_at"`
}
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// ── Peer-to-peer message types (over the "yaw" DataChannel) ──────────────────
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// MsgType identifies the kind of peer message.
type MsgType string
const (
MsgChat MsgType = "chat"
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
MsgPm MsgType = "pm" // private message, §8
MsgPeerGossip MsgType = "peer_gossip"
MsgFileListReq MsgType = "file_list_req"
MsgFileListResp MsgType = "file_list_resp"
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
MsgFileOffer MsgType = "file-offer" // §9, hyphenated per spec
MsgFileAccept MsgType = "file-accept"
MsgFileCancel MsgType = "file-cancel"
MsgFileDone MsgType = "file-done"
MsgPing MsgType = "ping"
MsgPong MsgType = "pong"
MsgHistoryRequest MsgType = "history_request"
MsgHistoryChunk MsgType = "history_chunk"
MsgReaction MsgType = "reaction"
)
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
// PmMessage is a private message sent directly over a single peer link (§8 "pm").
// The sender/receiver are implicit from the DataChannel; no room or from fields on the wire.
type PmMessage struct {
Text string `json:"text"`
Ts int64 `json:"ts"` // Unix milliseconds
}
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// PeerMessage is the top-level container sent over the "yaw" DataChannel.
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
// The spec types (hello, chat, pm, file-offer …) are flat JSON objects; we
// embed the fields directly using inline structs where needed, but for structured
// types we include the payload pointer. Unknown fields are ignored (forward compat).
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// File chunks go over a separate binary DataChannel labeled "f:<xid>".
type PeerMessage struct {
Type MsgType `json:"type"`
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
// chat / pm fields (flat on the wire per spec §8)
Mid string `json:"mid,omitempty"` // optional dedup id; required when relay hops > 0
Room string `json:"room,omitempty"` // chat only
Text string `json:"text,omitempty"` // chat and pm
Ts int64 `json:"ts,omitempty"` // chat and pm (Unix ms)
// Non-spec extensions (unknown types are silently ignored by other impls)
Gossip *PeerGossip `json:"gossip,omitempty"`
FileListResp *FileListResp `json:"file_list_resp,omitempty"`
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
// file transfer (§9) — fields are flat on the wire
feat: download dirs, file transfer resume, Wails desktop app, PWA, CI Daemon: - Per-network download directories (-download-dir flag, set_download_dir IPC) - File transfer resume after disconnection: .tmp.meta sidecars survive interruption; resume_offset in file-accept lets sender seek and continue - set_download_dir IPC command; download_dir reported in state_snapshot Protocol: - PeerMessage.ResumeOffset (EXT-006) for file transfer resume - IpcMessage.ShareNetworks json tag changed from "networks" to "network_ids" to fix duplicate json tag collision with Networks []NetworkInfo Desktop app (cmd/app): - Wails v2 shell embedding daemon logic directly (no subprocess) - System tray on Linux/Windows via getlantern/systray; macOS hides to Dock - OS notifications for message_received and file_complete via Wails events - notray build tag for headless/CI builds without GTK tray headers - build-app.sh: builds web frontend, copies dist, runs wails build Web / PWA: - manifest.json + Apple touch icon meta tags for mobile "Add to Home Screen" - PNG icons (192px, 512px, 180px) generated from SVG - Wails EventsOn("notify") hook in App.tsx for native OS notifications CI: - .gitea/workflows/build.yml: server binaries cross-compiled for 5 platforms, desktop app for Linux amd64, release artifacts published on v* tags Docs: - README: download dir, file transfer resume, desktop app, PWA, CI sections - EXTENSIONS.md: EXT-004 daemon mode marked shipped; EXT-006 resume added - FUTURE.md: roadmap updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 21:38:28 +02:00
Xid string `json:"xid,omitempty"`
Name string `json:"name,omitempty"`
Size int64 `json:"size,omitempty"`
SHA256 string `json:"sha256,omitempty"`
ResumeOffset int64 `json:"resume_offset,omitempty"` // waste-go ext: non-zero in file-accept when resuming
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
// file-done / file-cancel / file-accept just need xid (already above)
Reason string `json:"reason,omitempty"` // file-cancel
Seq *uint64 `json:"seq,omitempty"` // ping/pong
// history_request fields
Since int64 `json:"since,omitempty"` // Unix ms; 0 = no lower bound
Limit int `json:"limit,omitempty"`
// history_chunk fields
History []HistoryEntry `json:"history,omitempty"`
HistoryDone bool `json:"history_done,omitempty"`
// reaction fields
ReactionMID string `json:"reaction_mid,omitempty"`
ReactionEmoji string `json:"reaction_emoji,omitempty"`
}
// ResumableFile describes a partially-downloaded file found on daemon startup.
type ResumableFile struct {
Name string `json:"name"`
SHA256 string `json:"sha256"`
From string `json:"from"` // peer ID hex
Size int64 `json:"size"`
Offset int64 `json:"offset"` // bytes already received
}
// HistoryEntry is one message in a history_chunk response.
type HistoryEntry struct {
Mid string `json:"mid"`
From string `json:"from"` // peer ID hex
FromAlias string `json:"from_alias"` // advisory
Text string `json:"text"`
Ts int64 `json:"ts"` // Unix ms
}
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
// ChatMessage is a group chat message (wire type "chat", §8).
// Also used internally for persisting PMs after they are received.
type ChatMessage struct {
Mid string `json:"mid,omitempty"` // optional dedup id (required when relay hops > 0)
MsgID string `json:"msg_id,omitempty"` // EXT-007: content-addressed gossip ID
From PeerID `json:"from,omitempty"` // set by receiver from DC context; not on wire for pm
To *PeerID `json:"to,omitempty"` // internal only — not transmitted; set for DMs
Room string `json:"room"`
Text string `json:"text"`
Ts int64 `json:"ts"` // Unix milliseconds
}
// ComputeMsgID returns the EXT-007 content-addressed ID for a message.
// sha256(fromID \x00 room \x00 ts_decimal \x00 text)
func ComputeMsgID(fromID PeerID, room string, ts int64, text string) string {
h := sha256.New()
fmt.Fprintf(h, "%s\x00%s\x00%d\x00%s", string(fromID), room, ts, text)
return fmt.Sprintf("sha256:%x", h.Sum(nil))
}
// PeerGossip shares known peer addresses.
type PeerGossip struct {
Peers []GossipEntry `json:"peers"`
}
// GossipEntry is one peer hint shared via gossip.
type GossipEntry struct {
Peer PeerInfo `json:"peer"`
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
AddrHint string `json:"addr_hint"` // IP:port hint, may be behind NAT
LastSeen time.Time `json:"last_seen"`
}
// FileEntry describes a single file in a peer's shared directory.
type FileEntry struct {
Name string `json:"name"`
SizeBytes int64 `json:"size_bytes"`
Path string `json:"path,omitempty"` // relative path including filename
}
// ShareEntry describes one persistent share root.
type ShareEntry struct {
Path string `json:"path"`
Networks []string `json:"networks"` // ["*"] = global
}
// FileListResp is the payload for MsgFileListResp.
// MsgFileListReq carries no payload — it is a zero-field request.
type FileListResp struct {
Files []FileEntry `json:"files"`
}
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
// FileOffer is used internally when emitting EvtIncomingFile to the IPC layer.
// On the wire, file-offer fields are flat inside PeerMessage (xid/name/size/sha256).
type FileOffer struct {
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
Xid string `json:"xid"`
Bring wire protocol into full YAW/2 spec compliance Five interop issues fixed against PROTOCOL.md: - Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex string) as specified in §5.1, not net_raw_bytes. Both anchor server and client updated to match. - Chat wire fields renamed to spec names: text/ts (Unix ms int64) replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage matches §8 exactly; store and TUI updated accordingly. - Direct messages now use the spec "pm" type (flat {type,mid,text,ts}) instead of chat+to. Receiver reconstructs a ChatMessage with dm:<short-id> room for IPC/storage. §8 compliant. - File transfer message types changed to spec hyphenated names: file-offer, file-accept, file-cancel, file-done with spec field names (name/size not filename/size_bytes). §9 compliant. - DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen fires on OnOpen callback or immediately if the channel is already open when WireDataChannel is called (answerer race). Also fixes two bugs found during testing: - mid was missing from outgoing wire messages, causing all received messages to arrive with mid="" and collide on the UNIQUE DB constraint. mid is now included on all sent chat/pm messages; a random mid is generated for any received message that omits it. - Test scripts hardened: kill -9 + active lsof polling replaces blind sleep for port cleanup; join_network sent before peer_field queries (local_peer is now network-scoped and nil until joined). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
Name string `json:"name"`
Size int64 `json:"size"`
SHA256 string `json:"sha256"`
}
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// ── DataChannel hello (YAW/2 §6) ─────────────────────────────────────────────
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// HelloMessage is the first message sent on the "yaw" DataChannel.
// The signature binds this identity to the specific DTLS session.
// The Invite field is a waste-go extension (§ waste-go/extensions.md):
// when RequireInvite is enabled on a network, peers that omit or present
// an invalid signed invite are disconnected. YAW/2-only peers ignore this field.
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
type HelloMessage struct {
Type string `json:"type"` // always "hello"
ID string `json:"id"` // hex pubkey
Nick string `json:"nick"` // alias
Caps []string `json:"caps"` // capability list, e.g. ["chat","file"]
Sig string `json:"sig"` // hex ed25519 sig over HelloBindString
Invite string `json:"invite,omitempty"` // waste-go ext: signed waste: invite string
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
}
// HelloBindString returns the bytes the hello signature covers:
// "yaw/2 bind" || localDTLSFingerprint(32 bytes) || remoteDTLSFingerprint(32 bytes)
func HelloBindString(localFP, remoteFP []byte) []byte {
buf := []byte("yaw/2 bind")
buf = append(buf, localFP...)
buf = append(buf, remoteFP...)
return buf
}
// ── Signaling payload (sealed inside nacl/box, exchanged via anchor) ──────────
// SignalingKind identifies the kind of sealed signaling payload.
type SignalingKind string
const (
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
SigOffer SignalingKind = "offer"
SigAnswer SignalingKind = "answer"
SigCandidate SignalingKind = "candidate"
SigBye SignalingKind = "bye"
2026-06-22 14:45:15 +02:00
SigEkey SignalingKind = "ekey" // YAW/2.1: ephemeral key exchange
)
2026-06-22 14:45:15 +02:00
// SignalingPayload is the JSON plaintext sealed inside a crypto_box (YAW/2 §5 / §5.4).
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
type SignalingPayload struct {
Kind SignalingKind `json:"kind"`
SDP string `json:"sdp,omitempty"` // offer / answer
Cand string `json:"cand,omitempty"` // trickle ICE candidate line
Mid string `json:"mid,omitempty"` // media stream id for candidate
MLine int `json:"mline,omitempty"` // media line index
2026-06-22 14:45:15 +02:00
// YAW/2.1 ekey fields (sealed under static keys)
V string `json:"v,omitempty"` // "yaw/2.1"
EPK string `json:"epk,omitempty"` // hex-encoded ephemeral X25519 pubkey (32 bytes)
EkeySig string `json:"ekey_sig,omitempty"` // hex Ed25519 sig over ekey bind bytes
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
}
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// ── Anchor WebSocket wire types (YAW/2 §5) ────────────────────────────────────
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// AnchorMsgType identifies anchor WebSocket messages.
type AnchorMsgType string
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
const (
AnchorChallenge AnchorMsgType = "challenge"
AnchorJoin AnchorMsgType = "join"
AnchorJoined AnchorMsgType = "joined"
AnchorPeerJoin AnchorMsgType = "peer-join"
AnchorPeerLeave AnchorMsgType = "peer-leave"
AnchorTo AnchorMsgType = "to"
AnchorFrom AnchorMsgType = "from"
AnchorNoPeer AnchorMsgType = "no-peer"
)
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// AnchorMessage covers all WebSocket frames to/from the anchor.
type AnchorMessage struct {
Type AnchorMsgType `json:"type"`
Nonce string `json:"nonce,omitempty"` // challenge nonce, hex
ID string `json:"id,omitempty"` // peer hex id
Net string `json:"net,omitempty"` // hashed network name
Sig string `json:"sig,omitempty"` // ed25519 sig over (nonce||net), hex
Peers []string `json:"peers,omitempty"` // joined: list of peer hex ids in network
To string `json:"to,omitempty"` // target peer hex id
From string `json:"from,omitempty"` // sender peer hex id
Box string `json:"box,omitempty"` // base64 nacl/box sealed payload
}
// ── IPC protocol (daemon ↔ local UI) ─────────────────────────────────────────
// IpcMsgType identifies IPC messages.
type IpcMsgType string
const (
// Commands (UI → daemon)
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
CmdSendMessage IpcMsgType = "send_message"
CmdJoinNetwork IpcMsgType = "join_network" // fields: network_name (plaintext)
CmdLeaveNetwork IpcMsgType = "leave_network"
CmdGetState IpcMsgType = "get_state"
CmdSendFile IpcMsgType = "send_file"
CmdSetShareDir IpcMsgType = "set_share_dir" // set per-network share directory at runtime
CmdGenerateInvite IpcMsgType = "generate_invite"
CmdGetFileList IpcMsgType = "get_file_list"
CmdExportIdentity IpcMsgType = "export_identity" // returns encrypted backup blob
CmdImportIdentity IpcMsgType = "import_identity" // replaces identity from backup blob
CmdAddShare IpcMsgType = "add_share" // add a share root; fields: path, networks
CmdRemoveShare IpcMsgType = "remove_share" // remove a share root; field: path
CmdListShares IpcMsgType = "list_shares" // returns shares_list event
feat: download dirs, file transfer resume, Wails desktop app, PWA, CI Daemon: - Per-network download directories (-download-dir flag, set_download_dir IPC) - File transfer resume after disconnection: .tmp.meta sidecars survive interruption; resume_offset in file-accept lets sender seek and continue - set_download_dir IPC command; download_dir reported in state_snapshot Protocol: - PeerMessage.ResumeOffset (EXT-006) for file transfer resume - IpcMessage.ShareNetworks json tag changed from "networks" to "network_ids" to fix duplicate json tag collision with Networks []NetworkInfo Desktop app (cmd/app): - Wails v2 shell embedding daemon logic directly (no subprocess) - System tray on Linux/Windows via getlantern/systray; macOS hides to Dock - OS notifications for message_received and file_complete via Wails events - notray build tag for headless/CI builds without GTK tray headers - build-app.sh: builds web frontend, copies dist, runs wails build Web / PWA: - manifest.json + Apple touch icon meta tags for mobile "Add to Home Screen" - PNG icons (192px, 512px, 180px) generated from SVG - Wails EventsOn("notify") hook in App.tsx for native OS notifications CI: - .gitea/workflows/build.yml: server binaries cross-compiled for 5 platforms, desktop app for Linux amd64, release artifacts published on v* tags Docs: - README: download dir, file transfer resume, desktop app, PWA, CI sections - EXTENSIONS.md: EXT-004 daemon mode marked shipped; EXT-006 resume added - FUTURE.md: roadmap updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 21:38:28 +02:00
CmdCreateRoom IpcMsgType = "create_room" // field: room (name)
CmdSetDownloadDir IpcMsgType = "set_download_dir" // set per-network download directory at runtime; fields: network_id, path
CmdSendReaction IpcMsgType = "send_reaction" // fields: network_id, reaction_mid, reaction_emoji
// Events (daemon → UI)
EvtMessageReceived IpcMsgType = "message_received"
EvtPeerConnected IpcMsgType = "peer_connected"
EvtPeerDisconnected IpcMsgType = "peer_disconnected"
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
EvtSessionReady IpcMsgType = "session_ready" // DataChannel open + hello verified
EvtPeerStatus IpcMsgType = "peer_status" // ICE connection state + candidate type
EvtIncomingFile IpcMsgType = "incoming_file"
EvtFileProgress IpcMsgType = "file_progress"
EvtStateSnapshot IpcMsgType = "state_snapshot"
EvtError IpcMsgType = "error"
EvtInviteGenerated IpcMsgType = "invite_generated"
EvtFileList IpcMsgType = "file_list"
EvtFileComplete IpcMsgType = "file_complete"
Multi-network foundation: netmgr, derived identities, additive IPC protocol YAW/2 peer wire protocol is unchanged. Changes are local only. internal/crypto: - DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash; same master + same network always produces the same Ed25519 keypair (stable peer ID) internal/proto: - NetworkInfo type (network_id, network_name, local_peer) - NetworkID field on IpcMessage (optional; commands default to first network when absent) - Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer) - EvtNetworkJoined / EvtNetworkLeft events internal/netmgr (new): - Manager holds N independent Network contexts (derived identity, mesh, store, anchor) - Join(name) creates context, derives identity, opens per-network DB, starts anchor client - Leave(id) / LeaveAll() cancel contexts and close stores - Resolve(netID) returns named network, or Default() when netID is empty (backward compat) - Fan-out: Manager.Subscribe() receives tagged events from all networks - Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short internal/ipc: - Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn) - Commands without network_id route to mgr.Default() (backward compat) - state_snapshot includes Networks array; local_peer/connected_peers still populated from first network - generate_invite, get_file_list, send_message all respect network_id routing cmd/daemon: - Creates netmgr.Manager instead of mesh.Mesh directly - --join and --share-dir pass through Config - Auto-join via mgr.Join() before IPC starts test-network.sh: - Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
EvtNetworkJoined IpcMsgType = "network_joined"
EvtNetworkLeft IpcMsgType = "network_left"
EvtIdentityExported IpcMsgType = "identity_exported"
EvtIdentityImported IpcMsgType = "identity_imported"
EvtSharesList IpcMsgType = "shares_list"
EvtRoomCreated IpcMsgType = "room_created" // field: room (name)
EvtHistoryLoaded IpcMsgType = "history_loaded" // fields: room, messages
EvtResumableTransfers IpcMsgType = "resumable_transfers" // field: resumable_files
EvtReaction IpcMsgType = "reaction" // fields: reaction_mid, reaction_emoji, peer_id
)
Multi-network foundation: netmgr, derived identities, additive IPC protocol YAW/2 peer wire protocol is unchanged. Changes are local only. internal/crypto: - DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash; same master + same network always produces the same Ed25519 keypair (stable peer ID) internal/proto: - NetworkInfo type (network_id, network_name, local_peer) - NetworkID field on IpcMessage (optional; commands default to first network when absent) - Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer) - EvtNetworkJoined / EvtNetworkLeft events internal/netmgr (new): - Manager holds N independent Network contexts (derived identity, mesh, store, anchor) - Join(name) creates context, derives identity, opens per-network DB, starts anchor client - Leave(id) / LeaveAll() cancel contexts and close stores - Resolve(netID) returns named network, or Default() when netID is empty (backward compat) - Fan-out: Manager.Subscribe() receives tagged events from all networks - Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short internal/ipc: - Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn) - Commands without network_id route to mgr.Default() (backward compat) - state_snapshot includes Networks array; local_peer/connected_peers still populated from first network - generate_invite, get_file_list, send_message all respect network_id routing cmd/daemon: - Creates netmgr.Manager instead of mesh.Mesh directly - --join and --share-dir pass through Config - Auto-join via mgr.Join() before IPC starts test-network.sh: - Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
// NetworkInfo summarises one joined network for state_snapshot and network_joined events.
type NetworkInfo struct {
NetworkID string `json:"network_id"`
NetworkName string `json:"network_name"`
LocalPeer *PeerInfo `json:"local_peer,omitempty"`
ShareDir string `json:"share_dir,omitempty"` // absolute path; empty = not sharing
DownloadDir string `json:"download_dir,omitempty"` // absolute path for received files
Multi-network foundation: netmgr, derived identities, additive IPC protocol YAW/2 peer wire protocol is unchanged. Changes are local only. internal/crypto: - DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash; same master + same network always produces the same Ed25519 keypair (stable peer ID) internal/proto: - NetworkInfo type (network_id, network_name, local_peer) - NetworkID field on IpcMessage (optional; commands default to first network when absent) - Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer) - EvtNetworkJoined / EvtNetworkLeft events internal/netmgr (new): - Manager holds N independent Network contexts (derived identity, mesh, store, anchor) - Join(name) creates context, derives identity, opens per-network DB, starts anchor client - Leave(id) / LeaveAll() cancel contexts and close stores - Resolve(netID) returns named network, or Default() when netID is empty (backward compat) - Fan-out: Manager.Subscribe() receives tagged events from all networks - Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short internal/ipc: - Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn) - Commands without network_id route to mgr.Default() (backward compat) - state_snapshot includes Networks array; local_peer/connected_peers still populated from first network - generate_invite, get_file_list, send_message all respect network_id routing cmd/daemon: - Creates netmgr.Manager instead of mesh.Mesh directly - --join and --share-dir pass through Config - Auto-join via mgr.Join() before IPC starts test-network.sh: - Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
}
// IpcMessage covers both commands and events.
type IpcMessage struct {
Type IpcMsgType `json:"type"`
Multi-network foundation: netmgr, derived identities, additive IPC protocol YAW/2 peer wire protocol is unchanged. Changes are local only. internal/crypto: - DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash; same master + same network always produces the same Ed25519 keypair (stable peer ID) internal/proto: - NetworkInfo type (network_id, network_name, local_peer) - NetworkID field on IpcMessage (optional; commands default to first network when absent) - Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer) - EvtNetworkJoined / EvtNetworkLeft events internal/netmgr (new): - Manager holds N independent Network contexts (derived identity, mesh, store, anchor) - Join(name) creates context, derives identity, opens per-network DB, starts anchor client - Leave(id) / LeaveAll() cancel contexts and close stores - Resolve(netID) returns named network, or Default() when netID is empty (backward compat) - Fan-out: Manager.Subscribe() receives tagged events from all networks - Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short internal/ipc: - Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn) - Commands without network_id route to mgr.Default() (backward compat) - state_snapshot includes Networks array; local_peer/connected_peers still populated from first network - generate_invite, get_file_list, send_message all respect network_id routing cmd/daemon: - Creates netmgr.Manager instead of mesh.Mesh directly - --join and --share-dir pass through Config - Auto-join via mgr.Join() before IPC starts test-network.sh: - Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
// optional: scopes a command/event to a specific network.
// When absent, defaults to the first (or only) joined network.
NetworkID string `json:"network_id,omitempty"`
// send_message
Room string `json:"room,omitempty"`
To *PeerID `json:"to,omitempty"`
Body string `json:"body,omitempty"`
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
// join_network / leave_network
NetworkName string `json:"network_name,omitempty"`
NetworkHash string `json:"network_hash,omitempty"` // 64-char hex (yaw2 `net` field); alternative to network_name
ShareDir string `json:"share_dir,omitempty"` // optional per-network share directory
RequireInvite bool `json:"require_invite,omitempty"` // waste-go ext: reject peers without valid signed invite
InviteString string `json:"invite_string,omitempty"` // waste-go ext: the invite used to join (stored in mesh)
// send_file / set_share_dir / file_complete path
Path string `json:"path,omitempty"`
// events
Peer *PeerInfo `json:"peer,omitempty"`
PeerID *PeerID `json:"peer_id,omitempty"`
Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto Replace the original raw-TCP peer connections and Blowfish/RSA-era design with the YAW/2 protocol stack: Transport - internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/ candidate exchange rather than direct dialling. - internal/nat: deleted — ICE subsumes everything this package was going to do. Signaling - cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts peer-join/peer-leave events. Never sees plaintext signaling content. - internal/anchor: new anchor client. Manages PeerConnection lifecycle, decides offerer by peer-id comparison, seals/opens signaling payloads with nacl/box, implements mesh.Anchor. Crypto (internal/crypto) - PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2). - Sign/Verify: hex signatures throughout. - Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519 identity via Montgomery conversion (filippo.io/edwards25519), matching libsodium's crypto_sign_ed25519_*_to_curve25519. - Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open for signaling payloads. Wire types (internal/proto) - ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8). - FileChunk removed from PeerMessage — chunks go on a separate binary DataChannel labelled "f:<xid>"; FileDone added. - New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString. - PeerID.Short() now returns first 16 hex chars grouped in 4s. - IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added; EvtSessionReady added (fires when DataChannel opens and hello is received). IPC (internal/ipc) - join_network/leave_network replace connect (direct TCP dial). - Network joins are context-scoped: leave_network or client disconnect cancels the anchor connection cleanly. README updated to reflect new project layout, getting-started commands, IPC protocol, and roadmap state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
Nick string `json:"nick,omitempty"`
Message *ChatMessage `json:"message,omitempty"`
Offer *FileOffer `json:"offer,omitempty"`
TransferID string `json:"transfer_id,omitempty"`
BytesReceived int64 `json:"bytes_received,omitempty"`
TotalBytes int64 `json:"total_bytes,omitempty"`
Multi-network foundation: netmgr, derived identities, additive IPC protocol YAW/2 peer wire protocol is unchanged. Changes are local only. internal/crypto: - DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash; same master + same network always produces the same Ed25519 keypair (stable peer ID) internal/proto: - NetworkInfo type (network_id, network_name, local_peer) - NetworkID field on IpcMessage (optional; commands default to first network when absent) - Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer) - EvtNetworkJoined / EvtNetworkLeft events internal/netmgr (new): - Manager holds N independent Network contexts (derived identity, mesh, store, anchor) - Join(name) creates context, derives identity, opens per-network DB, starts anchor client - Leave(id) / LeaveAll() cancel contexts and close stores - Resolve(netID) returns named network, or Default() when netID is empty (backward compat) - Fan-out: Manager.Subscribe() receives tagged events from all networks - Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short internal/ipc: - Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn) - Commands without network_id route to mgr.Default() (backward compat) - state_snapshot includes Networks array; local_peer/connected_peers still populated from first network - generate_invite, get_file_list, send_message all respect network_id routing cmd/daemon: - Creates netmgr.Manager instead of mesh.Mesh directly - --join and --share-dir pass through Config - Auto-join via mgr.Join() before IPC starts test-network.sh: - Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
// state_snapshot fields (existing shape preserved for backward compat)
MasterAlias string `json:"master_alias,omitempty"` // daemon's alias (available before any network join)
MasterID string `json:"master_id,omitempty"` // daemon's master public key hex
Multi-network foundation: netmgr, derived identities, additive IPC protocol YAW/2 peer wire protocol is unchanged. Changes are local only. internal/crypto: - DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash; same master + same network always produces the same Ed25519 keypair (stable peer ID) internal/proto: - NetworkInfo type (network_id, network_name, local_peer) - NetworkID field on IpcMessage (optional; commands default to first network when absent) - Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer) - EvtNetworkJoined / EvtNetworkLeft events internal/netmgr (new): - Manager holds N independent Network contexts (derived identity, mesh, store, anchor) - Join(name) creates context, derives identity, opens per-network DB, starts anchor client - Leave(id) / LeaveAll() cancel contexts and close stores - Resolve(netID) returns named network, or Default() when netID is empty (backward compat) - Fan-out: Manager.Subscribe() receives tagged events from all networks - Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short internal/ipc: - Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn) - Commands without network_id route to mgr.Default() (backward compat) - state_snapshot includes Networks array; local_peer/connected_peers still populated from first network - generate_invite, get_file_list, send_message all respect network_id routing cmd/daemon: - Creates netmgr.Manager instead of mesh.Mesh directly - --join and --share-dir pass through Config - Auto-join via mgr.Join() before IPC starts test-network.sh: - Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
LocalPeer *PeerInfo `json:"local_peer,omitempty"`
ConnectedPeers []PeerInfo `json:"connected_peers,omitempty"`
KnownPeers []PeerInfo `json:"known_peers,omitempty"` // historically seen, not currently connected
Multi-network foundation: netmgr, derived identities, additive IPC protocol YAW/2 peer wire protocol is unchanged. Changes are local only. internal/crypto: - DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash; same master + same network always produces the same Ed25519 keypair (stable peer ID) internal/proto: - NetworkInfo type (network_id, network_name, local_peer) - NetworkID field on IpcMessage (optional; commands default to first network when absent) - Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer) - EvtNetworkJoined / EvtNetworkLeft events internal/netmgr (new): - Manager holds N independent Network contexts (derived identity, mesh, store, anchor) - Join(name) creates context, derives identity, opens per-network DB, starts anchor client - Leave(id) / LeaveAll() cancel contexts and close stores - Resolve(netID) returns named network, or Default() when netID is empty (backward compat) - Fan-out: Manager.Subscribe() receives tagged events from all networks - Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short internal/ipc: - Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn) - Commands without network_id route to mgr.Default() (backward compat) - state_snapshot includes Networks array; local_peer/connected_peers still populated from first network - generate_invite, get_file_list, send_message all respect network_id routing cmd/daemon: - Creates netmgr.Manager instead of mesh.Mesh directly - --join and --share-dir pass through Config - Auto-join via mgr.Join() before IPC starts test-network.sh: - Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
Rooms []string `json:"rooms,omitempty"`
// multi-network: all joined networks (additive)
Networks []NetworkInfo `json:"networks,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
InviteGenerated string `json:"invite,omitempty"`
Files []FileEntry `json:"files,omitempty"`
Messages []ChatMessage `json:"messages,omitempty"` // history_loaded
ResumableFiles []ResumableFile `json:"resumable_files,omitempty"` // resumable_transfers
ReactionMID string `json:"reaction_mid,omitempty"` // reaction
ReactionEmoji string `json:"reaction_emoji,omitempty"` // reaction
Shares []ShareEntry `json:"shares,omitempty"`
feat: download dirs, file transfer resume, Wails desktop app, PWA, CI Daemon: - Per-network download directories (-download-dir flag, set_download_dir IPC) - File transfer resume after disconnection: .tmp.meta sidecars survive interruption; resume_offset in file-accept lets sender seek and continue - set_download_dir IPC command; download_dir reported in state_snapshot Protocol: - PeerMessage.ResumeOffset (EXT-006) for file transfer resume - IpcMessage.ShareNetworks json tag changed from "networks" to "network_ids" to fix duplicate json tag collision with Networks []NetworkInfo Desktop app (cmd/app): - Wails v2 shell embedding daemon logic directly (no subprocess) - System tray on Linux/Windows via getlantern/systray; macOS hides to Dock - OS notifications for message_received and file_complete via Wails events - notray build tag for headless/CI builds without GTK tray headers - build-app.sh: builds web frontend, copies dist, runs wails build Web / PWA: - manifest.json + Apple touch icon meta tags for mobile "Add to Home Screen" - PNG icons (192px, 512px, 180px) generated from SVG - Wails EventsOn("notify") hook in App.tsx for native OS notifications CI: - .gitea/workflows/build.yml: server binaries cross-compiled for 5 platforms, desktop app for Linux amd64, release artifacts published on v* tags Docs: - README: download dir, file transfer resume, desktop app, PWA, CI sections - EXTENSIONS.md: EXT-004 daemon mode marked shipped; EXT-006 resume added - FUTURE.md: roadmap updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 21:38:28 +02:00
ShareNetworks []string `json:"network_ids,omitempty"` // for add_share command: scope to specific network IDs, or ["*"] for global
// export_identity / import_identity
Passphrase string `json:"passphrase,omitempty"` // import only; never echoed back
Backup string `json:"backup,omitempty"` // JSON backup blob
// peer_status — ICE connection quality
ConnState string `json:"conn_state,omitempty"` // pion PeerConnectionState string
CandidateType string `json:"candidate_type,omitempty"` // host | srflx | relay | unknown
RemoteAddress string `json:"remote_address,omitempty"` // remote IP:port of active candidate pair
}