PATINA docs

Deploy and configure

An indexer, a Bitcoin node, and a deployment record. No keys anywhere in the stack.

What you will know after this page
  • Which of the four components stores anything, and why none of them holds a private key.
  • Every field in the deployment record, and why the mainnet heights stay null until an activation is authorised.
  • The five flags that gate the stack, and the two separate things mainnet needs before a transaction can be built.
  • What status and ready must report during initial sync, and why a 503 there is the correct answer.
  • The seven checks to clear before this indexer answers a public request.

Components

Four processes. The column to read is the last one, because trust runs in one direction, from the frontend at the bottom up to the node, which trusts nobody and validates instead.

What runs where.
ComponentHoldsTrusts
Bitcoin nodeThe chainNothing. It validates.
IndexerDerived PATINA stateIts own node only
App backendNothing durable about PATINAThe indexer it is pointed at
FrontendNothingThe app backend
No key material, anywhere

No component in this list holds a private key, takes custody, or broadcasts a user transaction that the user has not signed. If a deployment ever appears to need a key, stop and find out why, because the design does not require one.

The public site draws the same boundary from the holder's side, in who can do what, and where each one stops.

Requirements

  • A fully validating Bitcoin node on the target network, with RPC reachable from the indexer.
  • Input values available for the transactions being indexed, either from the node or from the indexer's own UTXO tracking.
  • Durable storage for the index. Small next to the chain, but it must survive restarts.
  • The deployment record for the network being indexed.
  • A clock that is roughly correct, for logs. Nothing in the protocol depends on wall clock time.

The deployment record

One record binds this indexer to one network and one window. Copy the file that ships for your network rather than retyping it, then read the notes under the fields before changing any number in it.

{
  "network": "signet",
  "protocol_id": "PTNA",
  "spec_sha256": "...",
  "h_open": 260000,
  "h_close": 264032,
  "grace_end": 268064,
  "min_carrier_founding": 100000,
  "min_carrier_open": 10000,
  "commit_min_age": 144
}
  • Regtest and signet records ship in the protocol repo. Use them as they are.
  • h_close is h_open plus 4032, and grace_end is h_close plus 4032. The three heights are either all set or all null, never some of each.
  • Mainnet values stay unset until activation is authorised.
  • spec_sha256 binds this deployment to an exact specification. Publish it through GET /patina/status and log it with anything you keep.

Feature flags

Every flag fails closed. Unset means the feature does not exist, never that it runs on a guess. Read the right hand column as the state you get when you forget to set something.

Flags that gate the app backend and frontend.
FlagEffect when unset or false
PATINA_ENABLEDThe backend module does not load. No routes exist.
PATINA_INDEXER_URLNothing to proxy. Reads fail closed rather than returning empty data.
PATINA_NETWORKNo network selected. Refuse to start rather than guess.
VITE_PATINA_ENABLEDThe workspace is not shown in the frontend.
PATINA_MAINNET_AUTHORIZEDMainnet transaction construction is refused, even if the network is set to mainnet.
Mainnet needs two things, not one

Mainnet requires PATINA_MAINNET_AUTHORIZED=true and a mainnet deployment record naming at least two approvers. Code must refuse mainnet construction unless both are present. This is a hard stop, not a warning, and it exists so that a misconfigured environment cannot open a founding window.

The window those heights would open is the founding cohort, set out for holders on Firstlight Seals. It opens once, so a configuration mistake here is not recoverable by editing a file afterwards.

First run

  1. Start on regtest

    Blocks are instant, so a full mint rehearsal takes minutes rather than a day.

  2. Run the golden vectors

    Before the indexer sees a real chain. A build that fails vectors must not be deployed. See Golden vectors and state roots.

  3. Index from the deployment start height

    Not from block zero. There is nothing to find before the deployment.

  4. Confirm status is honest

    curl -s http://localhost:PORT/patina/status
    # indexed_height well below tip_height, synced false
    curl -s -o /dev/null -w '%{http_code}\n' http://localhost:PORT/patina/ready
    # 503 while syncing

    An indexer that reports ready during initial sync is misconfigured and will serve incomplete answers.

  5. Move to signet

    Real block timing, no value at risk. Run a full mint here, including the 144 block wait.

  6. Only then consider mainnet

    With authorisation, an approved deployment record, and the launch checklist complete. See Pre launch checklist.

Network exposure

  • The indexer needs the node's RPC. Nothing else needs the node.
  • Do not expose the Bitcoin RPC to the internet.
  • Rate limit the public API at the edge. The protocol defines no authentication, so protection is the operator's job.
  • /metrics is for your monitoring system, not for the public.
  • If browsers will call the API directly, CORS headers are required. Without them a page opened from disk, or from another origin, gets a request that fails before any data arrives.

Before serving traffic

Seven gates, each with a definite answer. One failure is enough to keep the instance out of rotation, whatever the other six say.

  1. Golden vectors pass on this exact build.
  2. status reports the right network and the expected spec_sha256.
  3. ready returns an error until sync completes, and success afterwards.
  4. A known artifact from the test network resolves correctly by id.
  5. A state root at a fixed height matches a second, independent indexer.
  6. Backups and the restore drill are done, not planned. See Back up and restore.
  7. Alerts are firing to somewhere a human will see them. See Verify and monitor.