Skip to content

fix(legion): parse the real Chainhooks 2.0 payload shape - #891

Merged
biwasxyz merged 1 commit into
mainfrom
fix/legion-chainhook-payload-shape
Jul 23, 2026
Merged

fix(legion): parse the real Chainhooks 2.0 payload shape#891
biwasxyz merged 1 commit into
mainfrom
fix/legion-chainhook-payload-shape

Conversation

@biwasxyz

Copy link
Copy Markdown
Contributor

The chainhook receiver in #890 was written against classic Chainhook's payload format. Chainhooks 2.0 differs in five places, and every one of them fails silently — the parser finds zero events, returns 200, and the service records a healthy delivery while nothing is indexed.

Caught in production: hook f0f6a9bc reported status: streaming, occurrence_count: 6 with an empty database.

What differs

Taken from @stacks/chainhooks-client's TypeBox schemas rather than the docs:

Classic (what I wrote) 2.0 (actual)
payload.apply payload.event.apply
tx.metadata.receipt.events tx.operations
type: "SmartContractEvent" type: "contract_log"
ev.data.* op.metadata.*
metadata.success === false metadata.status !== "success"

Also

Event values are normalised three ways — already-decoded object, {hex, repr}, or a bare hex string — falling back to the local Clarity codec. Indexing no longer depends on the service honouring decode_clarity_values.

A delivery parsing to zero events now logs a warning. That silence is precisely how this hid.

Tests

Three regression tests built on a delivery shaped to the real schema: nested extraction, contract filtering, and hex fallback. Also asserts an abort_by_post_condition transaction is skipped — an aborted conclude must never render as a conclusion that happened.

502 tests passing.

The receiver was written against classic Chainhook and matched none of the
2.0 delivery format, so every delivery parsed to zero events. Worse, it did
so silently: the handler returned 200, Chainhooks recorded six healthy
occurrences, and nothing was ever indexed.

Five differences, taken from the SDK's own TypeBox schemas rather than the
docs:

  apply/rollback live under `event`, not at the top level
  per-tx events are `operations`, not `metadata.receipt.events`
  the print type is `contract_log`, not `SmartContractEvent`
  fields hang off `metadata`, not `data`
  failure is `metadata.status !== "success"`, not `metadata.success === false`

Event values are also normalised three ways — already-decoded object,
{hex, repr}, or a bare hex string — falling back to the local Clarity codec
so indexing does not depend on the service honouring decode_clarity_values.

A delivery that parses to zero events now logs a warning, since that is
exactly how this failure hid.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@biwasxyz
biwasxyz merged commit f358f14 into main Jul 23, 2026
4 of 6 checks passed
@biwasxyz
biwasxyz deleted the fix/legion-chainhook-payload-shape branch July 23, 2026 16:25
@github-actions

Copy link
Copy Markdown
Contributor

Preview deployed: https://agent-news-staging.hosting-962.workers.dev

This preview uses sample data — beats, signals, and streaks are seeded automatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant