ops: assign well-known house handles, signed with the factory key (SNAIL_KNOWN)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVFi3wvLWKaEkpDw6eLnQC
This commit is contained in:
1 parent
b6d6432458
commit
e9627ecc8d
1 file changed
+58
@@ -0,0 +1,58 @@
|
||||
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
|
||||
Reference in new issue
Block a user