# Verify Router-stamped Programmable launches

> Read-only integration guide for Router-stamped Programmable Classic and Programmable Custom provenance on Ethereum.

Live manifest: https://developers.programmable.family/api/v2/manifest
Frozen Router ABI: https://developers.programmable.family/abis/ethereum/programmable-launch-stamp-router-v1.json
ABI SHA-256: sha256:bb4e728e9f9c850eb01f928e8a798ac206a82e241a8d93b3b3c686635c88ed86
GitHub reference: https://github.com/0xprogrammable/developers/blob/main/docs/reference/launch-stamp.md
Programmable documentation endpoints: no authentication
Ethereum RPC authentication: provider-specific

## Scope

Only launches executed and stamped through this Router inside its published block range have Router V1 provenance. Launches before `startBlock`, and direct factory calls outside the Router even when later, do not.

After bootstrap from the manifest and ABI, point verification requires only an Ethereum provider. A Programmable launch-feed API, indexer, Supabase project, or application server is not required. Continuous event indexing is optional.

## Router binding

| Field | Canonical value |
| --- | --- |
| `status` | `live` |
| `chainId` | `1` |
| `address` | `0x8622DD5bAb44185f2A458ac90384Ac99248f8d56` |
| `startBlock` | `25717612` |
| `endBlock` | `null` |
| `runtimeCodeHash` | `0x40e27ecf201761d5eb66bc4f2d5c6124831ef078d7baf458ca5f41b1a8108546` |
| `abiSha256` | `sha256:bb4e728e9f9c850eb01f928e8a798ac206a82e241a8d93b3b3c686635c88ed86` |
| `finalityConfirmations` | `64` |

Read the stable discovery document, follow `manifestUrl`, then use `launchStampRouter` from the live manifest. Verify the downloaded ABI bytes against `abiSha256` before the first lookup. At the selected canonical block, also verify the Router runtime and immutable binding getters from the manifest.

## Launch kinds

Classify only from the returned stamp record. Names, tickers, logos, creator metadata, factory lookalikes, and shared hook addresses are not provenance.

| Value | Enum | Public label |
| --- | --- | --- |
| `1` | `CustomGraph` | Programmable Custom |
| `2` | `Classic` | Programmable Classic |

`LaunchKindV1.Invalid = 0` is never a Programmable launch classification.

## Point verification

Resolve one finalized canonical block. Use that block for every runtime, binding, lookup, record, and proof read.

Remote RPC URLs must use HTTPS. Plain HTTP is accepted only for loopback development endpoints.

### Canonical preflight

1. Fetch the official discovery document and manifest. Require `status: live`, or `retired` for a historical read inside the published block range.
2. Require the complete manifest activation data: finalized canary evidence, chain and Router binding, all six immutable binding fields, block range, finality policy, runtime and ABI hashes, the sole payable atomic signature and selector, every getter descriptor, and every event topic and indexed layout.
3. Resolve the chosen block to one concrete number and opening hash. Enforce `startBlock`, `endBlock` when present, and the published confirmation policy for explicit block-number reads.
4. Require `eth_chainId == manifest.chainId`. At the same block, require the Router runtime Keccak-256 and the exact downloaded ABI byte SHA-256 to match the manifest. Derive and validate every advertised getter selector, event topic, indexed layout, and the sole payable atomic selector from that ABI.
5. Call `CHAIN_ID()` and all six immutable address/runtime binding getters. Require exact manifest matches, then verify `eth_getCode` runtime hashes for the permit authority, Graph Factory, and PoolManager.

### Resolve the launch ID

### Token

1. Call `launchIdByToken(address)`.
2. A successful zero result is a `NOT_STAMPED` candidate. Complete any required closing canonical-block check before returning it.

### Uniswap v4 pool

1. Call `launchIdByPool(address,bytes32)` with `(PoolManager, poolId)`.
2. A successful zero result is a `NOT_STAMPED` candidate. Complete any required closing canonical-block check before returning it.

### Exclusive component

1. Call `launchIdByComponent(address)`. Use this path only for a component explicitly exclusive to one launch.
2. The shared Classic hook is not a launch identifier.
3. A successful zero result is a `NOT_STAMPED` candidate. Complete any required closing canonical-block check before returning it.

### Validate a nonzero result

1. Call `launchStamp(bytes32)` with the nonzero launch ID and require a supported nonzero `record.kind`.
2. Require valid address encoding for `launchWallet`, `token`, `hook`, `poolManager`, and `routeLauncher`. Require nonzero `poolId`, `poolKeyHash`, `componentSetHash`, `routePayloadHash`, `routeLauncherRuntimeCodeHash`, `expectedResultHash`, `permitDigest`, and `stampHash`.
3. Require exact queried identity: `record.token == token`, or exact equality with `record.poolManager` and `record.poolId`. The record PoolManager must also equal the immutable manifest binding.
4. For a token or exclusive component, call `stampProof(address)` and require the same launch ID and `record.stampHash`. Require a nonzero recorded `componentRuntimeCodeHash(address)`.
5. For `CustomGraph`, require `record.routeLauncher` and `record.routeLauncherRuntimeCodeHash` to match the immutable Graph Factory binding. For `Classic`, retain the permit-bound launcher and runtime recorded in the stamp; do not invent a Classic immutable.
6. A current component-runtime comparison is a separate drift signal. A mismatch does not change the historical Router-provenance result.
7. Prefer EIP-1898 `{ blockHash, requireCanonical: true }` reads. If the provider requires number-bound reads, refetch that height and require its closing hash to equal the opening hash before returning `STAMPED` or `NOT_STAMPED`.
8. Classify only from `record.kind`. Return `STAMPED` only after every required gate above succeeds.

### Result states

- `STAMPED`: every manifest, canonical-block, runtime, ABI-descriptor, immutable-binding, lookup, record, identity, nonzero-field, proof, route, and any required closing-hash gate succeeds. Current component-runtime equality is reported separately.
- `NOT_STAMPED`: the canonical token, pool, or exclusive-component lookup succeeds and returns zero after any required closing canonical-block check.
- `UNAVAILABLE`: the Router is not live for the requested block, the chain is inactive, or required manifest activation data is incomplete.
- `INDETERMINATE`: RPC, ABI, runtime, block, decoding, or cross-check evidence is incomplete or inconsistent.

Only a successful canonical zero lookup is `NOT_STAMPED`. A timeout, pruned block, malformed response, chain mismatch, unavailable finalized block, or inconsistent nonzero response is `INDETERMINATE`, not an unsafe claim. `ORPHANED` is an event-observation or reorg state, not a point-verification outcome.

## Discover new launches when needed

Point verification does not require an indexer. If you need continuous discovery, scan only the canonical Router from `startBlock`, treat logs as candidates, and establish provenance with the point verifier.

| Event | Full signature | topic0 |
| --- | --- | --- |
| `ProgrammableLaunchStampedV1` | `ProgrammableLaunchStampedV1(bytes32,address,address,address,bytes32,bytes32)` | `0x6cf479a102f1eebc9244f48f8d68f6aa52b4c5a4516318df58ba46614a5b14f2` |
| `ProgrammableLaunchRouteStampedV1` | `ProgrammableLaunchRouteStampedV1(bytes32,uint8,bytes32,bytes32,bytes32)` | `0x45e7cc355b63ca67d6278a0d8d23470ce2a0741a9c60283d7dee712df7a877a5` |
| `ProgrammableComponentStampedV1` | `ProgrammableComponentStampedV1(bytes32,address,uint8,bytes32)` | `0x8147265e7396d6400cee8d049456a1f7438fdfbe2a7c81c976d51ba67e52ff4b` |

