#!/bin/sh # shared helpers for the dev bootstrap scripts. source, don't run. : "${PDS_URL:?PDS_URL must be set}" PASSWORD="${PASSWORD:-password}" CREATED_AT="${CREATED_AT:-2025-09-22T11:14:35+01:00}" # fail LINE... -> every line on stderr, then abort fail() { printf '%s\n' "$@" >&2 exit 1 } # resolve_handle HANDLE → DID on stdout resolve_handle() { rh_resp=$(curl -sS -w '\n%{http_code}' \ "${PDS_URL}/xrpc/com.atproto.identity.resolveHandle?handle=$1") rh_body=$(printf '%s\n' "$rh_resp" | sed '$d') rh_status=$(printf '%s\n' "$rh_resp" | tail -n1) case "$rh_status" in 200) printf '%s\n' "$rh_body" | jq -er '.did' ;; 400) : ;; # not found — expected *) fail "resolveHandle $1: HTTP $rh_status: $rh_body" ;; esac } require_handle() { rq_did=$(resolve_handle "$1") [ -n "$rq_did" ] || fail "resolveHandle $1: the pds doesn't know that handle." \ ' init-accounts.sh creates the seed accounts, so it either never ran or failed.' printf '%s\n' "$rq_did" } # login DID/Handle → access JWT on stdout login() { curl -fsS -H "Content-Type: application/json" \ -d "{\"identifier\":\"$1\",\"password\":\"${PASSWORD}\"}" \ "${PDS_URL}/xrpc/com.atproto.server.createSession" \ | jq -er '.accessJwt' } # service_token JWT LXM [AUD] → service auth JWT for the knot, on stdout. # AUD defaults to the did:web of $KNOT_HOSTNAME. service_token() { st_aud=${3:-"did:web:$(printf '%s' "${KNOT_HOSTNAME:?KNOT_HOSTNAME must be set}" | sed 's/:/%3A/g')"} curl -fsS -H "Authorization: Bearer $1" \ "${PDS_URL}/xrpc/com.atproto.server.getServiceAuth?aud=${st_aud}&lxm=$2&exp=$(( $(date +%s) + 240 ))" \ | jq -er '.token' } # put_record at://DID/COLLECTION/RKEY RECORD_JSON # → the record's cid on stdout, for use in a strongRef (comment subject, replyTo). # callers that don't need it can ignore stdout. put_record() { case "$1" in at://did:*/*/?*) ;; *) fail "put_record: expected at://DID/COLLECTION/RKEY, got $1" ;; esac pr_rest=${1#at://} pr_did=${pr_rest%%/*} pr_rest=${pr_rest#*/} pr_collection=${pr_rest%%/*} pr_rkey=${pr_rest#*/} pr_record="$2" # one login per record — the dev PDS runs with rate limits disabled pr_jwt=$(login "$pr_did") pr_payload=$(jq -nc \ --arg repo "$pr_did" \ --arg collection "$pr_collection" \ --arg rkey "$pr_rkey" \ --argjson record "$pr_record" \ '{repo:$repo, collection:$collection, rkey:$rkey, record:$record}') pr_resp=$(curl -fsS \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${pr_jwt}" \ -d "$pr_payload" \ "${PDS_URL}/xrpc/com.atproto.repo.putRecord") printf '[record] %s\n' "$1" >&2 printf '%s\n' "$pr_resp" | jq -er '.cid' # -e: fail loudly if the cid is absent }