Help us shape the future of Go! Take the 2026 Go Developer Survey

address

package
v1.3.104 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package address pkg/skychat/address/address.go c4-app-chat the skychat:// address grammar — one shareable, scannable identifier for the three things a user can open: a person, a group, a channel.

Grammar:

skychat://<pk>              a person — opens a 1:1 DM
skychat://<pk>/<group-id>   a group or channel hosted by that visor

Both forms are short enough to print on a card and to encode in a low-density QR code, which is the whole reason they exist: an invite link (skychat:invite:<base64url(json)>) is a few hundred characters because it carries the group's port, mode, admin list and proof-of-work price inline, and a code that dense is unpleasant to scan on a phone.

The trade is that an address is NOT self-contained. A group address names a group but does not describe it, so acting on one requires asking the host visor what it is — see Manager.ProbeGroup. That round trip is also what makes "type a key and let the app work out what it is" possible at all: a bare public key looks identical whether it belongs to a person or to the host of a channel, so nothing can be decided by inspection.

Which of the two forms to hand out is therefore a real choice, not a preference: an address is short and stays valid as the group changes, an invite works while the host is offline. Both are accepted everywhere a user can paste — see the note on Parse and ErrIsInvite.

Why the group ID is a path segment and not, say, a query parameter: a query needs escaping rules that QR alphanumeric mode does not cover cheaply, and "host/resource" is the shape every user already reads correctly from a URL.

Index

Constants

View Source
const Scheme = "skychat://"

Scheme is the URI prefix of a skychat address.

The `//` form is deliberate and distinguishes this from the older `skychat:invite:` links: an authority-style `//<pk>` says the part after it is a host, which is exactly what a visor public key is here.

Variables

View Source
var (
	// ErrEmpty is returned for input that is blank once trimmed.
	ErrEmpty = errors.New("skychat address: empty")

	// ErrIsInvite marks input that is a group invite link rather than an
	// address. Returned as a distinct sentinel so a caller holding one
	// paste box can try both parsers and route accordingly, rather than
	// telling a user who pasted a perfectly good invite that their
	// address is malformed.
	ErrIsInvite = errors.New("skychat address: this is an invite link, not an address")
)

Functions

func IsInvite

func IsInvite(s string) bool

IsInvite reports whether s looks like a group invite link. Exported so a caller can route input before parsing, without depending on the error value.

Types

type Address

type Address struct {
	// PK is the visor the address names: the peer for a DM, the group's
	// host for a group address.
	PK cipher.PubKey

	// GroupID is the group's UUID, empty for a DM address.
	GroupID string
}

Address is a parsed skychat address.

func DM

func DM(pk cipher.PubKey) Address

DM returns the address of a peer's 1:1 chat.

func Group

func Group(pk cipher.PubKey, groupID string) Address

Group returns the address of a group or channel hosted by pk.

func Parse

func Parse(s string) (Address, error)

Parse reads any of the accepted spellings of an address:

skychat://<pk>
skychat://<pk>/<group-id>
<pk>
<pk>/<group-id>

The bare forms are accepted because the field this feeds used to take nothing but a raw public key, and every key a user has already saved or shared is in that shape. Requiring the scheme would have broken every one of them for no gain.

Whitespace is trimmed and a trailing slash ignored — both are what a terminal copy, a QR decode, or a chat client's link detector tend to leave behind. A group invite link returns ErrIsInvite so the caller can hand it to the invite parser instead.

func (Address) IsGroup

func (a Address) IsGroup() bool

IsGroup reports whether this address names a group or channel rather than a person.

func (Address) Kind

func (a Address) Kind() Kind

Kind reports what this address points at.

func (Address) String

func (a Address) String() string

String renders the canonical form. Lowercase hex, because an address is compared and deduplicated as a string in several places (the UI's contact list keys on it) and mixed case would make two spellings of one identity look like two identities.

type Kind

type Kind string

Kind is what an address points at.

const (
	// KindDM — a bare public key: a person, opened as a 1:1 chat.
	KindDM Kind = "dm"

	// KindGroup — a public key plus a group ID. Whether the group is an
	// ordinary group or a broadcast channel is NOT knowable from the
	// address; only the host visor can say, so a resolver reports the
	// group kind separately. Calling this KindGroup rather than
	// KindGroupOrChannel keeps the grammar honest: the address form is
	// the same for both, and pretending otherwise would invite callers
	// to trust a distinction the string cannot carry.
	KindGroup Kind = "group"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL