@orangecheck/vote-cli 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command, Option } from 'commander';
3
- import { hexDecode, utf8Decode, generateX25519KeyPair, hexEncode, utf8Encode } from '@orangecheck/lock-crypto';
4
- import { pollId, ballotId, tally, canonicalBytes, commit, revealId } from '@orangecheck/vote-core';
3
+ import { generateX25519KeyPair, hexEncode, utf8Encode, hexDecode, utf8Decode } from '@orangecheck/lock-crypto';
4
+ import { ballotId, pollId, verifyPoll, canonicalBytes, commit, revealId, verifyReveal, tally } from '@orangecheck/vote-core';
5
5
  import { schnorr } from '@noble/curves/secp256k1';
6
6
  import { sha256 } from '@noble/hashes/sha256';
7
7
  import { randomBytes, bytesToHex, hexToBytes } from '@noble/hashes/utils';
8
8
  import WebSocket from 'ws';
9
9
  import { createInterface } from 'readline/promises';
10
- import { unseal, seal } from '@orangecheck/lock-core';
10
+ import { seal, unseal } from '@orangecheck/lock-core';
11
11
 
12
12
  function nip01Id(pubkey, created_at, kind, tags, content) {
13
13
  const serialized = JSON.stringify([0, pubkey, created_at, kind, tags, content]);
@@ -64,9 +64,12 @@ function buildRevealEvent(reveal) {
64
64
  }
65
65
  var DEFAULT_RELAYS = [
66
66
  "wss://relay.damus.io",
67
- "wss://relay.nostr.band",
68
67
  "wss://nos.lol",
69
- "wss://relay.snort.social"
68
+ "wss://relay.snort.social",
69
+ // First-party family relay. Its write policy allows only family kinds with
70
+ // canonical OC d-tag prefixes, and it is always queried alongside public
71
+ // relays, never the only copy. See github.com/orangecheck/oc-relay-infra.
72
+ "wss://relay.ochk.io"
70
73
  ];
71
74
  async function queryRelays(filter, relays = DEFAULT_RELAYS, timeoutMs = 8e3) {
72
75
  const byId = /* @__PURE__ */ new Map();
@@ -133,25 +136,17 @@ async function queryRelays(filter, relays = DEFAULT_RELAYS, timeoutMs = 8e3) {
133
136
  );
134
137
  return Array.from(byId.values()).sort((a, b) => b.created_at - a.created_at);
135
138
  }
136
- async function fetchPollEvent(pollId3, relays) {
137
- const events = await queryRelays(
138
- { kinds: [30080], "#d": [`oc-vote:poll:${pollId3}`], limit: 1 },
139
- relays
140
- );
141
- return events[0] ?? null;
139
+ async function fetchPollEvents(pollId3, relays) {
140
+ return queryRelays({ kinds: [30080], "#d": [`oc-vote:poll:${pollId3}`] }, relays);
142
141
  }
143
142
  async function fetchBallotEvents(pollId3, relays) {
144
143
  return queryRelays({ kinds: [30081], "#t": [pollId3] }, relays);
145
144
  }
146
- async function fetchRevealEvent(pollId3, relays) {
147
- const events = await queryRelays(
148
- { kinds: [30082], "#d": [`oc-vote:reveal:${pollId3}`], limit: 1 },
149
- relays
150
- );
151
- return events[0] ?? null;
145
+ async function fetchRevealEvents(pollId3, relays) {
146
+ return queryRelays({ kinds: [30082], "#d": [`oc-vote:reveal:${pollId3}`] }, relays);
152
147
  }
153
148
  async function fetchRecentPolls(limit = 30, relays) {
154
- return queryRelays({ kinds: [30080], limit }, relays);
149
+ return queryRelays({ kinds: [30080], "#t": ["oc-vote-poll"], limit }, relays);
155
150
  }
156
151
  async function publishEvent(event, relays = DEFAULT_RELAYS, timeoutMs = 6e3) {
157
152
  return Promise.all(
@@ -336,6 +331,20 @@ async function runCreate(opts) {
336
331
  w(`
337
332
  `);
338
333
  }
334
+
335
+ // src/bip322.ts
336
+ async function bip322Verify(args) {
337
+ try {
338
+ const mod = await import('bip322-js');
339
+ const Verifier = mod.Verifier ?? mod.default?.Verifier;
340
+ if (!Verifier) return false;
341
+ return Verifier.verifySignature(args.address, args.message, args.signature);
342
+ } catch {
343
+ return false;
344
+ }
345
+ }
346
+
347
+ // src/commands/discover.ts
339
348
  async function runDiscover(opts) {
340
349
  const limit = opts.limit ?? 30;
341
350
  const events = await fetchRecentPolls(limit, opts.relays ?? DEFAULT_RELAYS);
@@ -349,6 +358,7 @@ async function runDiscover(opts) {
349
358
  if (seen.has(pid)) continue;
350
359
  seen.add(pid);
351
360
  if (opts.openOnly && Date.parse(poll.deadline) < Date.now()) continue;
361
+ if (!(await verifyPoll(poll, bip322Verify)).ok) continue;
352
362
  items.push({ poll_id: pid, poll, nostr_created_at: ev.created_at });
353
363
  } catch {
354
364
  }
@@ -402,6 +412,32 @@ function runGenRevealKey(opts) {
402
412
 
403
413
  `);
404
414
  }
415
+ function parse(ev) {
416
+ try {
417
+ return JSON.parse(ev.content);
418
+ } catch {
419
+ return null;
420
+ }
421
+ }
422
+ async function selectPoll(events, pid, verify) {
423
+ let unverified = null;
424
+ for (const ev of events) {
425
+ const p = parse(ev);
426
+ if (!p || p.kind !== "oc-vote/poll" || pollId(p) !== pid) continue;
427
+ if ((await verifyPoll(p, verify)).ok) return { poll: p, signatureValid: true };
428
+ unverified ??= p;
429
+ }
430
+ return unverified ? { poll: unverified, signatureValid: false } : null;
431
+ }
432
+ async function selectReveal(events, poll, verify) {
433
+ for (const ev of events) {
434
+ const r = parse(ev);
435
+ if (r && (await verifyReveal(r, poll, verify)).ok) return r;
436
+ }
437
+ return null;
438
+ }
439
+
440
+ // src/commands/reveal.ts
405
441
  async function runReveal(opts) {
406
442
  if (!/^[0-9a-f]{64}$/.test(opts.pollId)) {
407
443
  throw new Error("poll id must be 64 hex chars");
@@ -410,9 +446,9 @@ async function runReveal(opts) {
410
446
  throw new Error("reveal_sk must be 64 hex chars");
411
447
  }
412
448
  const relays = opts.relays ?? DEFAULT_RELAYS;
413
- const pollEvent = await fetchPollEvent(opts.pollId, relays);
414
- if (!pollEvent) throw new Error("poll not found on relays");
415
- const poll = JSON.parse(pollEvent.content);
449
+ const selected = await selectPoll(await fetchPollEvents(opts.pollId, relays), opts.pollId, bip322Verify);
450
+ if (!selected) throw new Error("poll not found on relays");
451
+ const poll = selected.poll;
416
452
  if (poll.mode !== "secret") throw new Error("poll is public-mode \u2014 no reveal needed");
417
453
  if (poll.creator !== opts.creator) {
418
454
  throw new Error(
@@ -424,7 +460,7 @@ async function runReveal(opts) {
424
460
  `poll deadline is ${poll.deadline} \u2014 pass --force to publish before deadline`
425
461
  );
426
462
  }
427
- const existing = await fetchRevealEvent(opts.pollId, relays);
463
+ const existing = await selectReveal(await fetchRevealEvents(opts.pollId, relays), poll, bip322Verify);
428
464
  if (existing && !opts.force) {
429
465
  throw new Error("a reveal event already exists for this poll (pass --force to replace)");
430
466
  }
@@ -481,22 +517,28 @@ async function runReveal(opts) {
481
517
 
482
518
  `);
483
519
  }
520
+
521
+ // src/commands/show.ts
484
522
  async function runShow(opts) {
485
523
  const pid = opts.pollId;
486
524
  if (!/^[0-9a-f]{64}$/.test(pid)) {
487
525
  throw new Error("poll id must be 64 hex chars");
488
526
  }
489
527
  const relays = opts.relays ?? DEFAULT_RELAYS;
490
- const [pollEvent, ballotEvents] = await Promise.all([
491
- fetchPollEvent(pid, relays),
528
+ const [pollEvents, ballotEvents] = await Promise.all([
529
+ fetchPollEvents(pid, relays),
492
530
  fetchBallotEvents(pid, relays)
493
531
  ]);
494
- if (!pollEvent) throw new Error("poll not found");
495
- const poll = JSON.parse(pollEvent.content);
496
- if (pollId(poll) !== pid) throw new Error("poll content mismatch");
532
+ const selected = await selectPoll(pollEvents, pid, bip322Verify);
533
+ if (!selected) throw new Error("poll not found");
534
+ const { poll, signatureValid } = selected;
497
535
  if (opts.json) {
498
536
  process.stdout.write(
499
- JSON.stringify({ poll, ballot_count: ballotEvents.length }, null, 2) + "\n"
537
+ JSON.stringify(
538
+ { poll, poll_signature_valid: signatureValid, ballot_count: ballotEvents.length },
539
+ null,
540
+ 2
541
+ ) + "\n"
500
542
  );
501
543
  return;
502
544
  }
@@ -506,7 +548,7 @@ async function runShow(opts) {
506
548
  `);
507
549
  w(` options: ${poll.options.map((o) => `${o.id} (${o.label})`).join(", ")}
508
550
  `);
509
- w(` creator: ${poll.creator}
551
+ w(` creator: ${poll.creator}${signatureValid ? "" : " (SIGNATURE DOES NOT VERIFY)"}
510
552
  `);
511
553
  w(` mode: ${poll.mode}
512
554
  `);
@@ -557,22 +599,45 @@ function buildLookup(source) {
557
599
  }
558
600
 
559
601
  // src/commands/tally.ts
602
+ async function unsealOption(ballot, revealSk) {
603
+ if (!ballot.secret) return null;
604
+ const result = await unseal({
605
+ envelope: ballot.secret.envelope,
606
+ device: { device_id: "reveal", secretKey: hexDecode(revealSk) },
607
+ skipSenderVerification: true
608
+ });
609
+ return utf8Decode(result.payload);
610
+ }
611
+ function computeTally(input) {
612
+ const { poll, reveal } = input;
613
+ return tally({
614
+ poll,
615
+ ballots: input.ballots,
616
+ utxosAt: input.utxosAt,
617
+ snapshotBlock: input.snapshotBlock,
618
+ ...input.tipHeight !== void 0 ? { tipHeight: input.tipHeight } : {},
619
+ ...input.verify ? { verify: input.verify } : { skipSignatures: true },
620
+ ...poll.mode === "secret" && reveal ? { unseal: (b) => unsealOption(b, reveal.reveal_sk) } : {}
621
+ });
622
+ }
560
623
  async function runTally(opts) {
561
624
  const { pollId: pid } = opts;
562
625
  if (!/^[0-9a-f]{64}$/.test(pid)) {
563
626
  throw new Error("poll id must be 64 hex chars");
564
627
  }
565
628
  const relays = opts.relays ?? DEFAULT_RELAYS;
566
- const [pollEvent, ballotEvents, revealEvent] = await Promise.all([
567
- fetchPollEvent(pid, relays),
629
+ const verify = opts.verify !== false ? bip322Verify : null;
630
+ const [pollEvents, ballotEvents, revealEvents] = await Promise.all([
631
+ fetchPollEvents(pid, relays),
568
632
  fetchBallotEvents(pid, relays),
569
- fetchRevealEvent(pid, relays)
633
+ fetchRevealEvents(pid, relays)
570
634
  ]);
571
- if (!pollEvent) throw new Error("poll not found on any relay");
572
- const poll = JSON.parse(pollEvent.content);
573
- if (pollId(poll) !== pid) {
574
- throw new Error("poll content does not match poll_id");
635
+ const selected = await selectPoll(pollEvents, pid, verify ?? bip322Verify);
636
+ if (!selected) throw new Error("poll not found on any relay");
637
+ if (verify && !selected.signatureValid) {
638
+ throw new Error("poll signature does not verify against its creator (SPEC \xA710.1)");
575
639
  }
640
+ const poll = selected.poll;
576
641
  const ballots = [];
577
642
  const seen = /* @__PURE__ */ new Set();
578
643
  for (const ev of ballotEvents) {
@@ -586,48 +651,21 @@ async function runTally(opts) {
586
651
  } catch {
587
652
  }
588
653
  }
589
- const reveal = revealEvent ? JSON.parse(revealEvent.content) : null;
654
+ const reveal = poll.mode === "secret" ? await selectReveal(revealEvents, poll, bip322Verify) : null;
590
655
  const source = mempoolSource(opts.mempoolBase);
591
656
  const utxosAt = buildLookup(source);
592
657
  let snapshot = poll.snapshot_block;
593
658
  if (typeof snapshot !== "number") {
594
659
  snapshot = opts.snapshotBlock ?? await source.fetchTipHeight();
595
660
  }
596
- let revealedOptions;
597
- if (poll.mode === "secret" && reveal) {
598
- revealedOptions = {};
599
- for (const b of ballots) {
600
- if (!b.secret) continue;
601
- try {
602
- const result2 = await unseal({
603
- envelope: b.secret.envelope,
604
- device: { device_id: "reveal", secretKey: hexDecode(reveal.reveal_sk) },
605
- skipSenderVerification: true
606
- });
607
- revealedOptions[b.voter] = utf8Decode(result2.payload);
608
- } catch {
609
- }
610
- }
611
- }
612
- const verify = opts.verify !== false;
613
- const verifyBip322 = verify ? async (address, message, signatureB64) => {
614
- try {
615
- const mod = await import('bip322-js');
616
- const Verifier = mod.Verifier ?? mod.default?.Verifier;
617
- if (!Verifier) return false;
618
- return Verifier.verifySignature(address, message, signatureB64);
619
- } catch {
620
- return false;
621
- }
622
- } : void 0;
623
- const result = await tally({
661
+ const result = await computeTally({
624
662
  poll,
625
663
  ballots,
664
+ reveal,
626
665
  utxosAt,
627
666
  snapshotBlock: snapshot,
628
- skipSignatures: !verify,
629
- ...verifyBip322 ? { verifyBip322 } : {},
630
- ...revealedOptions ? { revealedOptions } : {}
667
+ ...typeof poll.snapshot_block === "number" ? { tipHeight: await source.fetchTipHeight() } : {},
668
+ verify
631
669
  });
632
670
  const output = {
633
671
  poll_id: pid,
@@ -696,17 +734,16 @@ async function runVerify(opts) {
696
734
  throw new Error("poll id must be 64 hex chars");
697
735
  }
698
736
  const relays = opts.relays ?? DEFAULT_RELAYS;
699
- const [pollEvent, ballotEvents] = await Promise.all([
700
- fetchPollEvent(pid, relays),
737
+ const [pollEvents, ballotEvents] = await Promise.all([
738
+ fetchPollEvents(pid, relays),
701
739
  fetchBallotEvents(pid, relays)
702
740
  ]);
703
- if (!pollEvent) throw new Error("poll not found");
704
- const poll = JSON.parse(pollEvent.content);
705
- if (pollId(poll) !== pid) throw new Error("poll content mismatch");
741
+ const selected = await selectPoll(pollEvents, pid, bip322Verify);
742
+ if (!selected) throw new Error("poll not found");
706
743
  const mod = await import('bip322-js');
707
744
  const Verifier = mod.Verifier ?? mod.default?.Verifier;
708
745
  if (!Verifier) throw new Error("bip322 verifier unavailable");
709
- const pollSigOk = Verifier.verifySignature(poll.creator, pid, poll.sig.value);
746
+ const pollSigOk = selected.signatureValid;
710
747
  const ballots = [];
711
748
  const seen = /* @__PURE__ */ new Set();
712
749
  const ballotResults = [];
@@ -769,12 +806,13 @@ async function runVote(opts) {
769
806
  if (!/^[0-9a-f]{64}$/.test(opts.pollId)) {
770
807
  throw new Error("poll id must be 64 hex chars");
771
808
  }
772
- const event = await fetchPollEvent(opts.pollId, opts.relays ?? DEFAULT_RELAYS);
773
- if (!event) throw new Error("poll not found on relays");
774
- const poll = JSON.parse(event.content);
775
- if (pollId(poll) !== opts.pollId) {
776
- throw new Error("poll content does not match poll_id");
809
+ const events = await fetchPollEvents(opts.pollId, opts.relays ?? DEFAULT_RELAYS);
810
+ const selected = await selectPoll(events, opts.pollId, bip322Verify);
811
+ if (!selected) throw new Error("poll not found on relays");
812
+ if (!selected.signatureValid) {
813
+ throw new Error("poll signature does not verify against its creator (SPEC \xA710.1)");
777
814
  }
815
+ const poll = selected.poll;
778
816
  if (poll.mode === "public" && !poll.options.some((o) => o.id === opts.option)) {
779
817
  throw new Error(`option "${opts.option}" not in poll options (${poll.options.map((o) => o.id).join(", ")})`);
780
818
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/events.ts","../src/nostr.ts","../src/sig.ts","../src/commands/create.ts","../src/commands/discover.ts","../src/commands/gen-reveal-key.ts","../src/commands/reveal.ts","../src/commands/show.ts","../src/utxos.ts","../src/commands/tally.ts","../src/commands/verify.ts","../src/commands/vote.ts","../src/cli.ts"],"names":["pollId","canonicalBytes","computePollId","generateX25519KeyPair","hexEncode","revealId","ballotId","result","computeBallotId"],"mappings":"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","file":"cli.js","sourcesContent":["// Build NIP-01 events for oc-vote kinds 30080/30081/30082.\n// Mirror of oc-vote-web/src/lib/vote/events.ts but node-safe (uses @noble only).\n\nimport { schnorr } from '@noble/curves/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, hexToBytes, randomBytes } from '@noble/hashes/utils';\n\nimport { canonicalBytes, ballotId, pollId, revealId } from '@orangecheck/vote-core';\nimport type { Ballot, Poll, Reveal } from '@orangecheck/vote-core';\n\nimport type { NostrEvent } from './nostr.js';\n\nfunction nip01Id(pubkey: string, created_at: number, kind: number, tags: string[][], content: string): string {\n const serialized = JSON.stringify([0, pubkey, created_at, kind, tags, content]);\n return bytesToHex(sha256(new TextEncoder().encode(serialized)));\n}\n\nfunction sign(kind: number, tags: string[][], content: string): NostrEvent {\n const sk = randomBytes(32);\n const pubkey = bytesToHex(schnorr.getPublicKey(sk));\n const created_at = Math.floor(Date.now() / 1000);\n const id = nip01Id(pubkey, created_at, kind, tags, content);\n const sig = bytesToHex(schnorr.sign(hexToBytes(id), sk));\n return { id, pubkey, created_at, kind, tags, content, sig };\n}\n\nexport function buildPollEvent(poll: Poll): NostrEvent {\n const pid = pollId(poll);\n const content = canonicalBytes(poll).trimEnd();\n const snapshot =\n typeof poll.snapshot_block === 'number' ? String(poll.snapshot_block) : poll.snapshot_block;\n// NIP-12 relays index SINGLE-LETTER tag names only. The multi-letter\n// `poll_id` / `voter` / `creator` tags below are readable diagnostics and are\n// NOT queryable — a `#poll_id` filter matches nothing on a conforming relay.\n// The `t` tags are what make these events findable, and for ballots they are\n// the ONLY way to enumerate a poll: a ballot's d-tag embeds the voter, tag\n// filters are exact-match, and enumerating voters is the point of the query.\n// Kept in sync with oc-vote-web/src/lib/vote/events.ts and normative in\n// oc-vote-protocol SPEC §3.4/§3.6.\n return sign(30080, [\n ['d', `oc-vote:poll:${pid}`],\n ['t', pid],\n ['t', 'oc-vote-poll'],\n ['t', poll.creator],\n ['poll_id', pid],\n ['creator', poll.creator],\n ['deadline', poll.deadline],\n ['snapshot', snapshot],\n ['mode', poll.mode],\n ], content);\n}\n\nexport function buildBallotEvent(ballot: Ballot): NostrEvent {\n const bid = ballotId(ballot);\n const content = canonicalBytes(ballot).trimEnd();\n return sign(30081, [\n ['d', `oc-vote:ballot:${ballot.poll_id}:${ballot.voter}`],\n // `t` = poll_id is the only path to \"every ballot in this poll\".\n ['t', ballot.poll_id],\n ['t', 'oc-vote-ballot'],\n ['t', ballot.voter],\n ['poll_id', ballot.poll_id],\n ['voter', ballot.voter],\n ['ballot_id', bid],\n ], content);\n}\n\nexport function buildRevealEvent(reveal: Reveal): NostrEvent {\n const rid = revealId(reveal);\n const content = canonicalBytes(reveal).trimEnd();\n return sign(30082, [\n ['d', `oc-vote:reveal:${reveal.poll_id}`],\n ['t', reveal.poll_id],\n ['t', 'oc-vote-reveal'],\n ['poll_id', reveal.poll_id],\n ['reveal_id', rid],\n ], content);\n}\n","// Minimal NIP-01 WebSocket client for oc-vote. Node-native via the `ws` package.\n\nimport WebSocket from 'ws';\n\nexport interface NostrEvent {\n id: string;\n kind: number;\n pubkey: string;\n created_at: number;\n content: string;\n tags: string[][];\n sig: string;\n}\n\nexport interface Filter {\n kinds?: number[];\n '#d'?: string[];\n /** NIP-12 indexable single-letter tag filter. */\n '#t'?: string[];\n limit?: number;\n}\n\nexport const DEFAULT_RELAYS = [\n 'wss://relay.damus.io',\n 'wss://relay.nostr.band',\n 'wss://nos.lol',\n 'wss://relay.snort.social',\n];\n\nexport async function queryRelays(\n filter: Filter,\n relays: string[] = DEFAULT_RELAYS,\n timeoutMs = 8000\n): Promise<NostrEvent[]> {\n const byId = new Map<string, NostrEvent>();\n await Promise.all(\n relays.map(\n (url) =>\n new Promise<void>((resolve) => {\n const subId = 'ocvcli-' + Math.random().toString(36).slice(2, 10);\n let settled = false;\n let ws: WebSocket | null = null;\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n try {\n ws?.close();\n } catch {}\n resolve();\n }, timeoutMs);\n try {\n ws = new WebSocket(url);\n ws.on('open', () => ws?.send(JSON.stringify(['REQ', subId, filter])));\n ws.on('message', (raw: WebSocket.RawData) => {\n try {\n const arr = JSON.parse(raw.toString()) as unknown[];\n if (!Array.isArray(arr) || arr.length === 0) return;\n if (arr[0] === 'EVENT' && arr[1] === subId) {\n const event = arr[2] as NostrEvent;\n if (event?.id) byId.set(event.id, event);\n } else if (arr[0] === 'EOSE' && arr[1] === subId) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n ws?.send(JSON.stringify(['CLOSE', subId]));\n ws?.close();\n } catch {}\n resolve();\n }\n } catch {\n // ignore parse errors\n }\n });\n ws.on('error', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve();\n });\n ws.on('close', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve();\n });\n } catch {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve();\n }\n }\n })\n )\n );\n return Array.from(byId.values()).sort((a, b) => b.created_at - a.created_at);\n}\n\nexport async function fetchPollEvent(pollId: string, relays?: string[]) {\n const events = await queryRelays(\n { kinds: [30080], '#d': [`oc-vote:poll:${pollId}`], limit: 1 },\n relays\n );\n return events[0] ?? null;\n}\n\n/**\n * Every ballot in a poll.\n *\n * `#t`, not `#poll_id`: relays index single-letter tag names only, so the old\n * filter matched nothing and every tally saw zero ballots. Callers must still\n * check each parsed ballot's `poll_id` — `t` is a shared namespace on these\n * events (poll id, family marker, voter address).\n */\nexport async function fetchBallotEvents(pollId: string, relays?: string[]) {\n return queryRelays({ kinds: [30081], '#t': [pollId] }, relays);\n}\n\nexport async function fetchRevealEvent(pollId: string, relays?: string[]) {\n const events = await queryRelays(\n { kinds: [30082], '#d': [`oc-vote:reveal:${pollId}`], limit: 1 },\n relays\n );\n return events[0] ?? null;\n}\n\nexport async function fetchRecentPolls(limit = 30, relays?: string[]) {\n return queryRelays({ kinds: [30080], limit }, relays);\n}\n\n// ── Publish ────────────────────────────────────────────────────────────────\n\nexport interface PublishResult {\n relay: string;\n ok: boolean;\n reason?: string;\n}\n\nexport async function publishEvent(\n event: NostrEvent,\n relays: string[] = DEFAULT_RELAYS,\n timeoutMs = 6000\n): Promise<PublishResult[]> {\n return Promise.all(\n relays.map(\n (url) =>\n new Promise<PublishResult>((resolve) => {\n let settled = false;\n let ws: WebSocket | null = null;\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n try {\n ws?.close();\n } catch {}\n resolve({ relay: url, ok: false, reason: 'timeout' });\n }, timeoutMs);\n try {\n ws = new WebSocket(url);\n ws.on('open', () => ws?.send(JSON.stringify(['EVENT', event])));\n ws.on('message', (raw: WebSocket.RawData) => {\n try {\n const arr = JSON.parse(raw.toString()) as unknown[];\n if (Array.isArray(arr) && arr[0] === 'OK' && arr[1] === event.id) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n ws?.close();\n } catch {}\n const ok = arr[2] === true;\n const reason =\n typeof arr[3] === 'string' ? arr[3] : undefined;\n resolve({\n relay: url,\n ok,\n ...(reason ? { reason } : {}),\n });\n }\n } catch {}\n });\n ws.on('error', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ relay: url, ok: false, reason: 'ws_error' });\n });\n ws.on('close', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ relay: url, ok: false, reason: 'closed_early' });\n });\n } catch (err) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({\n relay: url,\n ok: false,\n reason: err instanceof Error ? err.message : 'unknown',\n });\n }\n })\n )\n );\n}\n","// Interactive signature prompt.\n// The CLI never holds a Bitcoin private key. To sign a poll / ballot / reveal,\n// the caller either passes --sig <base64> on the command line, or we compute\n// the canonical id, print it, and ask the user to sign elsewhere (UniSat,\n// Xverse, Leather, sparrow-wallet, any BIP-322 signer) and paste back.\n\nimport { createInterface } from 'node:readline/promises';\n\nexport async function promptForSignature(\n address: string,\n id: string,\n preset?: string\n): Promise<string> {\n if (preset && preset.trim()) return preset.trim();\n\n process.stderr.write(\n `\\n sign with BIP-322, address ${address}\\n` +\n ` message: ${id}\\n\\n` +\n ` paste the base64 signature and press enter:\\n > `\n );\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n const sig = (await rl.question('')).trim();\n rl.close();\n if (!sig) throw new Error('empty signature');\n return sig;\n}\n","// oc-vote create — build + sign + publish a poll.\n\nimport { hexEncode } from '@orangecheck/lock-crypto';\nimport { generateX25519KeyPair } from '@orangecheck/lock-crypto';\nimport { canonicalBytes, pollId } from '@orangecheck/vote-core';\nimport type { Poll, PollMode, Tiebreak, WeightMode } from '@orangecheck/vote-core';\n\nimport { buildPollEvent } from '../events.js';\nimport { DEFAULT_RELAYS, publishEvent } from '../nostr.js';\nimport { promptForSignature } from '../sig.js';\n\nexport interface CreateOptions {\n creator: string;\n question: string;\n options: { id: string; label: string }[];\n deadline: string;\n snapshotBlock: number | 'deadline';\n weightMode: WeightMode;\n capDays?: number;\n minSats: number;\n minDays: number;\n tiebreak: Tiebreak;\n mode: PollMode;\n notes?: string;\n sig?: string;\n relays?: string[];\n dryRun?: boolean;\n json?: boolean;\n}\n\nexport async function runCreate(opts: CreateOptions): Promise<void> {\n if (!/^(bc1|1|3)[0-9a-zA-Z]+$/.test(opts.creator)) {\n throw new Error(`creator does not look like a Bitcoin mainnet address: ${opts.creator}`);\n }\n if (opts.options.length < 2) throw new Error('need at least 2 options');\n if (new Set(opts.options.map((o) => o.id)).size !== opts.options.length) {\n throw new Error('option ids must be unique');\n }\n\n // Secret mode: generate an X25519 reveal keypair.\n let reveal_pk: string | null = null;\n let reveal_sk: string | null = null;\n if (opts.mode === 'secret') {\n const kp = generateX25519KeyPair();\n reveal_sk = hexEncode(kp.secret);\n reveal_pk = hexEncode(kp.public);\n }\n\n const draft: Poll = {\n v: 0,\n kind: 'oc-vote/poll',\n creator: opts.creator,\n question: opts.question,\n options: opts.options,\n deadline: opts.deadline,\n snapshot_block: opts.snapshotBlock,\n weight_mode: opts.weightMode,\n weight_params:\n opts.weightMode === 'sats_days' && opts.capDays\n ? { cap_days: opts.capDays }\n : null,\n min_sats: opts.minSats,\n min_days: opts.minDays,\n mode: opts.mode,\n reveal_pk,\n tiebreak: opts.tiebreak,\n notes: opts.notes ?? null,\n created_at: new Date().toISOString().replace(/\\.\\d+Z$/, 'Z'),\n sig: { alg: 'bip322', pubkey: opts.creator, value: '' },\n };\n\n const pid = pollId(draft);\n\n if (opts.dryRun) {\n const out = {\n poll_id: pid,\n poll: draft,\n ...(reveal_sk ? { reveal_sk, reveal_pk } : {}),\n };\n process.stdout.write(JSON.stringify(out, null, 2) + '\\n');\n return;\n }\n\n const sigValue = await promptForSignature(opts.creator, pid, opts.sig);\n draft.sig.value = sigValue;\n\n const event = buildPollEvent(draft);\n const results = await publishEvent(event, opts.relays ?? DEFAULT_RELAYS);\n const okCount = results.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n poll_id: pid,\n published: okCount,\n total: results.length,\n relays: results,\n poll: draft,\n ...(reveal_sk ? { reveal_sk, reveal_pk } : {}),\n url: `https://vote.ochk.io/p/${pid}`,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n poll_id: ${pid}\\n`);\n w(` published: ${okCount}/${results.length} relays\\n`);\n for (const r of results) {\n w(` ${r.ok ? '✓' : '✗'} ${r.relay}${r.reason ? ` (${r.reason})` : ''}\\n`);\n }\n w(` url: https://vote.ochk.io/p/${pid}\\n`);\n if (reveal_sk) {\n w(`\\n SECRET MODE — save these or the poll is abandoned at deadline:\\n`);\n w(` reveal_pk: ${reveal_pk}\\n`);\n w(` reveal_sk: ${reveal_sk}\\n`);\n w(` to publish the reveal:\\n`);\n w(` oc-vote reveal --poll ${pid} --reveal-sk ${reveal_sk} --creator ${opts.creator}\\n`);\n }\n w(`\\n canonical bytes:\\n`);\n w(canonicalBytes({ ...draft, sig: { ...draft.sig, value: '' } }));\n w(`\\n`);\n}\n","// oc-vote discover — list recent polls across the default relay set.\n\nimport { pollId as computePollId } from '@orangecheck/vote-core';\nimport type { Poll } from '@orangecheck/vote-core';\n\nimport { DEFAULT_RELAYS, fetchRecentPolls } from '../nostr.js';\n\nexport interface DiscoverOptions {\n limit?: number;\n relays?: string[];\n json?: boolean;\n openOnly?: boolean;\n}\n\nexport async function runDiscover(opts: DiscoverOptions): Promise<void> {\n const limit = opts.limit ?? 30;\n const events = await fetchRecentPolls(limit, opts.relays ?? DEFAULT_RELAYS);\n\n interface Item {\n poll_id: string;\n poll: Poll;\n nostr_created_at: number;\n }\n const seen = new Set<string>();\n const items: Item[] = [];\n for (const ev of events) {\n try {\n const poll = JSON.parse(ev.content) as Poll;\n if (poll.kind !== 'oc-vote/poll' || poll.v !== 0) continue;\n const pid = computePollId(poll);\n if (seen.has(pid)) continue;\n seen.add(pid);\n if (opts.openOnly && Date.parse(poll.deadline) < Date.now()) continue;\n items.push({ poll_id: pid, poll, nostr_created_at: ev.created_at });\n } catch {}\n }\n items.sort((a, b) => b.nostr_created_at - a.nostr_created_at);\n\n if (opts.json) {\n process.stdout.write(JSON.stringify(items, null, 2) + '\\n');\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n discovered ${items.length} poll(s) across ${(opts.relays ?? DEFAULT_RELAYS).length} relays\\n\\n`);\n for (const { poll, poll_id, nostr_created_at } of items) {\n const isPast = Date.parse(poll.deadline) < Date.now();\n const age = Math.max(0, Math.floor((Date.now() / 1000 - nostr_created_at) / 60));\n const ageStr =\n age < 1\n ? 'just now'\n : age < 60\n ? `${age}m`\n : age < 60 * 24\n ? `${Math.floor(age / 60)}h`\n : `${Math.floor(age / (60 * 24))}d`;\n w(` [${isPast ? 'closed' : ' open '}] [${poll.weight_mode.padEnd(15)}] ${ageStr.padStart(5)} · ${poll.question}\\n`);\n w(` https://vote.ochk.io/p/${poll_id}\\n`);\n }\n if (items.length === 0) {\n w(` No polls found. Try: oc-vote create\\n`);\n }\n w(`\\n`);\n}\n","// oc-vote gen-reveal-key — print a fresh X25519 keypair for secret-mode\n// polls. Use this to pre-generate a key pair you pin into a --reveal-pk\n// flag, then publish the matching --reveal-sk at deadline.\n//\n// The standard `oc-vote create --mode secret` already generates one\n// automatically; this command exists for flows that want the key in hand\n// before composing the poll (e.g. DAO trustee ceremonies).\n\nimport { generateX25519KeyPair, hexEncode } from '@orangecheck/lock-crypto';\n\nexport interface GenRevealKeyOptions {\n json?: boolean;\n}\n\nexport function runGenRevealKey(opts: GenRevealKeyOptions): void {\n const kp = generateX25519KeyPair();\n const reveal_sk = hexEncode(kp.secret);\n const reveal_pk = hexEncode(kp.public);\n\n if (opts.json) {\n process.stdout.write(JSON.stringify({ reveal_sk, reveal_pk }, null, 2) + '\\n');\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n reveal_pk: ${reveal_pk}\\n`);\n w(` reveal_sk: ${reveal_sk}\\n\\n`);\n w(` pass reveal_pk to --reveal-pk at poll creation.\\n`);\n w(` keep reveal_sk offline until deadline; publish via:\\n`);\n w(` oc-vote reveal --poll <id> --reveal-sk ${reveal_sk} --creator <addr>\\n\\n`);\n}\n","// oc-vote reveal — publish the reveal event for a secret-mode poll.\n\nimport { revealId } from '@orangecheck/vote-core';\nimport type { Poll, Reveal } from '@orangecheck/vote-core';\n\nimport { buildRevealEvent } from '../events.js';\nimport { DEFAULT_RELAYS, fetchPollEvent, fetchRevealEvent, publishEvent } from '../nostr.js';\nimport { promptForSignature } from '../sig.js';\n\nexport interface RevealOptions {\n pollId: string;\n revealSk: string;\n creator: string;\n sig?: string;\n relays?: string[];\n force?: boolean;\n dryRun?: boolean;\n json?: boolean;\n}\n\nexport async function runReveal(opts: RevealOptions): Promise<void> {\n if (!/^[0-9a-f]{64}$/.test(opts.pollId)) {\n throw new Error('poll id must be 64 hex chars');\n }\n if (!/^[0-9a-f]{64}$/.test(opts.revealSk)) {\n throw new Error('reveal_sk must be 64 hex chars');\n }\n\n const relays = opts.relays ?? DEFAULT_RELAYS;\n const pollEvent = await fetchPollEvent(opts.pollId, relays);\n if (!pollEvent) throw new Error('poll not found on relays');\n const poll = JSON.parse(pollEvent.content) as Poll;\n if (poll.mode !== 'secret') throw new Error('poll is public-mode — no reveal needed');\n if (poll.creator !== opts.creator) {\n throw new Error(\n `poll creator is ${poll.creator} but you provided ${opts.creator}`\n );\n }\n if (Date.parse(poll.deadline) > Date.now() && !opts.force) {\n throw new Error(\n `poll deadline is ${poll.deadline} — pass --force to publish before deadline`\n );\n }\n\n const existing = await fetchRevealEvent(opts.pollId, relays);\n if (existing && !opts.force) {\n throw new Error('a reveal event already exists for this poll (pass --force to replace)');\n }\n\n const draft: Reveal = {\n v: 0,\n kind: 'oc-vote/reveal',\n poll_id: opts.pollId,\n reveal_sk: opts.revealSk,\n revealed_at: new Date().toISOString().replace(/\\.\\d+Z$/, 'Z'),\n sig: { alg: 'bip322', pubkey: opts.creator, value: '' },\n };\n\n const rid = revealId(draft);\n\n if (opts.dryRun) {\n process.stdout.write(JSON.stringify({ reveal_id: rid, reveal: draft }, null, 2) + '\\n');\n return;\n }\n\n const sigValue = await promptForSignature(opts.creator, rid, opts.sig);\n draft.sig.value = sigValue;\n\n const event = buildRevealEvent(draft);\n const results = await publishEvent(event, relays);\n const okCount = results.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n reveal_id: rid,\n published: okCount,\n total: results.length,\n relays: results,\n reveal: draft,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n reveal_id: ${rid}\\n`);\n w(` poll: ${poll.question}\\n`);\n w(` revealed: ${draft.revealed_at}\\n`);\n w(` published: ${okCount}/${results.length} relays\\n`);\n for (const r of results) {\n w(` ${r.ok ? '✓' : '✗'} ${r.relay}${r.reason ? ` (${r.reason})` : ''}\\n`);\n }\n w(`\\n tally with: oc-vote tally ${opts.pollId}\\n\\n`);\n}\n","// oc-vote show <poll_id> — print the poll metadata + ballot count.\n\nimport { pollId as computePollId, type Poll } from '@orangecheck/vote-core';\n\nimport { DEFAULT_RELAYS, fetchBallotEvents, fetchPollEvent } from '../nostr.js';\n\nexport interface ShowOptions {\n pollId: string;\n relays?: string[];\n json?: boolean;\n}\n\nexport async function runShow(opts: ShowOptions): Promise<void> {\n const pid = opts.pollId;\n if (!/^[0-9a-f]{64}$/.test(pid)) {\n throw new Error('poll id must be 64 hex chars');\n }\n const relays = opts.relays ?? DEFAULT_RELAYS;\n\n const [pollEvent, ballotEvents] = await Promise.all([\n fetchPollEvent(pid, relays),\n fetchBallotEvents(pid, relays),\n ]);\n if (!pollEvent) throw new Error('poll not found');\n const poll = JSON.parse(pollEvent.content) as Poll;\n if (computePollId(poll) !== pid) throw new Error('poll content mismatch');\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify({ poll, ballot_count: ballotEvents.length }, null, 2) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n question: ${poll.question}\\n`);\n w(` options: ${poll.options.map((o) => `${o.id} (${o.label})`).join(', ')}\\n`);\n w(` creator: ${poll.creator}\\n`);\n w(` mode: ${poll.mode}\\n`);\n w(` weight: ${poll.weight_mode}${poll.weight_mode === 'sats_days' && poll.weight_params?.cap_days ? ` (cap ${poll.weight_params.cap_days}d)` : ''}\\n`);\n w(` threshold: ${poll.min_sats} sat / ${poll.min_days} d\\n`);\n w(` tiebreak: ${poll.tiebreak}\\n`);\n w(` deadline: ${poll.deadline}\\n`);\n w(` snapshot: ${poll.snapshot_block}\\n`);\n w(` ballots: ${ballotEvents.length}\\n`);\n if (poll.notes) w(` notes: ${poll.notes}\\n`);\n w(`\\n`);\n}\n","// UTXO snapshot source for the CLI. Defaults to mempool.space; swappable via\n// --mempool-base flag.\n\nimport type { Utxo, UtxoLookup } from '@orangecheck/vote-core';\n\ninterface MempoolUtxo {\n txid: string;\n vout: number;\n value: number;\n status: { confirmed: boolean; block_height?: number; block_time?: number };\n}\n\nexport interface UtxoSource {\n fetchUtxos(address: string): Promise<Utxo[]>;\n fetchTipHeight(): Promise<number>;\n}\n\nexport function mempoolSource(base = 'https://mempool.space/api'): UtxoSource {\n return {\n async fetchUtxos(address) {\n const res = await fetch(`${base}/address/${address}/utxo`, {\n headers: { accept: 'application/json' },\n });\n if (!res.ok) throw new Error(`mempool utxo ${res.status}`);\n const data = (await res.json()) as MempoolUtxo[];\n return data\n .filter((u) => u.status.confirmed && typeof u.status.block_height === 'number')\n .map((u) => ({\n value: u.value,\n confirmed_height: u.status.block_height as number,\n }));\n },\n async fetchTipHeight() {\n const res = await fetch(`${base}/blocks/tip/height`);\n if (!res.ok) throw new Error(`tip ${res.status}`);\n return Number.parseInt((await res.text()).trim(), 10);\n },\n };\n}\n\nexport function buildLookup(source: UtxoSource): UtxoLookup {\n return async (addr: string, snapshot: number): Promise<Utxo[]> => {\n const all = await source.fetchUtxos(addr);\n return all.filter((u) => u.confirmed_height <= snapshot);\n };\n}\n","// oc-vote tally <poll_id>\n\nimport { hexDecode, utf8Decode } from '@orangecheck/lock-crypto';\nimport { unseal } from '@orangecheck/lock-core';\nimport {\n ballotId,\n pollId as computePollId,\n tally,\n type Ballot,\n type Poll,\n type Reveal,\n} from '@orangecheck/vote-core';\n\nimport {\n DEFAULT_RELAYS,\n fetchBallotEvents,\n fetchPollEvent,\n fetchRevealEvent,\n} from '../nostr.js';\nimport { buildLookup, mempoolSource } from '../utxos.js';\n\nexport interface TallyOptions {\n pollId: string;\n relays?: string[];\n mempoolBase?: string;\n json?: boolean;\n verify?: boolean;\n snapshotBlock?: number;\n}\n\nexport async function runTally(opts: TallyOptions): Promise<void> {\n const { pollId: pid } = opts;\n if (!/^[0-9a-f]{64}$/.test(pid)) {\n throw new Error('poll id must be 64 hex chars');\n }\n const relays = opts.relays ?? DEFAULT_RELAYS;\n\n const [pollEvent, ballotEvents, revealEvent] = await Promise.all([\n fetchPollEvent(pid, relays),\n fetchBallotEvents(pid, relays),\n fetchRevealEvent(pid, relays),\n ]);\n\n if (!pollEvent) throw new Error('poll not found on any relay');\n const poll = JSON.parse(pollEvent.content) as Poll;\n if (computePollId(poll) !== pid) {\n throw new Error('poll content does not match poll_id');\n }\n\n const ballots: Ballot[] = [];\n const seen = new Set<string>();\n for (const ev of ballotEvents) {\n try {\n const b = JSON.parse(ev.content) as Ballot;\n if (b.poll_id !== pid) continue;\n const id = ballotId(b);\n if (seen.has(id)) continue;\n seen.add(id);\n ballots.push(b);\n } catch {\n // skip malformed\n }\n }\n\n const reveal: Reveal | null = revealEvent\n ? (JSON.parse(revealEvent.content) as Reveal)\n : null;\n\n // Resolve snapshot\n const source = mempoolSource(opts.mempoolBase);\n const utxosAt = buildLookup(source);\n let snapshot = poll.snapshot_block;\n if (typeof snapshot !== 'number') {\n snapshot = opts.snapshotBlock ?? (await source.fetchTipHeight());\n }\n\n // Unseal secret-mode ballots if a reveal is published\n let revealedOptions: Record<string, string> | undefined;\n if (poll.mode === 'secret' && reveal) {\n revealedOptions = {};\n for (const b of ballots) {\n if (!b.secret) continue;\n try {\n const result = await unseal({\n envelope: b.secret.envelope as unknown as Parameters<typeof unseal>[0]['envelope'],\n device: { device_id: 'reveal', secretKey: hexDecode(reveal.reveal_sk) },\n skipSenderVerification: true,\n });\n revealedOptions[b.voter] = utf8Decode(result.payload);\n } catch {\n // skip: bad envelope or wrong reveal key\n }\n }\n }\n\n const verify = opts.verify !== false;\n const verifyBip322 = verify\n ? async (address: string, message: string, signatureB64: string) => {\n try {\n const mod = (await import('bip322-js')) as unknown as {\n Verifier?: { verifySignature(a: string, m: string, s: string): boolean };\n default?: {\n Verifier?: {\n verifySignature(a: string, m: string, s: string): boolean;\n };\n };\n };\n const Verifier = mod.Verifier ?? mod.default?.Verifier;\n if (!Verifier) return false;\n return Verifier.verifySignature(address, message, signatureB64);\n } catch {\n return false;\n }\n }\n : undefined;\n\n // Pass `snapshotBlock` rather than mutating poll.snapshot_block: the\n // poll's canonical bytes (and therefore pollId) include snapshot_block\n // verbatim, and mutating it would invalidate every ballot's poll_id.\n const result = await tally({\n poll,\n ballots,\n utxosAt,\n snapshotBlock: snapshot,\n skipSignatures: !verify,\n ...(verifyBip322 ? { verifyBip322 } : {}),\n ...(revealedOptions ? { revealedOptions } : {}),\n });\n\n const output = {\n poll_id: pid,\n question: poll.question,\n creator: poll.creator,\n mode: poll.mode,\n weight_mode: poll.weight_mode,\n deadline: poll.deadline,\n ballot_count: ballots.length,\n reveal_present: reveal != null,\n ...result,\n };\n\n if (opts.json) {\n process.stdout.write(JSON.stringify(output, null, 2) + '\\n');\n return;\n }\n\n // Human-readable\n const w = (s: string) => process.stdout.write(s);\n w(`\\n poll: ${poll.question}\\n`);\n w(` poll_id: ${pid}\\n`);\n w(` creator: ${poll.creator}\\n`);\n w(` mode: ${poll.mode}${poll.mode === 'secret' ? (reveal ? ' (revealed)' : ' (awaiting reveal)') : ''}\\n`);\n w(` weight: ${poll.weight_mode}\\n`);\n w(` threshold: ${poll.min_sats} sat / ${poll.min_days} d\\n`);\n w(` deadline: ${poll.deadline}\\n`);\n w(` snapshot: ${snapshot}\\n`);\n w(` ballots: ${ballots.length}\\n`);\n w(`\\n`);\n\n if (result.state === 'awaiting_reveal') {\n w(` STATE: awaiting reveal — secret-mode poll, creator has not yet published reveal_sk\\n\\n`);\n return;\n }\n\n w(` STATE: tallied\\n`);\n w(` turnout: ${result.turnout.voters} voters, weight ${result.turnout.weight.toLocaleString()}\\n\\n`);\n\n // Sort options by poll.options order\n const total = result.turnout.weight;\n const maxLabel = Math.max(...poll.options.map((o) => o.label.length));\n for (const opt of poll.options) {\n const wgt = result.tallies[opt.id] ?? 0;\n const pct = total > 0 ? (wgt / total) * 100 : 0;\n const barLen = total > 0 ? Math.round((wgt / total) * 30) : 0;\n const bar = '█'.repeat(barLen) + '·'.repeat(30 - barLen);\n w(` ${opt.label.padEnd(maxLabel)} ${bar} ${wgt.toLocaleString().padStart(12)} ${pct.toFixed(1).padStart(5)}%\\n`);\n }\n w(`\\n`);\n}\n","// oc-vote verify <poll_id> — fetch poll + ballots, verify every BIP-322 signature, report.\n\nimport {\n ballotId as computeBallotId,\n pollId as computePollId,\n type Ballot,\n type Poll,\n} from '@orangecheck/vote-core';\n\nimport { DEFAULT_RELAYS, fetchBallotEvents, fetchPollEvent } from '../nostr.js';\n\nexport interface VerifyOptions {\n pollId: string;\n relays?: string[];\n json?: boolean;\n}\n\nexport async function runVerify(opts: VerifyOptions): Promise<void> {\n const pid = opts.pollId;\n if (!/^[0-9a-f]{64}$/.test(pid)) {\n throw new Error('poll id must be 64 hex chars');\n }\n const relays = opts.relays ?? DEFAULT_RELAYS;\n\n const [pollEvent, ballotEvents] = await Promise.all([\n fetchPollEvent(pid, relays),\n fetchBallotEvents(pid, relays),\n ]);\n if (!pollEvent) throw new Error('poll not found');\n const poll = JSON.parse(pollEvent.content) as Poll;\n if (computePollId(poll) !== pid) throw new Error('poll content mismatch');\n\n const mod = (await import('bip322-js')) as unknown as {\n Verifier?: { verifySignature(a: string, m: string, s: string): boolean };\n default?: {\n Verifier?: { verifySignature(a: string, m: string, s: string): boolean };\n };\n };\n const Verifier = mod.Verifier ?? mod.default?.Verifier;\n if (!Verifier) throw new Error('bip322 verifier unavailable');\n\n const pollSigOk = Verifier.verifySignature(poll.creator, pid, poll.sig.value);\n\n const ballots: Ballot[] = [];\n const seen = new Set<string>();\n const ballotResults: Array<{ voter: string; ballot_id: string; ok: boolean }> = [];\n for (const ev of ballotEvents) {\n try {\n const b = JSON.parse(ev.content) as Ballot;\n if (b.poll_id !== pid) continue;\n const bid = computeBallotId(b);\n if (seen.has(bid)) continue;\n seen.add(bid);\n ballots.push(b);\n const ok = Verifier.verifySignature(b.voter, bid, b.sig.value);\n ballotResults.push({ voter: b.voter, ballot_id: bid, ok });\n } catch {\n // skip\n }\n }\n\n const okCount = ballotResults.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n poll_id: pid,\n poll_signature_valid: pollSigOk,\n ballot_count: ballots.length,\n ballots_valid: okCount,\n ballots_invalid: ballots.length - okCount,\n ballot_details: ballotResults,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n poll_id: ${pid}\\n`);\n w(` poll signature: ${pollSigOk ? 'VALID ✓' : 'INVALID ✗'}\\n`);\n w(` ballots observed: ${ballots.length}\\n`);\n w(` ballots valid: ${okCount}\\n`);\n w(` ballots invalid: ${ballots.length - okCount}\\n\\n`);\n if (ballots.length - okCount > 0) {\n w(` invalid ballots:\\n`);\n for (const r of ballotResults.filter((x) => !x.ok)) {\n w(` - ${r.voter} · ${r.ballot_id}\\n`);\n }\n w(`\\n`);\n }\n}\n","// oc-vote vote — build + sign + publish a ballot.\n//\n// Public mode: just --poll --voter --option --sig.\n// Secret mode: additionally --reveal-pk (from the poll); we seal the option\n// id into an oc-lock envelope + commit it per SPEC §4.4.\n\nimport { seal } from '@orangecheck/lock-core';\nimport { utf8Encode } from '@orangecheck/lock-crypto';\nimport { ballotId, commit, pollId as computePollId } from '@orangecheck/vote-core';\nimport type { Ballot, Poll } from '@orangecheck/vote-core';\n\nimport { buildBallotEvent } from '../events.js';\nimport { DEFAULT_RELAYS, fetchPollEvent, publishEvent } from '../nostr.js';\nimport { promptForSignature } from '../sig.js';\n\nexport interface VoteOptions {\n pollId: string;\n voter: string;\n option: string;\n sig?: string;\n relays?: string[];\n dryRun?: boolean;\n json?: boolean;\n}\n\nexport async function runVote(opts: VoteOptions): Promise<void> {\n if (!/^[0-9a-f]{64}$/.test(opts.pollId)) {\n throw new Error('poll id must be 64 hex chars');\n }\n\n // Fetch the poll from relays so we know the mode + options + reveal_pk.\n const event = await fetchPollEvent(opts.pollId, opts.relays ?? DEFAULT_RELAYS);\n if (!event) throw new Error('poll not found on relays');\n const poll = JSON.parse(event.content) as Poll;\n if (computePollId(poll) !== opts.pollId) {\n throw new Error('poll content does not match poll_id');\n }\n if (poll.mode === 'public' && !poll.options.some((o) => o.id === opts.option)) {\n throw new Error(`option \"${opts.option}\" not in poll options (${poll.options.map((o) => o.id).join(', ')})`);\n }\n\n let ballotOption: string | null = opts.option;\n let secret: Ballot['secret'] = null;\n\n if (poll.mode === 'secret') {\n if (!poll.reveal_pk) throw new Error('secret-mode poll missing reveal_pk');\n const envelope = await seal({\n payload: utf8Encode(opts.option),\n sender: { address: opts.voter, signMessage: async () => '' },\n recipients: [\n {\n address: `oc-vote:reveal:${opts.pollId}`,\n device_id: 'reveal',\n device_pk: poll.reveal_pk,\n },\n ],\n });\n ballotOption = null;\n secret = {\n envelope: envelope as unknown as Record<string, unknown>,\n commit: commit(opts.pollId, opts.voter, opts.option),\n };\n }\n\n const draft: Ballot = {\n v: 0,\n kind: 'oc-vote/ballot',\n poll_id: opts.pollId,\n voter: opts.voter,\n option: ballotOption,\n attestation_id: null,\n secret,\n created_at: new Date().toISOString().replace(/\\.\\d+Z$/, 'Z'),\n sig: { alg: 'bip322', pubkey: opts.voter, value: '' },\n };\n\n const bid = ballotId(draft);\n\n if (opts.dryRun) {\n process.stdout.write(JSON.stringify({ ballot_id: bid, ballot: draft }, null, 2) + '\\n');\n return;\n }\n\n const sigValue = await promptForSignature(opts.voter, bid, opts.sig);\n draft.sig.value = sigValue;\n\n const pub = buildBallotEvent(draft);\n const results = await publishEvent(pub, opts.relays ?? DEFAULT_RELAYS);\n const okCount = results.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n ballot_id: bid,\n published: okCount,\n total: results.length,\n relays: results,\n ballot: draft,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n ballot_id: ${bid}\\n`);\n w(` poll: ${poll.question}\\n`);\n w(` voter: ${opts.voter}\\n`);\n w(` option: ${opts.option}${poll.mode === 'secret' ? ' (sealed)' : ''}\\n`);\n w(` published: ${okCount}/${results.length} relays\\n`);\n for (const r of results) {\n w(` ${r.ok ? '✓' : '✗'} ${r.relay}${r.reason ? ` (${r.reason})` : ''}\\n`);\n }\n w(`\\n`);\n}\n","/**\n * @orangecheck/vote-cli — shell interface to OC Vote.\n *\n * read:\n * oc-vote tally <poll_id> run the pure tally function\n * oc-vote verify <poll_id> verify every BIP-322 signature\n * oc-vote show <poll_id> poll metadata + ballot count\n * oc-vote discover list recent polls across relays\n *\n * write (headless — signature via --sig or interactive paste):\n * oc-vote create build + sign + publish a poll\n * oc-vote vote cast a ballot (public or secret)\n * oc-vote reveal publish the reveal event\n *\n * utility:\n * oc-vote gen-reveal-key mint a fresh X25519 pair\n *\n * Defaults: canonical 4-relay set + mempool.space for UTXOs.\n * Swap via --relay wss://... (repeatable) and --mempool-base https://...\n */\n\nimport { Command, Option } from 'commander';\n\nimport { runCreate } from './commands/create.js';\nimport { runDiscover } from './commands/discover.js';\nimport { runGenRevealKey } from './commands/gen-reveal-key.js';\nimport { runReveal } from './commands/reveal.js';\nimport { runShow } from './commands/show.js';\nimport { runTally } from './commands/tally.js';\nimport { runVerify } from './commands/verify.js';\nimport { runVote } from './commands/vote.js';\n\nconst program = new Command();\n\nfunction collectRelay(v: string, prev: string[] = []): string[] {\n return [...prev, v];\n}\n\nfunction collectOption(v: string, prev: { id: string; label: string }[] = []) {\n const [id, ...rest] = v.split(':');\n if (!id) throw new Error(`--option requires \"id\" or \"id:label\"`);\n const label = rest.length ? rest.join(':') : id;\n return [...prev, { id, label }];\n}\n\nfunction parseDeadline(raw: string): string {\n const rel = raw.match(/^\\+(\\d+)([dh])$/);\n if (rel) {\n const n = Number.parseInt(rel[1]!, 10);\n const unit = rel[2];\n const ms = (unit === 'd' ? n * 24 : n) * 3600 * 1000;\n const d = new Date(Date.now() + ms);\n return d.toISOString().replace(/\\.\\d+Z$/, 'Z');\n }\n const parsed = new Date(raw);\n if (Number.isNaN(parsed.getTime())) throw new Error(`invalid deadline: ${raw}`);\n return parsed.toISOString().replace(/\\.\\d+Z$/, 'Z');\n}\n\nfunction parseSnapshot(raw: string): number | 'deadline' {\n if (raw === 'deadline') return 'deadline';\n const n = Number.parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) throw new Error(`invalid snapshot block: ${raw}`);\n return n;\n}\n\nprogram\n .name('oc-vote')\n .description('OC Vote — sovereign signaling for the open web')\n .version('0.2.0');\n\n// ── read ──────────────────────────────────────────────────────────────────\n\nprogram\n .command('tally <poll_id>')\n .description('Fetch the poll + ballots and run the pure tally function')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--mempool-base <url>', 'mempool.space-compatible base URL', 'https://mempool.space/api')\n .option('--snapshot <height>', 'Override snapshot block (integer)')\n .option('--no-verify', 'Skip BIP-322 signature verification')\n .option('--json', 'Emit JSON instead of human-readable output')\n .action(async (pollId: string, opts: Record<string, unknown>) => {\n await runTally({\n pollId,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n mempoolBase: opts.mempoolBase as string,\n json: Boolean(opts.json),\n verify: opts.verify !== false,\n snapshotBlock: opts.snapshot ? Number.parseInt(String(opts.snapshot), 10) : undefined,\n });\n });\n\nprogram\n .command('verify <poll_id>')\n .description('Verify every BIP-322 signature on the poll + its ballots')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--json', 'Emit JSON')\n .action(async (pollId: string, opts: Record<string, unknown>) => {\n await runVerify({\n pollId,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('show <poll_id>')\n .description('Print the poll metadata + ballot count without running the tally')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--json', 'Emit JSON')\n .action(async (pollId: string, opts: Record<string, unknown>) => {\n await runShow({\n pollId,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('discover')\n .description('List recent polls across the default relay set')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--limit <n>', 'max polls to return', '30')\n .option('--open-only', 'hide polls whose deadline has passed')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n await runDiscover({\n limit: Number.parseInt(String(opts.limit ?? '30'), 10),\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n json: Boolean(opts.json),\n openOnly: Boolean(opts.openOnly),\n });\n });\n\n// ── write ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('create')\n .description('Build + sign + publish a poll')\n .requiredOption('--creator <btc-addr>', 'Bitcoin address of the poll creator')\n .requiredOption('--question <text>', 'poll question')\n .requiredOption(\n '--option <id:label>',\n 'poll option; repeatable; \"id\" or \"id:label\"',\n collectOption,\n [] as { id: string; label: string }[]\n )\n .option('--deadline <iso8601 | +Nd | +Nh>', 'deadline in UTC', '+7d')\n .option('--snapshot <height | deadline>', 'snapshot block', 'deadline')\n .addOption(\n new Option('--weight-mode <mode>', 'weight function')\n .choices(['one_per_address', 'sats', 'sats_days'])\n .default('sats')\n )\n .option('--cap-days <n>', 'age cap in days (required for sats_days)', '180')\n .option('--min-sats <n>', 'minimum sat threshold', '0')\n .option('--min-days <n>', 'minimum UTXO-age threshold', '0')\n .addOption(\n new Option('--tiebreak <mode>', 'per-voter dedup rule')\n .choices(['latest', 'first'])\n .default('latest')\n )\n .addOption(\n new Option('--mode <mode>', 'ballot mode')\n .choices(['public', 'secret'])\n .default('public')\n )\n .option('--notes <text>', 'free-form notes (≤ 2048 bytes)')\n .option('--sig <base64>', 'BIP-322 signature of poll_id; prompts if omitted')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--dry-run', 'print canonical + id; do not sign or publish')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n const mode = opts.mode as 'public' | 'secret';\n const weightMode = opts.weightMode as 'one_per_address' | 'sats' | 'sats_days';\n await runCreate({\n creator: String(opts.creator),\n question: String(opts.question),\n options: opts.option as { id: string; label: string }[],\n deadline: parseDeadline(String(opts.deadline)),\n snapshotBlock: parseSnapshot(String(opts.snapshot)),\n weightMode,\n capDays: weightMode === 'sats_days' ? Number.parseInt(String(opts.capDays), 10) : undefined,\n minSats: Number.parseInt(String(opts.minSats), 10),\n minDays: Number.parseInt(String(opts.minDays), 10),\n tiebreak: opts.tiebreak as 'latest' | 'first',\n mode,\n notes: opts.notes ? String(opts.notes) : undefined,\n sig: opts.sig ? String(opts.sig) : undefined,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n dryRun: Boolean(opts.dryRun),\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('vote')\n .description('Cast a ballot on a poll')\n .requiredOption('--poll <poll_id>', '64-hex poll id')\n .requiredOption('--voter <btc-addr>', 'voter Bitcoin address')\n .requiredOption('--option <id>', 'chosen option id')\n .option('--sig <base64>', 'BIP-322 signature of ballot_id; prompts if omitted')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--dry-run', 'print canonical + id; do not sign or publish')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n await runVote({\n pollId: String(opts.poll),\n voter: String(opts.voter),\n option: String(opts.option),\n sig: opts.sig ? String(opts.sig) : undefined,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n dryRun: Boolean(opts.dryRun),\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('reveal')\n .description('Publish the reveal event for a secret-mode poll')\n .requiredOption('--poll <poll_id>', '64-hex poll id')\n .requiredOption('--reveal-sk <hex>', '64-hex X25519 secret key')\n .requiredOption('--creator <btc-addr>', 'poll creator address (must match the poll)')\n .option('--sig <base64>', 'BIP-322 signature of reveal_id; prompts if omitted')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--force', 'publish even before deadline / even if a reveal exists')\n .option('--dry-run', 'print reveal + id; do not sign or publish')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n await runReveal({\n pollId: String(opts.poll),\n revealSk: String(opts.revealSk),\n creator: String(opts.creator),\n sig: opts.sig ? String(opts.sig) : undefined,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n force: Boolean(opts.force),\n dryRun: Boolean(opts.dryRun),\n json: Boolean(opts.json),\n });\n });\n\n// ── utility ───────────────────────────────────────────────────────────────\n\nprogram\n .command('gen-reveal-key')\n .description('Mint a fresh X25519 keypair for secret-mode polls')\n .option('--json', 'Emit JSON')\n .action((opts: Record<string, unknown>) => {\n runGenRevealKey({ json: Boolean(opts.json) });\n });\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`oc-vote: ${msg}\\n`);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"sources":["../src/events.ts","../src/nostr.ts","../src/sig.ts","../src/commands/create.ts","../src/bip322.ts","../src/commands/discover.ts","../src/commands/gen-reveal-key.ts","../src/select.ts","../src/commands/reveal.ts","../src/commands/show.ts","../src/utxos.ts","../src/commands/tally.ts","../src/commands/verify.ts","../src/commands/vote.ts","../src/cli.ts"],"names":["pollId","canonicalBytes","computePollId","generateX25519KeyPair","hexEncode","verifyPoll","revealId","ballotId","computeBallotId"],"mappings":"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","file":"cli.js","sourcesContent":["// Build NIP-01 events for oc-vote kinds 30080/30081/30082.\n// Mirror of oc-vote-web/src/lib/vote/events.ts but node-safe (uses @noble only).\n\nimport { schnorr } from '@noble/curves/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, hexToBytes, randomBytes } from '@noble/hashes/utils';\n\nimport { canonicalBytes, ballotId, pollId, revealId } from '@orangecheck/vote-core';\nimport type { Ballot, Poll, Reveal } from '@orangecheck/vote-core';\n\nimport type { NostrEvent } from './nostr.js';\n\nfunction nip01Id(pubkey: string, created_at: number, kind: number, tags: string[][], content: string): string {\n const serialized = JSON.stringify([0, pubkey, created_at, kind, tags, content]);\n return bytesToHex(sha256(new TextEncoder().encode(serialized)));\n}\n\nfunction sign(kind: number, tags: string[][], content: string): NostrEvent {\n const sk = randomBytes(32);\n const pubkey = bytesToHex(schnorr.getPublicKey(sk));\n const created_at = Math.floor(Date.now() / 1000);\n const id = nip01Id(pubkey, created_at, kind, tags, content);\n const sig = bytesToHex(schnorr.sign(hexToBytes(id), sk));\n return { id, pubkey, created_at, kind, tags, content, sig };\n}\n\nexport function buildPollEvent(poll: Poll): NostrEvent {\n const pid = pollId(poll);\n const content = canonicalBytes(poll).trimEnd();\n const snapshot =\n typeof poll.snapshot_block === 'number' ? String(poll.snapshot_block) : poll.snapshot_block;\n// NIP-12 relays index SINGLE-LETTER tag names only. The multi-letter\n// `poll_id` / `voter` / `creator` tags below are readable diagnostics and are\n// NOT queryable — a `#poll_id` filter matches nothing on a conforming relay.\n// The `t` tags are what make these events findable, and for ballots they are\n// the ONLY way to enumerate a poll: a ballot's d-tag embeds the voter, tag\n// filters are exact-match, and enumerating voters is the point of the query.\n// Kept in sync with oc-vote-web/src/lib/vote/events.ts and normative in\n// oc-vote-protocol SPEC §3.4/§3.6.\n return sign(30080, [\n ['d', `oc-vote:poll:${pid}`],\n ['t', pid],\n ['t', 'oc-vote-poll'],\n ['t', poll.creator],\n ['poll_id', pid],\n ['creator', poll.creator],\n ['deadline', poll.deadline],\n ['snapshot', snapshot],\n ['mode', poll.mode],\n ], content);\n}\n\nexport function buildBallotEvent(ballot: Ballot): NostrEvent {\n const bid = ballotId(ballot);\n const content = canonicalBytes(ballot).trimEnd();\n return sign(30081, [\n ['d', `oc-vote:ballot:${ballot.poll_id}:${ballot.voter}`],\n // `t` = poll_id is the only path to \"every ballot in this poll\".\n ['t', ballot.poll_id],\n ['t', 'oc-vote-ballot'],\n ['t', ballot.voter],\n ['poll_id', ballot.poll_id],\n ['voter', ballot.voter],\n ['ballot_id', bid],\n ], content);\n}\n\nexport function buildRevealEvent(reveal: Reveal): NostrEvent {\n const rid = revealId(reveal);\n const content = canonicalBytes(reveal).trimEnd();\n return sign(30082, [\n ['d', `oc-vote:reveal:${reveal.poll_id}`],\n ['t', reveal.poll_id],\n ['t', 'oc-vote-reveal'],\n ['poll_id', reveal.poll_id],\n ['reveal_id', rid],\n ], content);\n}\n","// Minimal NIP-01 WebSocket client for oc-vote. Node-native via the `ws` package.\n\nimport WebSocket from 'ws';\n\nexport interface NostrEvent {\n id: string;\n kind: number;\n pubkey: string;\n created_at: number;\n content: string;\n tags: string[][];\n sig: string;\n}\n\nexport interface Filter {\n kinds?: number[];\n '#d'?: string[];\n /** NIP-12 indexable single-letter tag filter. */\n '#t'?: string[];\n limit?: number;\n}\n\nexport const DEFAULT_RELAYS = [\n 'wss://relay.damus.io',\n 'wss://nos.lol',\n 'wss://relay.snort.social',\n // First-party family relay. Its write policy allows only family kinds with\n // canonical OC d-tag prefixes, and it is always queried alongside public\n // relays, never the only copy. See github.com/orangecheck/oc-relay-infra.\n 'wss://relay.ochk.io',\n];\n\nexport async function queryRelays(\n filter: Filter,\n relays: string[] = DEFAULT_RELAYS,\n timeoutMs = 8000\n): Promise<NostrEvent[]> {\n const byId = new Map<string, NostrEvent>();\n await Promise.all(\n relays.map(\n (url) =>\n new Promise<void>((resolve) => {\n const subId = 'ocvcli-' + Math.random().toString(36).slice(2, 10);\n let settled = false;\n let ws: WebSocket | null = null;\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n try {\n ws?.close();\n } catch {}\n resolve();\n }, timeoutMs);\n try {\n ws = new WebSocket(url);\n ws.on('open', () => ws?.send(JSON.stringify(['REQ', subId, filter])));\n ws.on('message', (raw: WebSocket.RawData) => {\n try {\n const arr = JSON.parse(raw.toString()) as unknown[];\n if (!Array.isArray(arr) || arr.length === 0) return;\n if (arr[0] === 'EVENT' && arr[1] === subId) {\n const event = arr[2] as NostrEvent;\n if (event?.id) byId.set(event.id, event);\n } else if (arr[0] === 'EOSE' && arr[1] === subId) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n ws?.send(JSON.stringify(['CLOSE', subId]));\n ws?.close();\n } catch {}\n resolve();\n }\n } catch {\n // ignore parse errors\n }\n });\n ws.on('error', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve();\n });\n ws.on('close', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve();\n });\n } catch {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve();\n }\n }\n })\n )\n );\n return Array.from(byId.values()).sort((a, b) => b.created_at - a.created_at);\n}\n\n/**\n * Every event under the poll's d-tag, newest first. Not `limit: 1`: anyone\n * can publish under any d-tag with any created_at, so callers choose by\n * content and signature (see select.ts).\n */\nexport async function fetchPollEvents(pollId: string, relays?: string[]) {\n return queryRelays({ kinds: [30080], '#d': [`oc-vote:poll:${pollId}`] }, relays);\n}\n\n/**\n * Every ballot in a poll.\n *\n * `#t`, not `#poll_id`: relays index single-letter tag names only, so the old\n * filter matched nothing and every tally saw zero ballots. Callers must still\n * check each parsed ballot's `poll_id` — `t` is a shared namespace on these\n * events (poll id, family marker, voter address).\n */\nexport async function fetchBallotEvents(pollId: string, relays?: string[]) {\n return queryRelays({ kinds: [30081], '#t': [pollId] }, relays);\n}\n\n/** Every event under the poll's reveal d-tag; same reasoning as `fetchPollEvents`. */\nexport async function fetchRevealEvents(pollId: string, relays?: string[]) {\n return queryRelays({ kinds: [30082], '#d': [`oc-vote:reveal:${pollId}`] }, relays);\n}\n\n// `oc-vote-poll` marker: kind 30080 is shared with other Nostr applications.\nexport async function fetchRecentPolls(limit = 30, relays?: string[]) {\n return queryRelays({ kinds: [30080], '#t': ['oc-vote-poll'], limit }, relays);\n}\n\n// ── Publish ────────────────────────────────────────────────────────────────\n\nexport interface PublishResult {\n relay: string;\n ok: boolean;\n reason?: string;\n}\n\nexport async function publishEvent(\n event: NostrEvent,\n relays: string[] = DEFAULT_RELAYS,\n timeoutMs = 6000\n): Promise<PublishResult[]> {\n return Promise.all(\n relays.map(\n (url) =>\n new Promise<PublishResult>((resolve) => {\n let settled = false;\n let ws: WebSocket | null = null;\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n try {\n ws?.close();\n } catch {}\n resolve({ relay: url, ok: false, reason: 'timeout' });\n }, timeoutMs);\n try {\n ws = new WebSocket(url);\n ws.on('open', () => ws?.send(JSON.stringify(['EVENT', event])));\n ws.on('message', (raw: WebSocket.RawData) => {\n try {\n const arr = JSON.parse(raw.toString()) as unknown[];\n if (Array.isArray(arr) && arr[0] === 'OK' && arr[1] === event.id) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n ws?.close();\n } catch {}\n const ok = arr[2] === true;\n const reason =\n typeof arr[3] === 'string' ? arr[3] : undefined;\n resolve({\n relay: url,\n ok,\n ...(reason ? { reason } : {}),\n });\n }\n } catch {}\n });\n ws.on('error', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ relay: url, ok: false, reason: 'ws_error' });\n });\n ws.on('close', () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ relay: url, ok: false, reason: 'closed_early' });\n });\n } catch (err) {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({\n relay: url,\n ok: false,\n reason: err instanceof Error ? err.message : 'unknown',\n });\n }\n })\n )\n );\n}\n","// Interactive signature prompt.\n// The CLI never holds a Bitcoin private key. To sign a poll / ballot / reveal,\n// the caller either passes --sig <base64> on the command line, or we compute\n// the canonical id, print it, and ask the user to sign elsewhere (UniSat,\n// Xverse, Leather, sparrow-wallet, any BIP-322 signer) and paste back.\n\nimport { createInterface } from 'node:readline/promises';\n\nexport async function promptForSignature(\n address: string,\n id: string,\n preset?: string\n): Promise<string> {\n if (preset && preset.trim()) return preset.trim();\n\n process.stderr.write(\n `\\n sign with BIP-322, address ${address}\\n` +\n ` message: ${id}\\n\\n` +\n ` paste the base64 signature and press enter:\\n > `\n );\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n const sig = (await rl.question('')).trim();\n rl.close();\n if (!sig) throw new Error('empty signature');\n return sig;\n}\n","// oc-vote create — build + sign + publish a poll.\n\nimport { hexEncode } from '@orangecheck/lock-crypto';\nimport { generateX25519KeyPair } from '@orangecheck/lock-crypto';\nimport { canonicalBytes, pollId } from '@orangecheck/vote-core';\nimport type { Poll, PollMode, Tiebreak, WeightMode } from '@orangecheck/vote-core';\n\nimport { buildPollEvent } from '../events.js';\nimport { DEFAULT_RELAYS, publishEvent } from '../nostr.js';\nimport { promptForSignature } from '../sig.js';\n\nexport interface CreateOptions {\n creator: string;\n question: string;\n options: { id: string; label: string }[];\n deadline: string;\n snapshotBlock: number | 'deadline';\n weightMode: WeightMode;\n capDays?: number;\n minSats: number;\n minDays: number;\n tiebreak: Tiebreak;\n mode: PollMode;\n notes?: string;\n sig?: string;\n relays?: string[];\n dryRun?: boolean;\n json?: boolean;\n}\n\nexport async function runCreate(opts: CreateOptions): Promise<void> {\n if (!/^(bc1|1|3)[0-9a-zA-Z]+$/.test(opts.creator)) {\n throw new Error(`creator does not look like a Bitcoin mainnet address: ${opts.creator}`);\n }\n if (opts.options.length < 2) throw new Error('need at least 2 options');\n if (new Set(opts.options.map((o) => o.id)).size !== opts.options.length) {\n throw new Error('option ids must be unique');\n }\n\n // Secret mode: generate an X25519 reveal keypair.\n let reveal_pk: string | null = null;\n let reveal_sk: string | null = null;\n if (opts.mode === 'secret') {\n const kp = generateX25519KeyPair();\n reveal_sk = hexEncode(kp.secret);\n reveal_pk = hexEncode(kp.public);\n }\n\n const draft: Poll = {\n v: 0,\n kind: 'oc-vote/poll',\n creator: opts.creator,\n question: opts.question,\n options: opts.options,\n deadline: opts.deadline,\n snapshot_block: opts.snapshotBlock,\n weight_mode: opts.weightMode,\n weight_params:\n opts.weightMode === 'sats_days' && opts.capDays\n ? { cap_days: opts.capDays }\n : null,\n min_sats: opts.minSats,\n min_days: opts.minDays,\n mode: opts.mode,\n reveal_pk,\n tiebreak: opts.tiebreak,\n notes: opts.notes ?? null,\n created_at: new Date().toISOString().replace(/\\.\\d+Z$/, 'Z'),\n sig: { alg: 'bip322', pubkey: opts.creator, value: '' },\n };\n\n const pid = pollId(draft);\n\n if (opts.dryRun) {\n const out = {\n poll_id: pid,\n poll: draft,\n ...(reveal_sk ? { reveal_sk, reveal_pk } : {}),\n };\n process.stdout.write(JSON.stringify(out, null, 2) + '\\n');\n return;\n }\n\n const sigValue = await promptForSignature(opts.creator, pid, opts.sig);\n draft.sig.value = sigValue;\n\n const event = buildPollEvent(draft);\n const results = await publishEvent(event, opts.relays ?? DEFAULT_RELAYS);\n const okCount = results.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n poll_id: pid,\n published: okCount,\n total: results.length,\n relays: results,\n poll: draft,\n ...(reveal_sk ? { reveal_sk, reveal_pk } : {}),\n url: `https://vote.ochk.io/p/${pid}`,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n poll_id: ${pid}\\n`);\n w(` published: ${okCount}/${results.length} relays\\n`);\n for (const r of results) {\n w(` ${r.ok ? '✓' : '✗'} ${r.relay}${r.reason ? ` (${r.reason})` : ''}\\n`);\n }\n w(` url: https://vote.ochk.io/p/${pid}\\n`);\n if (reveal_sk) {\n w(`\\n SECRET MODE — save these or the poll is abandoned at deadline:\\n`);\n w(` reveal_pk: ${reveal_pk}\\n`);\n w(` reveal_sk: ${reveal_sk}\\n`);\n w(` to publish the reveal:\\n`);\n w(` oc-vote reveal --poll ${pid} --reveal-sk ${reveal_sk} --creator ${opts.creator}\\n`);\n }\n w(`\\n canonical bytes:\\n`);\n w(canonicalBytes({ ...draft, sig: { ...draft.sig, value: '' } }));\n w(`\\n`);\n}\n","// BIP-322 verification in vote-core's named-argument shape. Returns false on\n// any parse or verify failure.\n\nexport async function bip322Verify(args: {\n address: string;\n message: string;\n signature: string;\n}): Promise<boolean> {\n try {\n const mod = (await import('bip322-js')) as unknown as {\n Verifier?: { verifySignature(a: string, m: string, s: string): boolean };\n default?: {\n Verifier?: { verifySignature(a: string, m: string, s: string): boolean };\n };\n };\n const Verifier = mod.Verifier ?? mod.default?.Verifier;\n if (!Verifier) return false;\n return Verifier.verifySignature(args.address, args.message, args.signature);\n } catch {\n return false;\n }\n}\n","// oc-vote discover — list recent polls across the default relay set.\n\nimport { pollId as computePollId, verifyPoll } from '@orangecheck/vote-core';\nimport type { Poll } from '@orangecheck/vote-core';\n\nimport { bip322Verify } from '../bip322.js';\nimport { DEFAULT_RELAYS, fetchRecentPolls } from '../nostr.js';\n\nexport interface DiscoverOptions {\n limit?: number;\n relays?: string[];\n json?: boolean;\n openOnly?: boolean;\n}\n\nexport async function runDiscover(opts: DiscoverOptions): Promise<void> {\n const limit = opts.limit ?? 30;\n const events = await fetchRecentPolls(limit, opts.relays ?? DEFAULT_RELAYS);\n\n interface Item {\n poll_id: string;\n poll: Poll;\n nostr_created_at: number;\n }\n const seen = new Set<string>();\n const items: Item[] = [];\n for (const ev of events) {\n try {\n const poll = JSON.parse(ev.content) as Poll;\n if (poll.kind !== 'oc-vote/poll' || poll.v !== 0) continue;\n const pid = computePollId(poll);\n if (seen.has(pid)) continue;\n seen.add(pid);\n if (opts.openOnly && Date.parse(poll.deadline) < Date.now()) continue;\n // Listed only when the creator's signature verifies (SPEC §10.1).\n if (!(await verifyPoll(poll, bip322Verify)).ok) continue;\n items.push({ poll_id: pid, poll, nostr_created_at: ev.created_at });\n } catch {}\n }\n items.sort((a, b) => b.nostr_created_at - a.nostr_created_at);\n\n if (opts.json) {\n process.stdout.write(JSON.stringify(items, null, 2) + '\\n');\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n discovered ${items.length} poll(s) across ${(opts.relays ?? DEFAULT_RELAYS).length} relays\\n\\n`);\n for (const { poll, poll_id, nostr_created_at } of items) {\n const isPast = Date.parse(poll.deadline) < Date.now();\n const age = Math.max(0, Math.floor((Date.now() / 1000 - nostr_created_at) / 60));\n const ageStr =\n age < 1\n ? 'just now'\n : age < 60\n ? `${age}m`\n : age < 60 * 24\n ? `${Math.floor(age / 60)}h`\n : `${Math.floor(age / (60 * 24))}d`;\n w(` [${isPast ? 'closed' : ' open '}] [${poll.weight_mode.padEnd(15)}] ${ageStr.padStart(5)} · ${poll.question}\\n`);\n w(` https://vote.ochk.io/p/${poll_id}\\n`);\n }\n if (items.length === 0) {\n w(` No polls found. Try: oc-vote create\\n`);\n }\n w(`\\n`);\n}\n","// oc-vote gen-reveal-key — print a fresh X25519 keypair for secret-mode\n// polls. Use this to pre-generate a key pair you pin into a --reveal-pk\n// flag, then publish the matching --reveal-sk at deadline.\n//\n// The standard `oc-vote create --mode secret` already generates one\n// automatically; this command exists for flows that want the key in hand\n// before composing the poll (e.g. DAO trustee ceremonies).\n\nimport { generateX25519KeyPair, hexEncode } from '@orangecheck/lock-crypto';\n\nexport interface GenRevealKeyOptions {\n json?: boolean;\n}\n\nexport function runGenRevealKey(opts: GenRevealKeyOptions): void {\n const kp = generateX25519KeyPair();\n const reveal_sk = hexEncode(kp.secret);\n const reveal_pk = hexEncode(kp.public);\n\n if (opts.json) {\n process.stdout.write(JSON.stringify({ reveal_sk, reveal_pk }, null, 2) + '\\n');\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n reveal_pk: ${reveal_pk}\\n`);\n w(` reveal_sk: ${reveal_sk}\\n\\n`);\n w(` pass reveal_pk to --reveal-pk at poll creation.\\n`);\n w(` keep reveal_sk offline until deadline; publish via:\\n`);\n w(` oc-vote reveal --poll <id> --reveal-sk ${reveal_sk} --creator <addr>\\n\\n`);\n}\n","// Pick the poll / reveal out of everything relays return under a d-tag.\n//\n// The poll is an event whose content hashes to the requested id (SPEC §3.2);\n// among those, one whose creator signature verifies (§10.1) is preferred.\n// The reveal is the first that verifies against the poll (§6.4, §10.3).\n\nimport {\n pollId as computePollId,\n verifyPoll,\n verifyReveal,\n type Poll,\n type Reveal,\n type SignatureVerifier,\n} from '@orangecheck/vote-core';\n\nimport type { NostrEvent } from './nostr.js';\n\nfunction parse<T>(ev: NostrEvent): T | null {\n try {\n return JSON.parse(ev.content) as T;\n } catch {\n return null;\n }\n}\n\nexport async function selectPoll(\n events: NostrEvent[],\n pid: string,\n verify: SignatureVerifier\n): Promise<{ poll: Poll; signatureValid: boolean } | null> {\n let unverified: Poll | null = null;\n for (const ev of events) {\n const p = parse<Poll>(ev);\n if (!p || p.kind !== 'oc-vote/poll' || computePollId(p) !== pid) continue;\n if ((await verifyPoll(p, verify)).ok) return { poll: p, signatureValid: true };\n unverified ??= p;\n }\n return unverified ? { poll: unverified, signatureValid: false } : null;\n}\n\nexport async function selectReveal(\n events: NostrEvent[],\n poll: Poll,\n verify: SignatureVerifier\n): Promise<Reveal | null> {\n for (const ev of events) {\n const r = parse<Reveal>(ev);\n if (r && (await verifyReveal(r, poll, verify)).ok) return r;\n }\n return null;\n}\n","// oc-vote reveal — publish the reveal event for a secret-mode poll.\n\nimport { revealId } from '@orangecheck/vote-core';\nimport type { Reveal } from '@orangecheck/vote-core';\n\nimport { bip322Verify } from '../bip322.js';\n\nimport { buildRevealEvent } from '../events.js';\nimport { DEFAULT_RELAYS, fetchPollEvents, fetchRevealEvents, publishEvent } from '../nostr.js';\nimport { selectPoll, selectReveal } from '../select.js';\nimport { promptForSignature } from '../sig.js';\n\nexport interface RevealOptions {\n pollId: string;\n revealSk: string;\n creator: string;\n sig?: string;\n relays?: string[];\n force?: boolean;\n dryRun?: boolean;\n json?: boolean;\n}\n\nexport async function runReveal(opts: RevealOptions): Promise<void> {\n if (!/^[0-9a-f]{64}$/.test(opts.pollId)) {\n throw new Error('poll id must be 64 hex chars');\n }\n if (!/^[0-9a-f]{64}$/.test(opts.revealSk)) {\n throw new Error('reveal_sk must be 64 hex chars');\n }\n\n const relays = opts.relays ?? DEFAULT_RELAYS;\n const selected = await selectPoll(await fetchPollEvents(opts.pollId, relays), opts.pollId, bip322Verify);\n if (!selected) throw new Error('poll not found on relays');\n const poll = selected.poll;\n if (poll.mode !== 'secret') throw new Error('poll is public-mode — no reveal needed');\n if (poll.creator !== opts.creator) {\n throw new Error(\n `poll creator is ${poll.creator} but you provided ${opts.creator}`\n );\n }\n if (Date.parse(poll.deadline) > Date.now() && !opts.force) {\n throw new Error(\n `poll deadline is ${poll.deadline} — pass --force to publish before deadline`\n );\n }\n\n // Only a reveal that verifies against the poll counts as already published.\n const existing = await selectReveal(await fetchRevealEvents(opts.pollId, relays), poll, bip322Verify);\n if (existing && !opts.force) {\n throw new Error('a reveal event already exists for this poll (pass --force to replace)');\n }\n\n const draft: Reveal = {\n v: 0,\n kind: 'oc-vote/reveal',\n poll_id: opts.pollId,\n reveal_sk: opts.revealSk,\n revealed_at: new Date().toISOString().replace(/\\.\\d+Z$/, 'Z'),\n sig: { alg: 'bip322', pubkey: opts.creator, value: '' },\n };\n\n const rid = revealId(draft);\n\n if (opts.dryRun) {\n process.stdout.write(JSON.stringify({ reveal_id: rid, reveal: draft }, null, 2) + '\\n');\n return;\n }\n\n const sigValue = await promptForSignature(opts.creator, rid, opts.sig);\n draft.sig.value = sigValue;\n\n const event = buildRevealEvent(draft);\n const results = await publishEvent(event, relays);\n const okCount = results.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n reveal_id: rid,\n published: okCount,\n total: results.length,\n relays: results,\n reveal: draft,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n reveal_id: ${rid}\\n`);\n w(` poll: ${poll.question}\\n`);\n w(` revealed: ${draft.revealed_at}\\n`);\n w(` published: ${okCount}/${results.length} relays\\n`);\n for (const r of results) {\n w(` ${r.ok ? '✓' : '✗'} ${r.relay}${r.reason ? ` (${r.reason})` : ''}\\n`);\n }\n w(`\\n tally with: oc-vote tally ${opts.pollId}\\n\\n`);\n}\n","// oc-vote show <poll_id> — print the poll metadata + ballot count.\n\n\nimport { bip322Verify } from '../bip322.js';\nimport { DEFAULT_RELAYS, fetchBallotEvents, fetchPollEvents } from '../nostr.js';\nimport { selectPoll } from '../select.js';\n\nexport interface ShowOptions {\n pollId: string;\n relays?: string[];\n json?: boolean;\n}\n\nexport async function runShow(opts: ShowOptions): Promise<void> {\n const pid = opts.pollId;\n if (!/^[0-9a-f]{64}$/.test(pid)) {\n throw new Error('poll id must be 64 hex chars');\n }\n const relays = opts.relays ?? DEFAULT_RELAYS;\n\n const [pollEvents, ballotEvents] = await Promise.all([\n fetchPollEvents(pid, relays),\n fetchBallotEvents(pid, relays),\n ]);\n const selected = await selectPoll(pollEvents, pid, bip322Verify);\n if (!selected) throw new Error('poll not found');\n const { poll, signatureValid } = selected;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n { poll, poll_signature_valid: signatureValid, ballot_count: ballotEvents.length },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n question: ${poll.question}\\n`);\n w(` options: ${poll.options.map((o) => `${o.id} (${o.label})`).join(', ')}\\n`);\n w(` creator: ${poll.creator}${signatureValid ? '' : ' (SIGNATURE DOES NOT VERIFY)'}\\n`);\n w(` mode: ${poll.mode}\\n`);\n w(` weight: ${poll.weight_mode}${poll.weight_mode === 'sats_days' && poll.weight_params?.cap_days ? ` (cap ${poll.weight_params.cap_days}d)` : ''}\\n`);\n w(` threshold: ${poll.min_sats} sat / ${poll.min_days} d\\n`);\n w(` tiebreak: ${poll.tiebreak}\\n`);\n w(` deadline: ${poll.deadline}\\n`);\n w(` snapshot: ${poll.snapshot_block}\\n`);\n w(` ballots: ${ballotEvents.length}\\n`);\n if (poll.notes) w(` notes: ${poll.notes}\\n`);\n w(`\\n`);\n}\n","// UTXO snapshot source for the CLI. Defaults to mempool.space; swappable via\n// --mempool-base flag.\n\nimport type { Utxo, UtxoLookup } from '@orangecheck/vote-core';\n\ninterface MempoolUtxo {\n txid: string;\n vout: number;\n value: number;\n status: { confirmed: boolean; block_height?: number; block_time?: number };\n}\n\nexport interface UtxoSource {\n fetchUtxos(address: string): Promise<Utxo[]>;\n fetchTipHeight(): Promise<number>;\n}\n\nexport function mempoolSource(base = 'https://mempool.space/api'): UtxoSource {\n return {\n async fetchUtxos(address) {\n const res = await fetch(`${base}/address/${address}/utxo`, {\n headers: { accept: 'application/json' },\n });\n if (!res.ok) throw new Error(`mempool utxo ${res.status}`);\n const data = (await res.json()) as MempoolUtxo[];\n return data\n .filter((u) => u.status.confirmed && typeof u.status.block_height === 'number')\n .map((u) => ({\n value: u.value,\n confirmed_height: u.status.block_height as number,\n }));\n },\n async fetchTipHeight() {\n const res = await fetch(`${base}/blocks/tip/height`);\n if (!res.ok) throw new Error(`tip ${res.status}`);\n return Number.parseInt((await res.text()).trim(), 10);\n },\n };\n}\n\nexport function buildLookup(source: UtxoSource): UtxoLookup {\n return async (addr: string, snapshot: number): Promise<Utxo[]> => {\n const all = await source.fetchUtxos(addr);\n return all.filter((u) => u.confirmed_height <= snapshot);\n };\n}\n","// oc-vote tally <poll_id>\n\nimport { hexDecode, utf8Decode } from '@orangecheck/lock-crypto';\nimport { unseal } from '@orangecheck/lock-core';\nimport {\n ballotId,\n tally,\n type Ballot,\n type Poll,\n type Reveal,\n type SignatureVerifier,\n type TallyResult,\n type UtxoLookup,\n} from '@orangecheck/vote-core';\n\nimport { bip322Verify } from '../bip322.js';\nimport {\n DEFAULT_RELAYS,\n fetchBallotEvents,\n fetchPollEvents,\n fetchRevealEvents,\n} from '../nostr.js';\nimport { selectPoll, selectReveal } from '../select.js';\nimport { buildLookup, mempoolSource } from '../utxos.js';\n\nexport interface TallyOptions {\n pollId: string;\n relays?: string[];\n mempoolBase?: string;\n json?: boolean;\n verify?: boolean;\n snapshotBlock?: number;\n}\n\n/** Open a secret ballot's envelope with the revealed key (SPEC §6.4 step 2). */\nexport async function unsealOption(ballot: Ballot, revealSk: string): Promise<string | null> {\n if (!ballot.secret) return null;\n const result = await unseal({\n envelope: ballot.secret.envelope as unknown as Parameters<typeof unseal>[0]['envelope'],\n device: { device_id: 'reveal', secretKey: hexDecode(revealSk) },\n skipSenderVerification: true,\n });\n return utf8Decode(result.payload);\n}\n\nexport interface ComputeTallyInput {\n poll: Poll;\n ballots: Ballot[];\n /** A reveal that already passed verifyReveal; null when none exists. */\n reveal: Reveal | null;\n utxosAt: UtxoLookup;\n snapshotBlock: number;\n tipHeight?: number;\n /** null skips every signature check (--no-verify). */\n verify: SignatureVerifier | null;\n}\n\n/**\n * vote-core's tally with this CLI's unsealer. vote-core calls `unseal` on each\n * voter's verified, tiebroken ballot only, so a ballot that fails its\n * signature never supplies a voter's option.\n */\nexport function computeTally(input: ComputeTallyInput): Promise<TallyResult> {\n const { poll, reveal } = input;\n return tally({\n poll,\n ballots: input.ballots,\n utxosAt: input.utxosAt,\n snapshotBlock: input.snapshotBlock,\n ...(input.tipHeight !== undefined ? { tipHeight: input.tipHeight } : {}),\n ...(input.verify ? { verify: input.verify } : { skipSignatures: true }),\n ...(poll.mode === 'secret' && reveal\n ? { unseal: (b: Ballot) => unsealOption(b, reveal.reveal_sk) }\n : {}),\n });\n}\n\nexport async function runTally(opts: TallyOptions): Promise<void> {\n const { pollId: pid } = opts;\n if (!/^[0-9a-f]{64}$/.test(pid)) {\n throw new Error('poll id must be 64 hex chars');\n }\n const relays = opts.relays ?? DEFAULT_RELAYS;\n\n const verify = opts.verify !== false ? bip322Verify : null;\n const [pollEvents, ballotEvents, revealEvents] = await Promise.all([\n fetchPollEvents(pid, relays),\n fetchBallotEvents(pid, relays),\n fetchRevealEvents(pid, relays),\n ]);\n\n const selected = await selectPoll(pollEvents, pid, verify ?? bip322Verify);\n if (!selected) throw new Error('poll not found on any relay');\n if (verify && !selected.signatureValid) {\n throw new Error('poll signature does not verify against its creator (SPEC §10.1)');\n }\n const poll = selected.poll;\n\n const ballots: Ballot[] = [];\n const seen = new Set<string>();\n for (const ev of ballotEvents) {\n try {\n const b = JSON.parse(ev.content) as Ballot;\n if (b.poll_id !== pid) continue;\n const id = ballotId(b);\n if (seen.has(id)) continue;\n seen.add(id);\n ballots.push(b);\n } catch {\n // skip malformed\n }\n }\n\n // Only a reveal signed by the creator, after the deadline, opens ballots.\n const reveal: Reveal | null =\n poll.mode === 'secret' ? await selectReveal(revealEvents, poll, bip322Verify) : null;\n\n // Resolve snapshot\n const source = mempoolSource(opts.mempoolBase);\n const utxosAt = buildLookup(source);\n let snapshot = poll.snapshot_block;\n if (typeof snapshot !== 'number') {\n snapshot = opts.snapshotBlock ?? (await source.fetchTipHeight());\n }\n\n // Pass `snapshotBlock` rather than mutating poll.snapshot_block: the\n // poll's canonical bytes (and therefore pollId) include snapshot_block\n // verbatim, and mutating it would invalidate every ballot's poll_id.\n // A snapshot fixed by the poll must have 6 confirmations (SPEC §10.5).\n const result = await computeTally({\n poll,\n ballots,\n reveal,\n utxosAt,\n snapshotBlock: snapshot,\n ...(typeof poll.snapshot_block === 'number'\n ? { tipHeight: await source.fetchTipHeight() }\n : {}),\n verify,\n });\n\n const output = {\n poll_id: pid,\n question: poll.question,\n creator: poll.creator,\n mode: poll.mode,\n weight_mode: poll.weight_mode,\n deadline: poll.deadline,\n ballot_count: ballots.length,\n reveal_present: reveal != null,\n ...result,\n };\n\n if (opts.json) {\n process.stdout.write(JSON.stringify(output, null, 2) + '\\n');\n return;\n }\n\n // Human-readable\n const w = (s: string) => process.stdout.write(s);\n w(`\\n poll: ${poll.question}\\n`);\n w(` poll_id: ${pid}\\n`);\n w(` creator: ${poll.creator}\\n`);\n w(` mode: ${poll.mode}${poll.mode === 'secret' ? (reveal ? ' (revealed)' : ' (awaiting reveal)') : ''}\\n`);\n w(` weight: ${poll.weight_mode}\\n`);\n w(` threshold: ${poll.min_sats} sat / ${poll.min_days} d\\n`);\n w(` deadline: ${poll.deadline}\\n`);\n w(` snapshot: ${snapshot}\\n`);\n w(` ballots: ${ballots.length}\\n`);\n w(`\\n`);\n\n if (result.state === 'awaiting_reveal') {\n w(` STATE: awaiting reveal — secret-mode poll, creator has not yet published reveal_sk\\n\\n`);\n return;\n }\n\n w(` STATE: tallied\\n`);\n w(` turnout: ${result.turnout.voters} voters, weight ${result.turnout.weight.toLocaleString()}\\n\\n`);\n\n // Sort options by poll.options order\n const total = result.turnout.weight;\n const maxLabel = Math.max(...poll.options.map((o) => o.label.length));\n for (const opt of poll.options) {\n const wgt = result.tallies[opt.id] ?? 0;\n const pct = total > 0 ? (wgt / total) * 100 : 0;\n const barLen = total > 0 ? Math.round((wgt / total) * 30) : 0;\n const bar = '█'.repeat(barLen) + '·'.repeat(30 - barLen);\n w(` ${opt.label.padEnd(maxLabel)} ${bar} ${wgt.toLocaleString().padStart(12)} ${pct.toFixed(1).padStart(5)}%\\n`);\n }\n w(`\\n`);\n}\n","// oc-vote verify <poll_id> — fetch poll + ballots, verify every BIP-322 signature, report.\n\nimport { ballotId as computeBallotId, type Ballot } from '@orangecheck/vote-core';\n\nimport { bip322Verify } from '../bip322.js';\nimport { DEFAULT_RELAYS, fetchBallotEvents, fetchPollEvents } from '../nostr.js';\nimport { selectPoll } from '../select.js';\n\nexport interface VerifyOptions {\n pollId: string;\n relays?: string[];\n json?: boolean;\n}\n\nexport async function runVerify(opts: VerifyOptions): Promise<void> {\n const pid = opts.pollId;\n if (!/^[0-9a-f]{64}$/.test(pid)) {\n throw new Error('poll id must be 64 hex chars');\n }\n const relays = opts.relays ?? DEFAULT_RELAYS;\n\n const [pollEvents, ballotEvents] = await Promise.all([\n fetchPollEvents(pid, relays),\n fetchBallotEvents(pid, relays),\n ]);\n const selected = await selectPoll(pollEvents, pid, bip322Verify);\n if (!selected) throw new Error('poll not found');\n\n const mod = (await import('bip322-js')) as unknown as {\n Verifier?: { verifySignature(a: string, m: string, s: string): boolean };\n default?: {\n Verifier?: { verifySignature(a: string, m: string, s: string): boolean };\n };\n };\n const Verifier = mod.Verifier ?? mod.default?.Verifier;\n if (!Verifier) throw new Error('bip322 verifier unavailable');\n\n const pollSigOk = selected.signatureValid;\n\n const ballots: Ballot[] = [];\n const seen = new Set<string>();\n const ballotResults: Array<{ voter: string; ballot_id: string; ok: boolean }> = [];\n for (const ev of ballotEvents) {\n try {\n const b = JSON.parse(ev.content) as Ballot;\n if (b.poll_id !== pid) continue;\n const bid = computeBallotId(b);\n if (seen.has(bid)) continue;\n seen.add(bid);\n ballots.push(b);\n const ok = Verifier.verifySignature(b.voter, bid, b.sig.value);\n ballotResults.push({ voter: b.voter, ballot_id: bid, ok });\n } catch {\n // skip\n }\n }\n\n const okCount = ballotResults.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n poll_id: pid,\n poll_signature_valid: pollSigOk,\n ballot_count: ballots.length,\n ballots_valid: okCount,\n ballots_invalid: ballots.length - okCount,\n ballot_details: ballotResults,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n poll_id: ${pid}\\n`);\n w(` poll signature: ${pollSigOk ? 'VALID ✓' : 'INVALID ✗'}\\n`);\n w(` ballots observed: ${ballots.length}\\n`);\n w(` ballots valid: ${okCount}\\n`);\n w(` ballots invalid: ${ballots.length - okCount}\\n\\n`);\n if (ballots.length - okCount > 0) {\n w(` invalid ballots:\\n`);\n for (const r of ballotResults.filter((x) => !x.ok)) {\n w(` - ${r.voter} · ${r.ballot_id}\\n`);\n }\n w(`\\n`);\n }\n}\n","// oc-vote vote — build + sign + publish a ballot.\n//\n// Public mode: just --poll --voter --option --sig.\n// Secret mode: additionally --reveal-pk (from the poll); we seal the option\n// id into an oc-lock envelope + commit it per SPEC §4.4.\n\nimport { seal } from '@orangecheck/lock-core';\nimport { utf8Encode } from '@orangecheck/lock-crypto';\nimport { ballotId, commit } from '@orangecheck/vote-core';\nimport type { Ballot } from '@orangecheck/vote-core';\n\nimport { bip322Verify } from '../bip322.js';\n\nimport { buildBallotEvent } from '../events.js';\nimport { DEFAULT_RELAYS, fetchPollEvents, publishEvent } from '../nostr.js';\nimport { selectPoll } from '../select.js';\nimport { promptForSignature } from '../sig.js';\n\nexport interface VoteOptions {\n pollId: string;\n voter: string;\n option: string;\n sig?: string;\n relays?: string[];\n dryRun?: boolean;\n json?: boolean;\n}\n\nexport async function runVote(opts: VoteOptions): Promise<void> {\n if (!/^[0-9a-f]{64}$/.test(opts.pollId)) {\n throw new Error('poll id must be 64 hex chars');\n }\n\n // Fetch the poll from relays so we know the mode + options + reveal_pk.\n const events = await fetchPollEvents(opts.pollId, opts.relays ?? DEFAULT_RELAYS);\n const selected = await selectPoll(events, opts.pollId, bip322Verify);\n if (!selected) throw new Error('poll not found on relays');\n if (!selected.signatureValid) {\n throw new Error('poll signature does not verify against its creator (SPEC §10.1)');\n }\n const poll = selected.poll;\n if (poll.mode === 'public' && !poll.options.some((o) => o.id === opts.option)) {\n throw new Error(`option \"${opts.option}\" not in poll options (${poll.options.map((o) => o.id).join(', ')})`);\n }\n\n let ballotOption: string | null = opts.option;\n let secret: Ballot['secret'] = null;\n\n if (poll.mode === 'secret') {\n if (!poll.reveal_pk) throw new Error('secret-mode poll missing reveal_pk');\n const envelope = await seal({\n payload: utf8Encode(opts.option),\n sender: { address: opts.voter, signMessage: async () => '' },\n recipients: [\n {\n address: `oc-vote:reveal:${opts.pollId}`,\n device_id: 'reveal',\n device_pk: poll.reveal_pk,\n },\n ],\n });\n ballotOption = null;\n secret = {\n envelope: envelope as unknown as Record<string, unknown>,\n commit: commit(opts.pollId, opts.voter, opts.option),\n };\n }\n\n const draft: Ballot = {\n v: 0,\n kind: 'oc-vote/ballot',\n poll_id: opts.pollId,\n voter: opts.voter,\n option: ballotOption,\n attestation_id: null,\n secret,\n created_at: new Date().toISOString().replace(/\\.\\d+Z$/, 'Z'),\n sig: { alg: 'bip322', pubkey: opts.voter, value: '' },\n };\n\n const bid = ballotId(draft);\n\n if (opts.dryRun) {\n process.stdout.write(JSON.stringify({ ballot_id: bid, ballot: draft }, null, 2) + '\\n');\n return;\n }\n\n const sigValue = await promptForSignature(opts.voter, bid, opts.sig);\n draft.sig.value = sigValue;\n\n const pub = buildBallotEvent(draft);\n const results = await publishEvent(pub, opts.relays ?? DEFAULT_RELAYS);\n const okCount = results.filter((r) => r.ok).length;\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n ballot_id: bid,\n published: okCount,\n total: results.length,\n relays: results,\n ballot: draft,\n },\n null,\n 2\n ) + '\\n'\n );\n return;\n }\n\n const w = (s: string) => process.stdout.write(s);\n w(`\\n ballot_id: ${bid}\\n`);\n w(` poll: ${poll.question}\\n`);\n w(` voter: ${opts.voter}\\n`);\n w(` option: ${opts.option}${poll.mode === 'secret' ? ' (sealed)' : ''}\\n`);\n w(` published: ${okCount}/${results.length} relays\\n`);\n for (const r of results) {\n w(` ${r.ok ? '✓' : '✗'} ${r.relay}${r.reason ? ` (${r.reason})` : ''}\\n`);\n }\n w(`\\n`);\n}\n","/**\n * @orangecheck/vote-cli — shell interface to OC Vote.\n *\n * read:\n * oc-vote tally <poll_id> run the pure tally function\n * oc-vote verify <poll_id> verify every BIP-322 signature\n * oc-vote show <poll_id> poll metadata + ballot count\n * oc-vote discover list recent polls across relays\n *\n * write (headless — signature via --sig or interactive paste):\n * oc-vote create build + sign + publish a poll\n * oc-vote vote cast a ballot (public or secret)\n * oc-vote reveal publish the reveal event\n *\n * utility:\n * oc-vote gen-reveal-key mint a fresh X25519 pair\n *\n * Defaults: canonical 4-relay set + mempool.space for UTXOs.\n * Swap via --relay wss://... (repeatable) and --mempool-base https://...\n */\n\nimport { Command, Option } from 'commander';\n\nimport { runCreate } from './commands/create.js';\nimport { runDiscover } from './commands/discover.js';\nimport { runGenRevealKey } from './commands/gen-reveal-key.js';\nimport { runReveal } from './commands/reveal.js';\nimport { runShow } from './commands/show.js';\nimport { runTally } from './commands/tally.js';\nimport { runVerify } from './commands/verify.js';\nimport { runVote } from './commands/vote.js';\n\nconst program = new Command();\n\nfunction collectRelay(v: string, prev: string[] = []): string[] {\n return [...prev, v];\n}\n\nfunction collectOption(v: string, prev: { id: string; label: string }[] = []) {\n const [id, ...rest] = v.split(':');\n if (!id) throw new Error(`--option requires \"id\" or \"id:label\"`);\n const label = rest.length ? rest.join(':') : id;\n return [...prev, { id, label }];\n}\n\nfunction parseDeadline(raw: string): string {\n const rel = raw.match(/^\\+(\\d+)([dh])$/);\n if (rel) {\n const n = Number.parseInt(rel[1]!, 10);\n const unit = rel[2];\n const ms = (unit === 'd' ? n * 24 : n) * 3600 * 1000;\n const d = new Date(Date.now() + ms);\n return d.toISOString().replace(/\\.\\d+Z$/, 'Z');\n }\n const parsed = new Date(raw);\n if (Number.isNaN(parsed.getTime())) throw new Error(`invalid deadline: ${raw}`);\n return parsed.toISOString().replace(/\\.\\d+Z$/, 'Z');\n}\n\nfunction parseSnapshot(raw: string): number | 'deadline' {\n if (raw === 'deadline') return 'deadline';\n const n = Number.parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) throw new Error(`invalid snapshot block: ${raw}`);\n return n;\n}\n\nprogram\n .name('oc-vote')\n .description('OC Vote — sovereign signaling for the open web')\n .version('0.2.0');\n\n// ── read ──────────────────────────────────────────────────────────────────\n\nprogram\n .command('tally <poll_id>')\n .description('Fetch the poll + ballots and run the pure tally function')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--mempool-base <url>', 'mempool.space-compatible base URL', 'https://mempool.space/api')\n .option('--snapshot <height>', 'Override snapshot block (integer)')\n .option('--no-verify', 'Skip BIP-322 signature verification')\n .option('--json', 'Emit JSON instead of human-readable output')\n .action(async (pollId: string, opts: Record<string, unknown>) => {\n await runTally({\n pollId,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n mempoolBase: opts.mempoolBase as string,\n json: Boolean(opts.json),\n verify: opts.verify !== false,\n snapshotBlock: opts.snapshot ? Number.parseInt(String(opts.snapshot), 10) : undefined,\n });\n });\n\nprogram\n .command('verify <poll_id>')\n .description('Verify every BIP-322 signature on the poll + its ballots')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--json', 'Emit JSON')\n .action(async (pollId: string, opts: Record<string, unknown>) => {\n await runVerify({\n pollId,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('show <poll_id>')\n .description('Print the poll metadata + ballot count without running the tally')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--json', 'Emit JSON')\n .action(async (pollId: string, opts: Record<string, unknown>) => {\n await runShow({\n pollId,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('discover')\n .description('List recent polls across the default relay set')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--limit <n>', 'max polls to return', '30')\n .option('--open-only', 'hide polls whose deadline has passed')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n await runDiscover({\n limit: Number.parseInt(String(opts.limit ?? '30'), 10),\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n json: Boolean(opts.json),\n openOnly: Boolean(opts.openOnly),\n });\n });\n\n// ── write ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('create')\n .description('Build + sign + publish a poll')\n .requiredOption('--creator <btc-addr>', 'Bitcoin address of the poll creator')\n .requiredOption('--question <text>', 'poll question')\n .requiredOption(\n '--option <id:label>',\n 'poll option; repeatable; \"id\" or \"id:label\"',\n collectOption,\n [] as { id: string; label: string }[]\n )\n .option('--deadline <iso8601 | +Nd | +Nh>', 'deadline in UTC', '+7d')\n .option('--snapshot <height | deadline>', 'snapshot block', 'deadline')\n .addOption(\n new Option('--weight-mode <mode>', 'weight function')\n .choices(['one_per_address', 'sats', 'sats_days'])\n .default('sats')\n )\n .option('--cap-days <n>', 'age cap in days (required for sats_days)', '180')\n .option('--min-sats <n>', 'minimum sat threshold', '0')\n .option('--min-days <n>', 'minimum UTXO-age threshold', '0')\n .addOption(\n new Option('--tiebreak <mode>', 'per-voter dedup rule')\n .choices(['latest', 'first'])\n .default('latest')\n )\n .addOption(\n new Option('--mode <mode>', 'ballot mode')\n .choices(['public', 'secret'])\n .default('public')\n )\n .option('--notes <text>', 'free-form notes (≤ 2048 bytes)')\n .option('--sig <base64>', 'BIP-322 signature of poll_id; prompts if omitted')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--dry-run', 'print canonical + id; do not sign or publish')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n const mode = opts.mode as 'public' | 'secret';\n const weightMode = opts.weightMode as 'one_per_address' | 'sats' | 'sats_days';\n await runCreate({\n creator: String(opts.creator),\n question: String(opts.question),\n options: opts.option as { id: string; label: string }[],\n deadline: parseDeadline(String(opts.deadline)),\n snapshotBlock: parseSnapshot(String(opts.snapshot)),\n weightMode,\n capDays: weightMode === 'sats_days' ? Number.parseInt(String(opts.capDays), 10) : undefined,\n minSats: Number.parseInt(String(opts.minSats), 10),\n minDays: Number.parseInt(String(opts.minDays), 10),\n tiebreak: opts.tiebreak as 'latest' | 'first',\n mode,\n notes: opts.notes ? String(opts.notes) : undefined,\n sig: opts.sig ? String(opts.sig) : undefined,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n dryRun: Boolean(opts.dryRun),\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('vote')\n .description('Cast a ballot on a poll')\n .requiredOption('--poll <poll_id>', '64-hex poll id')\n .requiredOption('--voter <btc-addr>', 'voter Bitcoin address')\n .requiredOption('--option <id>', 'chosen option id')\n .option('--sig <base64>', 'BIP-322 signature of ballot_id; prompts if omitted')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--dry-run', 'print canonical + id; do not sign or publish')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n await runVote({\n pollId: String(opts.poll),\n voter: String(opts.voter),\n option: String(opts.option),\n sig: opts.sig ? String(opts.sig) : undefined,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n dryRun: Boolean(opts.dryRun),\n json: Boolean(opts.json),\n });\n });\n\nprogram\n .command('reveal')\n .description('Publish the reveal event for a secret-mode poll')\n .requiredOption('--poll <poll_id>', '64-hex poll id')\n .requiredOption('--reveal-sk <hex>', '64-hex X25519 secret key')\n .requiredOption('--creator <btc-addr>', 'poll creator address (must match the poll)')\n .option('--sig <base64>', 'BIP-322 signature of reveal_id; prompts if omitted')\n .option('--relay <url>', 'Nostr relay (repeatable)', collectRelay, [] as string[])\n .option('--force', 'publish even before deadline / even if a reveal exists')\n .option('--dry-run', 'print reveal + id; do not sign or publish')\n .option('--json', 'Emit JSON')\n .action(async (opts: Record<string, unknown>) => {\n await runReveal({\n pollId: String(opts.poll),\n revealSk: String(opts.revealSk),\n creator: String(opts.creator),\n sig: opts.sig ? String(opts.sig) : undefined,\n relays: (opts.relay as string[] | undefined)?.length ? (opts.relay as string[]) : undefined,\n force: Boolean(opts.force),\n dryRun: Boolean(opts.dryRun),\n json: Boolean(opts.json),\n });\n });\n\n// ── utility ───────────────────────────────────────────────────────────────\n\nprogram\n .command('gen-reveal-key')\n .description('Mint a fresh X25519 keypair for secret-mode polls')\n .option('--json', 'Emit JSON')\n .action((opts: Record<string, unknown>) => {\n runGenRevealKey({ json: Boolean(opts.json) });\n });\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`oc-vote: ${msg}\\n`);\n process.exit(1);\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orangecheck/vote-cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Command-line tool for OC Vote \u2014 tally, verify, and inspect polls from your shell.",
5
5
  "keywords": [
6
6
  "oc-vote",
@@ -36,13 +36,14 @@
36
36
  "build": "tsup",
37
37
  "dev": "tsup --watch",
38
38
  "type-check": "tsc --noEmit",
39
+ "test": "vitest run",
39
40
  "clean": "rm -rf dist",
40
41
  "prepublishOnly": "npm run clean && npm run build"
41
42
  },
42
43
  "dependencies": {
43
44
  "@noble/curves": "^1.6.0",
44
45
  "@noble/hashes": "^1.5.0",
45
- "@orangecheck/vote-core": "^0.1.1",
46
+ "@orangecheck/vote-core": "^1.3.0",
46
47
  "@orangecheck/lock-core": "^0.1.0",
47
48
  "@orangecheck/lock-crypto": "^0.1.0",
48
49
  "bip322-js": "^3.0.0",
@@ -53,7 +54,8 @@
53
54
  "@types/node": "^22.10.2",
54
55
  "@types/ws": "^8.5.12",
55
56
  "tsup": "^8.3.5",
56
- "typescript": "^5.7.2"
57
+ "typescript": "^5.7.2",
58
+ "vitest": "^4.1.11"
57
59
  },
58
60
  "publishConfig": {
59
61
  "access": "public"