1. Require `eth_chainId == 0x1`, the exact Router emitter, full topic signatures, runtime, ABI, bindings, block range, and finality policy.
2. Backfill bounded `eth_getLogs` chunks from `startBlock` through a finalized boundary. Respect `endBlock` if a future manifest retires this Router.
3. Persist block number and hash, transaction hash and index, and log index as the idempotency key.
4. Correlate the three event types by `launchId`; then reproduce the candidate with getter reads at the same canonical block.
5. Advance a durable checkpoint only through finality. Explicit block reads require at least 64 confirmations.
6. Replay an overlap on every run. Prefer EIP-1898 reads with `requireCanonical: true`; after a reorg, rewind to the last common finalized checkpoint and replay.
7. Begin polling or subscription from the overlapping checkpoint so backfill and live follow have no gap.

## Canonical resources

- [Discovery document](https://developers.programmable.family/.well-known/programmable.json) — stable entry point that supplies `manifestUrl`.
- [Live manifest](https://developers.programmable.family/api/v2/manifest) — chain, Router, start block, runtime, immutable bindings, event topics, ABI URL, and ABI digest.
- [Hosted Router ABI](https://developers.programmable.family/abis/ethereum/programmable-launch-stamp-router-v1.json) — hash the exact downloaded bytes and match `sha256:bb4e728e9f9c850eb01f928e8a798ac206a82e241a8d93b3b3c686635c88ed86`.
- [GitHub Router reference](https://github.com/0xprogrammable/developers/blob/main/docs/reference/launch-stamp.md) — complete point-verification specification and finalized PCAN test case.
- [Terminal guide](https://github.com/0xprogrammable/developers/blob/main/docs/guides/terminals-and-scanners.md) — backfill, live follow, overlap, reorg, and finality handling.
- [JSON-RPC verifier](https://github.com/0xprogrammable/developers/blob/main/examples/verify-launch-stamp.mjs) — dependency-light implementation.
- [viem verifier](https://github.com/0xprogrammable/developers/blob/main/examples/verify-launch-stamp-viem.ts) — typed application implementation.

## Finalized PCAN vector

Use this CustomGraph launch as the end-to-end integration vector:

- transaction: `0xc07b4e70233534a1d4f435ffc9a636ed5f542f4aedcde35052c58224f378b612`
- block: `25717953`
- launchId: `0x5a52180427785716bff0a36218dde89f0459db265d0c2bdfcfde81a8fe733c92`
- stampHash: `0x06cb71b38d9b8b1dd1ffcdb00f31c774be36f5473979c3831d5fd0c96cdaa579`
- token: `0x9DEeB39D2590b0cAD5fc473F755C5F97Dcc8f7cE`
- hook: `0xEBa46f25DfF528141dE5317109Acb5A989296044`
- initializer: `0x87B108848B444bC44A01734D62C7be4a2fA64983`
- PoolManager: `0x000000000004444c5dc75cB358380D2e3dE08A90`
- poolId: `0x5c5a3ebee6840640642ba2bea526621a4962d2c89c388c36a2edb4725802a229`
- launchKind: `1` (Programmable Custom)

The token, pool, and exclusive components resolve to the same launch ID and stamp hash. Generic token or pool discovery by a third party is separate from verified Programmable provenance.

## What verification proves

A Router record establishes provenance only after the published address, runtime, binding, lookup, and cross-check requirements pass. For its exact recorded pool, successful verification also establishes initialization during the same atomic launch transaction.

It does not establish safety, tradability, current liquidity or pool state, audit coverage, review status, approval, endorsement, permission to launch, or terminal support. It does not automatically list or label a launch in GMGN, Axiom, FOMO, or any other terminal; each consumer must implement the published verification procedure.

These docs define read-only verification. General public submissions and open wallet self-service are not available. Approved Hookbuilder Applicants can use the gated flow for a prepared release. This reference grants neither access nor launch authorization.