Files
teahub/.gitea/workflows/wk-house.yml
T

59 lines
2.7 KiB
YAML

name: wk-house
# Assign well-known.online "house" handles to a pubkey (default: the factory key) via POST /house,
# signed with the factory nsec (SNAIL_KNOWN). The key never appears in logs.
on:
workflow_dispatch:
inputs:
names:
description: comma-separated names
required: true
og:
description: list in og.well-known.online (free inbox)
required: true
default: 'true'
pubkey:
description: owner pubkey (hex or npub); empty = the factory key
required: false
default: ''
jobs:
house:
runs-on: ubuntu-latest
steps:
- name: assign
env:
NSEC: ${{ secrets.SNAIL_KNOWN }}
NAMES: ${{ inputs.names }}
OG: ${{ inputs.og }}
OWNER: ${{ inputs.pubkey }}
run: |
mkdir -p /tmp/h && cd /tmp/h
npm init -y >/dev/null && npm i --silent @noble/curves@1.9.7 >/dev/null
cat > h.mjs <<'EOF'
import { schnorr } from '@noble/curves/secp256k1';
import { createHash } from 'node:crypto';
const CH = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
function nsecToHex(s) {
s = s.trim().toLowerCase();
if (/^[0-9a-f]{64}$/.test(s)) return s;
const d = [...s.slice(s.lastIndexOf('1') + 1)].map((c) => CH.indexOf(c)).slice(0, -6);
let acc = 0, bits = 0; const out = [];
for (const v of d) { acc = (acc << 5) | v; bits += 5; while (bits >= 8) { bits -= 8; out.push((acc >> bits) & 255); } }
return Buffer.from(out).toString('hex');
}
const sk = nsecToHex(process.env.NSEC);
const pk = Buffer.from(schnorr.getPublicKey(sk)).toString('hex');
console.log('signer', pk);
let i = 0;
for (const name of process.env.NAMES.split(',').map((s) => s.trim()).filter(Boolean)) {
const ev = { pubkey: pk, created_at: Math.floor(Date.now() / 1000), kind: 27235, content: String(i++),
tags: [['u', 'https://well-known.online/house'], ['method', 'POST'], ['name', name]] };
ev.id = createHash('sha256').update(JSON.stringify([0, ev.pubkey, ev.created_at, ev.kind, ev.tags, ev.content])).digest('hex');
ev.sig = Buffer.from(schnorr.sign(ev.id, sk)).toString('hex');
const body = { event: ev, og: process.env.OG === 'true', ...(process.env.OWNER ? { pubkey: process.env.OWNER } : {}) };
const r = await fetch('https://well-known.online/house', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) });
console.log(name, r.status, await r.text());
if (r.status >= 300) process.exitCode = 1;
}
EOF
node h.mjs