> ## Documentation Index
> Fetch the complete documentation index at: https://docs.presschain.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Build an Evidence Viewer

> A practical example for reading evidence, tallies and artifact integrity for a Capsule.

# Build an evidence viewer

An evidence viewer is a good first complete PressChain application because it combines canonical identifiers, contract reads, off-chain artifacts and protocol status without requiring the application to become a signer.

The input is a Capsule ID. The output is a structured list of evidence with integrity and tally state.

## Data flow

```mermaid theme={null}
flowchart LR
  ID[Capsule ID] --> REG[Evidence registry]
  REG --> IDS[Evidence IDs]
  IDS --> ITEM[Evidence record]
  ITEM --> URI[Fetch artifact URI]
  URI --> HASH[Verify content hash]
  ITEM --> TALLY[Evidence tally]
  HASH --> UI[Evidence card]
  TALLY --> UI
```

## Read evidence IDs

The active V3 evidence registry exposes `getEvidenceIds(bytes32)` and `evidenceCountByCapsuleId(bytes32)`.

```ts theme={null}
const ids: bigint[] = await evidenceRegistry.getEvidenceIds(capsuleId);
```

Then resolve records and tallies in parallel with a sensible concurrency limit.

```ts theme={null}
async function loadEvidence(id: bigint) {
  const [item, tally] = await Promise.all([
    evidenceRegistry.getEvidence(id),
    evidenceRegistry.getEvidenceTally(id),
  ]);

  return { item, tally };
}
```

## Interpret status carefully

Current evidence status values are ordered by the Solidity enum:

| Value | Status      |
| ----: | ----------- |
|   `0` | `NONE`      |
|   `1` | `OPEN`      |
|   `2` | `SUPPORTED` |
|   `3` | `REJECTED`  |
|   `4` | `DISPUTED`  |
|   `5` | `FINALIZED` |

The tally also has a separate `finalized` boolean. Do not infer finality from vote counts alone.

## Verify artifact integrity

A record may reference a PDF, image, dataset, transcript or another artifact through `uri`. Fetch bytes without text normalization, hash the exact bytes according to the record convention and compare the result to `contentHash`.

Your UI can then separate protocol status from artifact availability:

```ts theme={null}
type ArtifactState =
  | "verified"
  | "hash-mismatch"
  | "unavailable"
  | "not-checked";
```

An unavailable URL does not erase the on-chain evidence record. A hash mismatch should be visible because the retrieved bytes do not match the committed artifact.

## Render meaningful context

Useful evidence cards include:

* label
* evidence type
* canonical URI
* media type
* cover image when present
* submitter address or resolved identity
* primary evidence flag
* active state
* content hash
* support, reject and participation counts
* finalized state

Avoid replacing these with a single opaque “trust score.” Evidence should remain inspectable.

## Distinguish canonical and dispute paths

The V3 contract reserves evidence type `255` for dispute evidence. Normal canonical attachment rejects that value, while `submitDisputeEvidence` creates a record with label `DISPUTE_EVIDENCE`.

A viewer can use this distinction to build separate sections for supporting source material and later challenges without pretending they are the same relationship.

## Add a write path later

Once the viewer is reliable, add PressKey-backed actions. Canonical evidence attachment requires the proper Capsule relationship. Dispute evidence has its own contract method and validation rules.

Keep the viewer read path independent of the signer so anyone can inspect a Capsule even when PressKey is locked.
