Files

4.5 KiB

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.

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:

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, 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:

t3 auth pairing create --scope orchestration:read --scope orchestration:operate --label "WristCode gateway"

Then, within a few minutes, on the gateway machine:

docker compose exec gateway wristcode host add https://t3-desktop.example.com <credential> --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:

docker compose exec gateway wristcode host add http://desktop.lan:3773 <credential> \
  --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.

  1. Use your own team and bundle IDs. The project ships with mine: the team GQJNM5YK2M and the bundle ID prefix org.gbrown. Replace both everywhere they appear under watch/, which grep -rn -e GQJNM5YK2M -e org.gbrown watch lists. They are in project.yml, the entitlements, the Info.plist files, DeviceStore.swift, the tests and scripts/testflight.sh. The watch app's bundle ID, <prefix>.wristcode.watchkitapp, is the APNS_TOPIC from step 2.

  2. Generate the project and open it:

    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 <prefix>.wristcode. watch/README.md has the details, plus a demo mode that runs without a gateway.

5. Pair your watch

On the gateway machine:

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 in place of the one filled in, 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 <name> unpairs one.