Skip to content

feat: pox-5 register-signer ingestion and staking signer endpoints#2585

Merged
rafa-stacks merged 3 commits into
pox5from
pox5--staking-signers
Jun 17, 2026
Merged

feat: pox-5 register-signer ingestion and staking signer endpoints#2585
rafa-stacks merged 3 commits into
pox5from
pox5--staking-signers

Conversation

@rafa-stacks

@rafa-stacks rafa-stacks commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Description

As an application developer building pox-5 staking UIs, I want to look up the registered staking signers and their current signing keys through the API.

Motivation. The pox-5 register-signer event binds a signer principal to a compressed secp256k1 signing key. The contract stores this in (define-map signers principal (buff 33)) and map-sets on re-registration, so a signer has exactly one current key (latest-wins). Until now this event was an unhandled TODO stub. This PR ingests it, materializes the registry, and exposes it.

What changed:

  1. Ingestionregister-signer is handled in the pox-5 event switch and upserted into a new materialized staking_signers table (one row per signer principal, latest-wins), mirroring the contract semantics. It's a current-state accumulator like stx_locked_balances (no canonical column).
  2. Reorg-saferecomputeStakingSigners runs after the reorg queue drains in markEntitiesCanonical: for each signer touched by a flipped register-signer event, it re-derives the latest canonical registration from pox5_events (the source of truth, which retains every event with full location + canonical), and upserts or deletes. A signer key is latest-wins (not additive), so it's recomputed, not delta-applied — the same approach used for stx_locked_balances.
  3. Endpoints (under the existing /staking namespace, in a new staking-signers.ts route module):
    • GET /extended/v3/staking/signers — cursor-paginated list of registered signers (by signer principal).
    • GET /extended/v3/staking/signers/:principal — a single signer plus the block position of its registration transaction (joined in from txs).

How this impacts application developers

Two new read endpoints. The list returns just { signer, signer_key } per signer; the detail endpoint adds the registration transaction (its tx_id plus block / bitcoin_block positions), consistent with the bond detail endpoint.

// GET /extended/v3/staking/signers
{
  "limit": 100,
  "total": 1,
  "cursor": { "next": null, "previous": null, "current": "SP….signer-manager" },
  "results": [
    { "signer": "SP….signer-manager", "signer_key": "0x02…" }
  ]
}
// GET /extended/v3/staking/signers/:principal
{
  "signer": "SP….signer-manager",
  "signer_key": "0x02…",
  "transaction": {
    "tx_id": "0x…",
    "block": { "height": 162, "hash": "0x…", "index_hash": "0x…", "time": 1714000000, "tx_index": 3 },
    "bitcoin_block": { "height": 700123, "time": 1713999000 }
  }
}

Type of Change

  • New feature

Does this introduce a breaking change?

No — two additive read endpoints and one new table, on the unreleased pox-5 line.

Are documentation updates required?

  • openapi.yaml is intentionally not regenerated here; it's produced by the release process.

Testing information

  1. Included — simulated-ingestion tests in tests/api/pox5/signers.test.ts (no live chain): a registration appears in the list; re-registration rotates the key (single row, latest-wins); cursor pagination; orphaning the registration block removes the signer; orphaning a re-registration reverts to the prior key; the detail endpoint returns the joined transaction block position; 404 for an unregistered principal. Full pox5 suite passes.
  2. N/A (feature).
  3. Affected paths: pox-5 register-signer ingestion + markEntitiesCanonical reorg recompute in pg-write-store.ts; the v3 signer read methods; the new signer route/schema/serializer.
  4. grant-signer-key / revoke-signer-grant remain TODO stubs (separate authorization layer), scoped out of this pass.
  5. Watch out for: the detail endpoint INNER JOINs staking_signers to the canonical txs row for the registration's block position. staking_signers deliberately stores only tx_id / block_height / burn_block_height (current-state accumulator); the block hash / index hash / time / tx_index / burn block time are joined on read, and block_height / burn_block_height feed the block / bitcoin_block heights.

DB tables added

  • staking_signers (new) — materialized pox-5 signer registry: signer (PK), signer_key, tx_id, block_height, burn_block_height.

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.47090% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
migrations/1779800000006_staking-signers.ts 97.82% 0 Missing and 1 partial ⚠️
src/api/routes/v3/staking-signers.ts 98.88% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@rafa-stacks rafa-stacks merged commit 1815bfb into pox5 Jun 17, 2026
20 checks passed
@rafa-stacks rafa-stacks deleted the pox5--staking-signers branch June 17, 2026 22:02
@github-project-automation github-project-automation Bot moved this to ✅ Done in API Board Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant