Skip to content

feat(api): add v3 stacks and bitcoin block summary endpoints - #2718

Merged
rafa-stacks merged 10 commits into
mainfrom
claude/v2-endpoints-no-v3-53b252
Oct 20, 2026
Merged

rafa-stacks merged 10 commits into
mainfrom
claude/v2-endpoints-no-v3-53b252

Conversation

@rafa-stacks

@rafa-stacks rafa-stacks commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Adds cursor-paginated v3 block endpoints: GET /extended/v3/blocks, /blocks/{height_or_hash} (block details incl. parent, size and execution cost), /bitcoin-blocks, /bitcoin-blocks/{height_or_hash}, and /bitcoin-blocks/{height_or_hash}/blocks. Stacks block summaries (also used by search and miner rewards) gain tenure height, tx count and their Bitcoin anchor; Bitcoin blocks carry their stored header time (new burn_blocks.burn_block_time), an interpolated or projected time, and their Stacks block and transaction counts; and v3 block times on legacy rows without one now fall back to the Bitcoin block time.

Sample responses

GET /extended/v3/blocks?limit=2
{
  "total": 5,
  "limit": 2,
  "cursor": {
    "next": "3",
    "previous": null,
    "current": "5"
  },
  "results": [
    {
      "height": 5,
      "hash": "0x000000000000000000000000000000000000000000000000000000000000b005",
      "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000005",
      "time": 1760001235,
      "time_iso": "2025-10-09T09:13:55.000Z",
      "tenure_height": 2,
      "tx_count": 4,
      "bitcoin_block": {
        "height": 900002,
        "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba2"
      }
    },
    {
      "height": 4,
      "hash": "0x000000000000000000000000000000000000000000000000000000000000b004",
      "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000004",
      "time": 1760001230,
      "time_iso": "2025-10-09T09:13:50.000Z",
      "tenure_height": 2,
      "tx_count": 1,
      "bitcoin_block": {
        "height": 900002,
        "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba2"
      }
    }
  ]
}
GET /extended/v3/blocks?limit=2&cursor=3
{
  "total": 5,
  "limit": 2,
  "cursor": {
    "next": "1",
    "previous": "5",
    "current": "3"
  },
  "results": [
    {
      "height": 3,
      "hash": "0x000000000000000000000000000000000000000000000000000000000000b003",
      "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000003",
      "time": 1760000040,
      "time_iso": "2025-10-09T08:54:00.000Z",
      "tenure_height": 1,
      "tx_count": 2,
      "bitcoin_block": {
        "height": 900000,
        "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba0"
      }
    },
    {
      "height": 2,
      "hash": "0x000000000000000000000000000000000000000000000000000000000000b002",
      "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000002",
      "time": 1760000035,
      "time_iso": "2025-10-09T08:53:55.000Z",
      "tenure_height": 1,
      "tx_count": 3,
      "bitcoin_block": {
        "height": 900000,
        "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba0"
      }
    }
  ]
}
GET /extended/v3/blocks/5
{
  "height": 5,
  "hash": "0x000000000000000000000000000000000000000000000000000000000000b005",
  "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000005",
  "time": 1760001235,
  "time_iso": "2025-10-09T09:13:55.000Z",
  "tenure_height": 2,
  "tx_count": 4,
  "bitcoin_block": {
    "height": 900002,
    "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba2",
    "time": 1760001200,
    "time_iso": "2025-10-09T09:13:20.000Z"
  },
  "parent_block": {
    "hash": "0x000000000000000000000000000000000000000000000000000000000000b004",
    "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000004"
  },
  "size": 720,
  "execution_cost": {
    "read_count": 48,
    "read_length": 16384,
    "runtime": 100000,
    "write_count": 12,
    "write_length": 2048
  }
}
GET /extended/v3/bitcoin-blocks?limit=3
{
  "total": 4,
  "limit": 3,
  "cursor": {
    "next": "900000",
    "previous": null,
    "current": "900003"
  },
  "results": [
    {
      "height": 900003,
      "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba3",
      "time": null,
      "time_iso": null,
      "projected_time": 1760001800,
      "projected_time_iso": "2025-10-09T09:23:20.000Z",
      "stacks_block_count": 0,
      "tx_count": 0
    },
    {
      "height": 900002,
      "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba2",
      "time": 1760001200,
      "time_iso": "2025-10-09T09:13:20.000Z",
      "projected_time": null,
      "projected_time_iso": null,
      "stacks_block_count": 2,
      "tx_count": 5
    },
    {
      "height": 900001,
      "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba1",
      "time": 1760000600,
      "time_iso": "2025-10-09T09:03:20.000Z",
      "projected_time": null,
      "projected_time_iso": null,
      "stacks_block_count": 0,
      "tx_count": 0
    }
  ]
}
GET /extended/v3/bitcoin-blocks?limit=3&cursor=900000
{
  "total": 4,
  "limit": 3,
  "cursor": {
    "next": null,
    "previous": "900003",
    "current": "900000"
  },
  "results": [
    {
      "height": 900000,
      "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba0",
      "time": 1760000000,
      "time_iso": "2025-10-09T08:53:20.000Z",
      "projected_time": null,
      "projected_time_iso": null,
      "stacks_block_count": 3,
      "tx_count": 6
    }
  ]
}
GET /extended/v3/bitcoin-blocks/900001
{
  "height": 900001,
  "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba1",
  "time": 1760000600,
  "time_iso": "2025-10-09T09:03:20.000Z",
  "projected_time": null,
  "projected_time_iso": null,
  "stacks_block_count": 0,
  "tx_count": 0
}
GET /extended/v3/bitcoin-blocks/900010
{
  "height": 900010,
  "hash": null,
  "time": null,
  "time_iso": null,
  "projected_time": 1760006000,
  "projected_time_iso": "2025-10-09T10:33:20.000Z",
  "stacks_block_count": 0,
  "tx_count": 0
}
GET /extended/v3/bitcoin-blocks/900000/blocks?limit=2
{
  "total": 3,
  "limit": 2,
  "cursor": {
    "next": "1",
    "previous": null,
    "current": "3"
  },
  "results": [
    {
      "height": 3,
      "hash": "0x000000000000000000000000000000000000000000000000000000000000b003",
      "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000003",
      "time": 1760000040,
      "time_iso": "2025-10-09T08:54:00.000Z",
      "tenure_height": 1,
      "tx_count": 2,
      "bitcoin_block": {
        "height": 900000,
        "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba0"
      }
    },
    {
      "height": 2,
      "hash": "0x000000000000000000000000000000000000000000000000000000000000b002",
      "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000002",
      "time": 1760000035,
      "time_iso": "2025-10-09T08:53:55.000Z",
      "tenure_height": 1,
      "tx_count": 3,
      "bitcoin_block": {
        "height": 900000,
        "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba0"
      }
    }
  ]
}
GET /extended/v3/search?q=4&type=block
{
  "results": [
    {
      "type": "block",
      "result": {
        "height": 4,
        "hash": "0x000000000000000000000000000000000000000000000000000000000000b004",
        "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000004",
        "time": 1760001230,
        "time_iso": "2025-10-09T09:13:50.000Z",
        "tenure_height": 2,
        "tx_count": 1,
        "bitcoin_block": {
          "height": 900002,
          "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba2"
        }
      }
    }
  ]
}
GET /extended/v3/principals/ST3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9/mining/rewards
{
  "total": 1,
  "limit": 20,
  "cursor": {
    "next": null,
    "previous": null,
    "current": "5:0"
  },
  "results": [
    {
      "id": "0x0000000000000000000000000000000000000000000000000000000000000005:0",
      "recipient": "ST3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9",
      "miner": "ST3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9",
      "block": {
        "height": 5,
        "hash": "0x000000000000000000000000000000000000000000000000000000000000b005",
        "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000005",
        "time": 1760001235,
        "time_iso": "2025-10-09T09:13:55.000Z",
        "tenure_height": 2,
        "tx_count": 4,
        "bitcoin_block": {
          "height": 900002,
          "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba2"
        }
      },
      "source_block": {
        "height": 1,
        "hash": "0x000000000000000000000000000000000000000000000000000000000000b001",
        "index_hash": "0x0000000000000000000000000000000000000000000000000000000000000001",
        "time": 1760000030,
        "time_iso": "2025-10-09T08:53:50.000Z",
        "tenure_height": 1,
        "tx_count": 1,
        "bitcoin_block": {
          "height": 900000,
          "hash": "0x0000000000000000000000000000000000000000000000000000000000c8bba0"
        }
      },
      "coinbase": "1000000000",
      "fees": "2210",
      "total": "1000002210"
    }
  ]
}

