# Go SDK The Go SDK (`sdks/go/`) provides a native QUIC + Cap'n Proto client for quicproquo, giving Go applications full access to the messaging API without any HTTP translation layer. ## Prerequisites - Go 1.21+ - A running qpq server ## Installation ```go import "quicproquo.dev/sdk/go/qpq" ``` ## Quick start ```go package main import ( "context" "fmt" "log" "quicproquo.dev/sdk/go/qpq" ) func main() { ctx := context.Background() // Connect to the server client, err := qpq.Connect(ctx, qpq.Options{ Addr: "127.0.0.1:7000", InsecureSkipVerify: true, // development only }) if err != nil { log.Fatal(err) } // Health check status, err := client.Health(ctx) if err != nil { log.Fatal(err) } fmt.Println("Server status:", status) // OPAQUE authentication if err := client.LoginStart(ctx, "alice", "secret"); err != nil { log.Fatal(err) } if err := client.LoginFinish(ctx); err != nil { log.Fatal(err) } // Resolve a peer peerKey, err := client.ResolveUser(ctx, "bob") if err != nil { log.Fatal(err) } // Create a DM channel channelID, err := client.CreateChannel(ctx, peerKey) if err != nil { log.Fatal(err) } fmt.Println("Channel:", channelID) // Send a message if err := client.Send(ctx, peerKey, []byte("Hello from Go!")); err != nil { log.Fatal(err) } // Send a disappearing message (1 hour TTL) if err := client.SendWithTTL(ctx, peerKey, []byte("This vanishes"), 3600); err != nil { log.Fatal(err) } // Receive messages msgs, err := client.Receive(ctx, peerKey) if err != nil { log.Fatal(err) } for _, m := range msgs { fmt.Println("Received:", string(m)) } } ``` ## API reference | Method | Description | |---|---| | `Connect(ctx, opts)` | Establish QUIC connection to server | | `Health(ctx)` | Server readiness probe | | `RegisterStart/Finish(ctx, user, pass)` | OPAQUE registration | | `LoginStart/Finish(ctx, user, pass)` | OPAQUE login | | `ResolveUser(ctx, username)` | Look up a user's identity key | | `CreateChannel(ctx, peerKey)` | Create a 1:1 DM channel | | `Send(ctx, recipientKey, payload)` | Send a message | | `SendWithTTL(ctx, recipientKey, payload, ttlSecs)` | Send a disappearing message | | `Receive(ctx, recipientKey)` | Fetch queued messages | | `ReceiveWait(ctx, recipientKey, timeoutMs)` | Long-poll for messages (default 5 s timeout) | | `DeleteAccount(ctx)` | Delete the authenticated account | ## Transport details - **Protocol:** QUIC with TLS 1.3 via `quic-go` - **ALPN:** `"capnp"` (same as the Rust client) - **Serialisation:** Cap'n Proto RPC over a single bidirectional stream - **Idle timeout:** 300 seconds - **Auth:** Session token stored in client, sent with every RPC via the `Auth` struct ## Connection options ```go type Options struct { Addr string // "host:port" CACertPath string // path to CA cert (DER format) InsecureSkipVerify bool // skip TLS verification (dev only!) Token string // pre-existing auth token (optional) } ``` ## Project structure ``` sdks/go/ ├── proto/ # Generated Cap'n Proto types from node.capnp ├── transport/ # QUIC transport layer (quic-go + TLS 1.3) ├── qpq/ # High-level client API (QpqClient) ├── cmd/example/ # Example CLI program ├── go.mod └── README.md ``` ## Running the example ```bash cd sdks/go/cmd/example go run main.go ``` ## Regenerating proto types If you modify `schemas/node.capnp`, regenerate the Go types: ```bash capnp compile -ogo sdks/go/proto/node.capnp ```