// Package invite encodes and decodes waste invite strings. // // Format: "waste:" // // The JSON payload is compatible with yaw2: the `net` field carries the full // 64-char hex SHA-256("yaw2-net:"+name) hash that yaw2 clients pass directly // to the signaling server. A yaw2 client that can parse the base64 JSON can join // the same network without knowing the plaintext name. package invite import ( "crypto/sha256" "encoding/base64" "encoding/hex" "encoding/json" "fmt" "strings" ) const prefix = "waste:" // Invite holds the information needed to join a network. type Invite struct { Anchor string `json:"anchor"` // WebSocket anchor URL Network string `json:"network"` // plaintext network name Net string `json:"net,omitempty"` // 64-char hex SHA-256("yaw2-net:"+name) — yaw2 `net` field } // Encode returns a waste: invite string for the given anchor URL and network name. func Encode(anchor, network string) (string, error) { if anchor == "" { return "", fmt.Errorf("anchor URL is required") } if network == "" { return "", fmt.Errorf("network name is required") } h := sha256.Sum256([]byte("yaw2-net:" + network)) b, err := json.Marshal(Invite{ Anchor: anchor, Network: network, Net: hex.EncodeToString(h[:]), }) if err != nil { return "", err } return prefix + base64.URLEncoding.EncodeToString(b), nil } // Decode parses a waste: invite string and returns the Invite. func Decode(s string) (Invite, error) { s = strings.TrimSpace(s) if !strings.HasPrefix(s, prefix) { return Invite{}, fmt.Errorf("not a waste invite (expected 'waste:' prefix)") } b, err := base64.URLEncoding.DecodeString(strings.TrimPrefix(s, prefix)) if err != nil { return Invite{}, fmt.Errorf("invalid invite: %w", err) } var inv Invite if err := json.Unmarshal(b, &inv); err != nil { return Invite{}, fmt.Errorf("invalid invite payload: %w", err) } if inv.Anchor == "" || inv.Network == "" { return Invite{}, fmt.Errorf("invite is missing anchor or network name") } return inv, nil } // NetHash returns the full 64-char hex network hash for the given name // (SHA-256("yaw2-net:" + name)). This is the `net` field sent to the anchor. func NetHash(name string) string { h := sha256.Sum256([]byte("yaw2-net:" + name)) return hex.EncodeToString(h[:]) }