# TypeScript SDK reference (`@quiver/sdk`)

A thin viem-based client over `QuiverCoordinator`, plus hash-chain helpers and chain definitions.

## Install

```bash
npm i viem
# @quiver/sdk source ships in the public kit (github.com/camdengrieh/quiver-kit, under sdk/).
# npm-registry publish is pending; until then, vendor it from the kit or build it locally:
#   pnpm --filter @quiver/sdk build
```

Requires `viem ^2.21`. ESM only (`"type": "module"`).

## Exports

```ts
import {
  QuiverClient,                 // high-level client
  quiverCoordinatorAbi,         // ABIs
  quiverConsumerAbi,
  robinhoodMainnet,             // viem chain defs
  robinhoodTestnet,
  anvilLocal,
  QUIVER_CHAINS,                // { rh_mainnet, rh_testnet, local }
  buildQuiver,                  // hash-chain helpers (provider side)
  commitmentOf,
  revelationOf,
  userCommitmentOf,
  combineRandomValues,
} from "@quiver/sdk";
```

## `QuiverClient`

```ts
const quiver = new QuiverClient({
  coordinator,          // Address (required)
  publicClient,         // viem PublicClient (required, reads)
  walletClient,         // viem WalletClient (required only for writes)
  account,              // optional; defaults to walletClient.account
});
```

Reads:
- `getFee(provider) → Promise<bigint>`
- `getProviderInfo(provider) → Promise<ProviderInfo>`
- `getRequest(provider, seq)`
- `getFailedCallback(provider, seq) → Promise<{ exists, randomNumber }>`

Writes:
- `requestRandomness(provider, userRandomNumber?, { value? }) → Promise<RandomnessRequestResult>`
  — **push flow.** Defaults `userRandomNumber` to fresh CSPRNG bytes and `value` to `getFee`.
  The caller's contract must implement `quiverCallback`.
- `request(provider, userRandomNumber?, { useBlockhash?, value? }) → Promise<RandomnessRequestResult>`
  — **pull flow.** Commits `keccak256(userRandomNumber)`; keep `userRandomNumber` to reveal later.
- `reveal(provider, seq, userRevelation, providerRevelation) → Promise<{ hash, randomNumber }>`
  — pull reveal; returns the final random number.

Tracking:
- `waitForFulfillment(provider, seq, { pollingIntervalMs?, timeoutMs? }) → Promise<{ randomNumber }>`
  — resolves when `RandomnessRevealed` fires for `(provider, seq)`. Default timeout 180s, poll 2s.

Static helpers:
- `QuiverClient.generateUserRandom() → Hex` — 32 CSPRNG bytes.
- `QuiverClient.userCommitment(userRandomNumber) → Hex` — `keccak256(userRandomNumber)`.

`RandomnessRequestResult = { hash, sequenceNumber: bigint, provider, userRandomNumber }`.

## End-to-end examples

### Push flow (contract receives the callback)

```ts
const { sequenceNumber } = await quiver.requestRandomness(provider);
const { randomNumber } = await quiver.waitForFulfillment(provider, sequenceNumber);
console.log("random:", randomNumber);
```

### Pull flow (reveal yourself)

```ts
const userRandom = QuiverClient.generateUserRandom();
const { sequenceNumber } = await quiver.request(provider, userRandom);

// Obtain providerRevelation from the provider's reveal endpoint (ProviderInfo.uri),
// or compute it with revelationOf(seed, chainLength, seq) if you run the provider.
const { randomNumber } = await quiver.reveal(
  provider, sequenceNumber, userRandom, providerRevelation,
);
```

## Hash-chain helpers (provider side)

Only needed if you operate a provider / keeper.

- `buildQuiver(seed, length) → Hex[]` — the full hash chain.
- `commitmentOf(seed, length) → Hex` — the on-chain commitment (`keccak256^length(seed)`).
- `revelationOf(seed, length, seq) → Hex` — the link revealed for sequence `seq`.
- `userCommitmentOf(userRandomNumber) → Hex` — `keccak256(userRandomNumber)` (pull commitments).
- `combineRandomValues(userRevelation, providerRevelation, blockHash) → Hex` — recompute a result
  off-chain to verify fairness (pass `0x00…00` as blockHash when `useBlockhash` was false).

These are cross-checked against `cast keccak` and the on-chain `combineRandomValues`.
