> ## 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.

# Connect to PressChain

> Configure a web or backend application for the PressChain V3 testnet.

# Connect to PressChain

A PressChain integration begins with two different connections: a **read connection** to JSON-RPC and a **user authorization connection** through PressKey. Keeping them separate makes the application easier to secure and easier to operate.

For reads, use the canonical V3 RPC endpoint:

```text theme={null}
https://rpc.presschain.io
```

The current testnet Chain ID is `77117002`, or `0x498B64A` in hexadecimal.

## Web application setup

A browser application can read through JSON-RPC directly and use PressKey only when the user needs to authorize an action.

```ts theme={null}
export const network = {
  chainId: 77117002,
  chainIdHex: "0x498B64A",
  rpcUrl: "https://rpc.presschain.io",
};

export async function verifyRpc() {
  const response = await fetch(network.rpcUrl, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "eth_chainId",
      params: [],
    }),
  });

  const body = await response.json();
  if (body.error) throw new Error(body.error.message);
  if (String(body.result).toLowerCase() !== network.chainIdHex.toLowerCase()) {
    throw new Error(`Unexpected chain: ${body.result}`);
  }

  return true;
}
```

Run this check during application startup or before enabling network-sensitive features. Do not wait until the user signs a transaction to discover the app is pointed at a different chain.

## Detect PressKey

```ts theme={null}
export function getPressKey() {
  const provider = window.presschain;
  if (!provider?.isPressKey) {
    throw new Error("PressKey is required for PressChain authorization");
  }
  return provider;
}
```

PressKey currently exposes an EIP-style provider. It also assigns itself to `window.ethereum` when another provider has not already claimed that name, but PressChain-native applications should prefer `window.presschain` explicitly.

## Backend setup

Backends that only read network state do not need a wallet at all.

```ts theme={null}
export async function rpc(method: string, params: unknown[] = []) {
  const res = await fetch("https://rpc.presschain.io", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ jsonrpc: "2.0", id: Date.now(), method, params }),
  });

  if (!res.ok) throw new Error(`RPC request failed: ${res.status}`);
  const json = await res.json();
  if (json.error) throw new Error(json.error.message || "RPC error");
  return json.result;
}
```

This is the correct place for block reads, log indexing, balance checks and read-only `eth_call` operations. It is not the correct place for storing user signing keys.

## Configuration you should keep together

Treat network and deployment values as a coherent environment package:

```ts theme={null}
export type PressChainEnvironment = {
  name: string;
  protocolMajor: "v3";
  chainId: number;
  rpcUrl: string;
  contracts: Record<string, `0x${string}`>;
};
```

Load the contract map from an approved deployment manifest. This prevents a common failure mode where one page points at the new evidence registry while another still calls an older contributor contract.

## First health checks

Before building product features, verify these conditions:

1. `eth_chainId` returns the expected testnet ID.
2. `eth_blockNumber` advances over time.
3. Your application can perform `eth_call` against a known deployed contract.
4. PressKey can be detected on an allowed PressChain domain.
5. Account and network change events update application state.

Once those are true, continue to [Read Chain State](/quickstart/read-chain). That guide establishes a reliable read path before any user write is introduced.
