# quicproquo Go SDK

Go client library for the [quicproquo](https://github.com/nicholasgasior/quicproquo) E2E encrypted messenger.

## Prerequisites

- Go 1.21+
- A running quicproquo server

## Installation

```sh
go get quicproquo.dev/sdk/go
```

## Quick Start

```go
package main

import (
    "context"
    "fmt"

    "quicproquo.dev/sdk/go/qpq"
)

func main() {
    ctx := context.Background()

    // Connect to a local server (dev mode)
    client, err := qpq.Connect(ctx, qpq.Options{
        Addr:               "127.0.0.1:5001",
        InsecureSkipVerify: true,
    })
    if err != nil {
        panic(err)
    }
    defer client.Close()

    // Check server health
    status, err := client.Health(ctx)
    fmt.Println("Server:", status)

    // Set a session token (obtained via OPAQUE login)
    client.SetSessionToken(token)

    // Resolve a user
    key, err := client.ResolveUser(ctx, "alice")

    // Create a DM channel
    channelID, wasNew, err := client.CreateChannel(ctx, peerKey)

    // Send a message
    seq, err := client.Send(ctx, recipientKey, []byte("hello"))

    // Receive messages
    msgs, err := client.Receive(ctx, myKey)

    // Long-poll for messages (5s timeout)
    msgs, err = client.ReceiveWait(ctx, myKey, 5000)
}
```

## API Reference

### Connection

| Method | Description |
|---|---|
| `qpq.Connect(ctx, opts)` | Connect to a server, returns `*Client` |
| `client.Close()` | Disconnect |

### Authentication

| Method | Description |
|---|---|
| `client.SetSessionToken(token)` | Set a pre-existing OPAQUE session token |
| `client.RegisterStart(ctx, username, request)` | Start OPAQUE registration |
| `client.RegisterFinish(ctx, username, upload, identityKey)` | Complete OPAQUE registration |
| `client.LoginStart(ctx, username, request)` | Start OPAQUE login |
| `client.LoginFinish(ctx, username, finalization, identityKey)` | Complete OPAQUE login (stores token) |

### Messaging

| Method | Description |
|---|---|
| `client.ResolveUser(ctx, username)` | Look up a user's identity key |
| `client.CreateChannel(ctx, peerKey)` | Create a 1:1 DM channel |
| `client.Send(ctx, recipientKey, payload)` | Send a message |
| `client.SendWithTTL(ctx, recipientKey, payload, ttlSecs)` | Send a disappearing message |
| `client.Receive(ctx, recipientKey)` | Fetch queued messages |
| `client.ReceiveWait(ctx, recipientKey, timeoutMs)` | Long-poll for messages |
| `client.DeleteAccount(ctx)` | Permanently delete account |
| `client.Health(ctx)` | Check server health |

### OPAQUE Login

Full OPAQUE login requires a Go OPAQUE client library to generate the cryptographic
messages. The SDK provides the RPC wrappers (`RegisterStart`/`RegisterFinish`,
`LoginStart`/`LoginFinish`), but you must supply the OPAQUE protocol bytes.

For testing without OPAQUE, use `SetSessionToken` with a token obtained by other means.

## Structure

- `proto/node/` -- Generated Cap'n Proto Go types from `schemas/node.capnp`
- `transport/` -- QUIC + TLS 1.3 transport and Cap'n Proto RPC framing
- `qpq/` -- High-level client API (auth, messaging, channels)
- `cmd/example/` -- Example usage

## Regenerating Proto Types

```sh
capnp compile \
  -I "$(go env GOPATH)/pkg/mod/capnproto.org/go/capnp/v3@v3.1.0-alpha.2/std" \
  -ogo proto/node/node.capnp
```
