> ## 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 with PressKey

> Add PressKey identity and authorization to a PressChain web application without taking custody of keys.

# Build with PressKey

PressKey is the user authorization boundary for PressChain-native browser applications. Your application prepares intent. PressKey manages the connected identity and signing interaction.

## Detect the provider

```ts theme={null}
function requirePressKey() {
  const provider = window.presschain;
  if (!provider?.isPressKey) {
    throw new Error("Install or enable PressKey to continue");
  }
  return provider;
}
```

The provider exposes `request`, `on` and `removeListener`, along with network identity for Chain ID `77117002`.

## Connect deliberately

Do not request identity on every page load. Ask when a feature actually needs it.

```ts theme={null}
async function connectPressKey() {
  const provider = requirePressKey();
  const accounts = await provider.request({ method: "eth_requestAccounts" });

  if (!Array.isArray(accounts) || accounts.length === 0) {
    throw new Error("PressKey returned no account");
  }

  return accounts[0] as `0x${string}`;
}
```

A read-only article page can remain useful without connection. A publish, vote or evidence action can request connection at the moment the user chooses that action.

## Track identity as live state

```ts theme={null}
const provider = requirePressKey();

function accountsChanged(accounts: string[]) {
  store.setState({ account: accounts[0] ?? null });
}

function chainChanged(chainId: string) {
  store.setState({ chainId });
}

provider.on("accountsChanged", accountsChanged);
provider.on("chainChanged", chainChanged);
provider.on("lockChanged", ({ locked }: { locked: boolean }) => {
  store.setState({ signerLocked: locked });
});
```

Remove listeners when the owning component or application scope is disposed. Otherwise hot reloads and client-side navigation can accidentally register handlers more than once.

## Separate preparation from authorization

A strong transaction flow does substantial work before asking for a signature:

1. Validate required fields locally.
2. Resolve current role, bond and relationship state.
3. Upload durable metadata or evidence content.
4. Compute canonical hashes.
5. Encode the exact contract call.
6. Confirm current PressKey account and chain.
7. Present a human-readable transaction review.
8. Ask PressKey to authorize.
9. Track the submitted transaction to a receipt.
10. Refresh authoritative state or wait for the projection to catch up.

This gives the user a clear explanation of what the signature changes.

## Do not send secrets to the site

A PressChain website should never ask for a seed phrase or private key. The current extension implementation deliberately keeps unlocked signing material inside the extension session rather than exposing it through `window.presschain`.

Your application only receives provider results and public account information.

## Handle lock and timeout states

Provider requests can reject or time out. Build explicit UI for that outcome.

```ts theme={null}
try {
  await performAuthorizedAction();
} catch (error) {
  const message = error instanceof Error ? error.message : "PressKey request failed";

  if (/timed out/i.test(message)) {
    showRetry("PressKey did not answer within the request window.");
  } else if (/locked/i.test(message)) {
    showUnlockPrompt();
  } else {
    showActionError(message);
  }
}
```

Do not automatically generate a second write transaction after an ambiguous timeout. First determine whether the original transaction was submitted.

## Build for protocol state, not wallet state alone

Connection only proves that an address is available. Before exposing privileged actions, resolve the required role and Capsule relationship.

For example, canonical evidence attachment in the V3 evidence registry is allowed for the Capsule author, registered contributors and protocol administration. It is not unlocked merely by being connected or holding an unrelated role.

That difference is where PressKey and PressChain fit together: PressKey proves the actor authorizing the request, while protocol state decides whether that actor can perform it.