@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Deep-fork cache validators can serve stale responses, and unbounded height parameters can produce database errors.

3 open findings
What changed in this PR

Adds cursor-paginated v3 Stacks and Bitcoin block summary APIs backed by canonical datastore queries and a materialized Bitcoin block count.

Changes:

  • Adds block list, detail, and Bitcoin-to-Stacks block endpoints.
  • Introduces summary schemas, serializers, cursors, and datastore queries.
  • Maintains chain_tip.burn_block_count and adds endpoint coverage.
File Description
tests/​api/​blocks/​block-v3.test.ts Tests Stacks block summaries and pagination.
tests/​api/​blocks/​bitcoin-block-v3.test.ts Tests Bitcoin block endpoints, forks, pagination, and caching.
src/​datastore/​v3/​types.ts Generalizes block summary database types.
src/​datastore/​v3/​pg-store-v3.ts Adds canonical block summary queries.
src/​datastore/​v3/​helpers.ts Parses block-height cursors.
src/​datastore/​pg-write-store.ts Maintains the burn-block counter.
src/​api/​serializers/​v3/​search.ts Reuses block summary serializers.
src/​api/​serializers/​v3/​blocks.ts Serializes block summaries.
src/​api/​schemas/​v3/​entities/​search.ts Reuses the shared Bitcoin block schema.
src/​api/​schemas/​v3/​entities/​common.ts Defines Bitcoin block summaries.
src/​api/​schemas/​v3/​cursors.ts Defines block pagination cursors.
src/​api/​routes/​v3/​blocks.ts Adds Stacks block list and detail routes.
src/​api/​routes/​v3/​bitcoin-blocks.ts Adds Bitcoin block summary routes.
src/​api/​init.ts Registers the Bitcoin block routes.
migrations/​1779800000029_chain-tip-burn-block-count.ts Adds and backfills the burn-block counter.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/api/routes/v3/bitcoin-blocks.ts Resolved
Comment thread src/api/routes/v3/bitcoin-blocks.ts Resolved
Comment thread src/api/routes/v3/blocks.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Timestamp handling remains incorrect for legacy Stacks blocks and same-height Bitcoin replacements.

2 open issues
3 resolved since last review

Review effort: Balanced

Comment thread src/api/serializers/v3/blocks.ts Resolved
Comment thread src/api/serializers/v3/blocks.ts Resolved
@rafa-stacks
rafa-stacks marked this pull request as ready for review October 20, 2026 18:56
@rafa-stacks
rafa-stacks merged commit 5bdb0f3 into main Oct 20, 2026
26 checks passed
@rafa-stacks
rafa-stacks deleted the claude/v2-endpoints-no-v3-53b252 branch October 20, 2026 20:15
@github-project-automation github-project-automation Bot moved this to ✅ Done in API Board Oct 20, 2026

This branch was successfully deployed

1 active deployment
Production — b3b2626f Deployed Oct 20, 2026 by rafa-stacks via build-publish #3856
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants