Skip to content

feat(jobs): expose ash/ocr hex on awaiting_signature JobStatus result - #195

Merged
TaprootFreak merged 2 commits into
stagingfrom
feature/jobs-awaiting-signature-ash-ocr
Jun 4, 2026
Merged

feat(jobs): expose ash/ocr hex on awaiting_signature JobStatus result#195
TaprootFreak merged 2 commits into
stagingfrom
feature/jobs-awaiting-signature-ash-ocr

Conversation

@TaprootFreak

Copy link
Copy Markdown
Contributor

Why

A pure-TypeScript wallet (@zkcoins/sdk) needs account_state_hash (ash) + output_coins_root (ocr) to sign the send commitment. Until now the awaiting_signature JobStatus carried only proof_id; ash/ocr were reachable solely via GET /api/proof/{id} as a binary bincode CoinProof blob that only Rust/wasm can decode. That breaks the thin-client rule (wallet = key only, trusts the node, no heavy client-side logic; see CONTRIBUTING "Trust model").

What

When a send job transitions to awaiting_signature, ash + ocr are written as lowercase hex into the job result, so GET /api/jobs/:id and the SSE stream surface them under result.account_state_hash / result.output_coins_root — the exact keys the SDK's pay() already reads. This closes the pure-TS commit loop without any binary proof decode.

Where ash/ocr come from

The same source the completed mint/commit results use: ProofData::from_field_elements over the send proof's public inputs, hex-encoded via digest_to_bytes. Extraction is factored into a shared flow::send_commit_hashes helper that mint_flow, send_flow, and commit_flow all call, so the hex is bit-identical to what createCommitment expects and commit_flow re-derives from the same proof.

Additive / minimal

  • completed result shape, top-level proof_id, and the JobStatusResponse wire schema (result is already free-form JSON) are unchanged.
  • No new endpoint, env var, or migration.
  • set_awaiting_signature stores the result in the existing response_body column (the terminal complete body overwrites it later). The GET handler and SSE initial frame now surface result for awaiting_signature in addition to completed; a post-restart resume re-publishes the persisted hashes.

Tests / gates

  • api_remote send roundtrip now asserts the awaiting_signature result hex equals the proof-decoded ash/ocr (contract check; runs in deploy-dev / ci:full).
  • job_store + router unit tests cover the new persistence + snapshot paths.
  • Local coverage gate green: 100% lines + 100% functions on the node package (442 tests passed), cargo fmt --check, clippy (MVP + all-features) -D warnings, and cargo check --workspace --all-features all clean.

…_signature job result

A pure-TypeScript wallet must know account_state_hash (ash) and
output_coins_root (ocr) to sign the send commitment, but until now the
awaiting_signature JobStatus carried only proof_id. The hashes were
reachable solely via GET /api/proof/{id} as a binary bincode CoinProof
blob that only Rust/wasm can decode — breaking the thin-client rule
(wallet = key only, trusts the node, no heavy client-side logic).

This change writes ash + ocr as lowercase hex into the job result when a
send job transitions to awaiting_signature, so GET /api/jobs/:id and the
SSE stream surface them under result.account_state_hash /
result.output_coins_root — the exact keys @zkcoins/sdk's pay() reads.

ash/ocr come from the same source the completed mint/commit results use:
ProofData::from_field_elements over the send proof's public inputs,
hex-encoded via digest_to_bytes. Extraction is factored into a shared
flow::send_commit_hashes helper that mint_flow, send_flow, and
commit_flow all call, so the hex is bit-identical to what
createCommitment expects and commit_flow re-derives.

Purely additive: completed result shape, proof_id top-level field, and
the JobStatusResponse wire schema (result is already free-form JSON) are
unchanged. No new endpoint, env var, or migration. set_awaiting_signature
stores the result in the existing response_body column (the terminal
complete body overwrites it later); the GET handler and SSE initial frame
now surface result for awaiting_signature in addition to completed, and a
post-restart resume re-publishes the persisted hashes.

Tests: api_remote send roundtrip asserts the awaiting_signature result
hex equals the proof-decoded ash/ocr; job_store + router unit tests cover
the new persistence and snapshot paths (100% line + function gate green).
@TaprootFreak TaprootFreak added the ci:full Trigger heavy CI jobs (Server + Shared Tests + Coverage Gate, ~60-90 min on M3 Ultra) label Jun 3, 2026
@TaprootFreak
TaprootFreak marked this pull request as ready for review June 3, 2026 16:01
@TaprootFreak TaprootFreak added ci:full Trigger heavy CI jobs (Server + Shared Tests + Coverage Gate, ~60-90 min on M3 Ultra) and removed ci:full Trigger heavy CI jobs (Server + Shared Tests + Coverage Gate, ~60-90 min on M3 Ultra) labels Jun 3, 2026
@TaprootFreak
TaprootFreak merged commit 9d174d2 into staging Jun 4, 2026
22 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:full Trigger heavy CI jobs (Server + Shared Tests + Coverage Gate, ~60-90 min on M3 Ultra)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant