# Setting up WristCode This guide runs the gateway, connects your T3 Code machines to it, builds the watch app, and pairs your watch. It takes about an hour, most of it in Apple's developer portal. ## 1. Run the gateway The gateway is one container with one SQLite file in `/data`. Run it on a machine that is always on and can reach every T3 Code server. ```sh cd deploy cp .env.example .env # fill in after step 2, or leave the APNS_ lines empty for now mkdir data docker compose up -d --build ``` `compose.yml` builds the image from `gateway/` and listens on `127.0.0.1:8080`. Podman works the same with `podman compose`. The image runs as uid 1000, which needs to be able to write `data/`. The watch needs to reach the gateway over cellular, so put it behind a reverse proxy that serves HTTPS on a public name, such as `wristcode.example.com`, and forwards to port 8080. Check it with: ```sh curl https://wristcode.example.com/v1/health ``` Every route except health and pairing needs a device token, which only pairing hands out. ## 2. Set up notifications The gateway sends notifications through Apple's push service (APNs) with a key from your developer account. 1. In [Certificates, IDs & Profiles](https://developer.apple.com/account/resources/authkeys/list), make a key with Apple Push Notifications service enabled, and download its `.p8` file. 2. Put the file in `deploy/data/apns.p8`. 3. Fill in `deploy/.env`: the key's ID, your team ID, and `APNS_TOPIC`, which is the watch app's bundle ID from step 4. 4. Restart the gateway with `docker compose up -d`. Without these settings the gateway still works. It logs each notification instead of sending it. ## 3. Connect your T3 Code machines The gateway logs in to each T3 Code server with a one-time pairing credential. On the T3 Code machine: ```sh t3 auth pairing create --scope orchestration:read --scope orchestration:operate --label "WristCode gateway" ``` Then, within a few minutes, on the gateway machine: ```sh docker compose exec gateway wristcode host add https://t3-desktop.example.com --label "Desktop" ``` The gateway trades the credential for a 30 day session that can read and drive threads, and the credential stops working. The label is what the watch shows. A machine you can reach several ways can list fallbacks with `--alt-url`, preferred first. The gateway uses the first route that answers, so put a LAN or VPN address first and a public URL last: ```sh docker compose exec gateway wristcode host add http://desktop.lan:3773 \ --label "Desktop" --alt-url https://t3-desktop.example.com ``` `wristcode host list` shows each host and when its session expires. T3 sessions cannot be renewed, so a week before one expires the watch gets a notification. To renew, run `host add` again with a fresh credential, or let `scripts/renew-hosts.sh` do every host over SSH. Copy `scripts/hosts.conf.example` to `scripts/hosts.conf` and list your machines in it first. ## 4. Build the watch app You need a Mac with Xcode and [XcodeGen](https://github.com/yonaskolb/XcodeGen). 1. Copy `watch/Local.xcconfig.example` to `watch/Local.xcconfig`, which git ignores, and set your team ID and a bundle ID prefix you own, such as `com.example`. The watch app's bundle ID is `.wristcode.watchkitapp`, which is the `APNS_TOPIC` from step 2. 2. Generate the project and open it: ```sh cd watch xcodegen generate open WristCode.xcodeproj ``` 3. Run the `WristCode` scheme on your watch. Xcode registers the bundle IDs and the push capability for you with automatic signing. To install it without Xcode attached, upload a build to TestFlight with `watch/scripts/testflight.sh`. It needs an App Store Connect API key and an app record for `.wristcode`. [watch/README.md](../watch/README.md) has the details, plus a demo mode that runs without a gateway. ## 5. Pair your watch On the gateway machine: ```sh docker compose exec gateway wristcode pair ``` It prints a 6 digit code that works once, for 5 minutes. On the watch, enter your gateway's URL and the code. The watch then asks to send notifications. Allow it, and send a test notification from the gear button, then Notifications, to check the whole chain. `wristcode device list` shows paired watches, and `wristcode device revoke ` unpairs one.