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

# CypherClient

> Constructor options, namespace overview, and wallet helpers.

`CypherClient` is the SDK entrypoint. Construction is cheap and synchronous - no RPC calls until you call a method.

```typescript TypeScript theme={null}
import { Connection } from "@solana/web3.js";
import { CypherClient, keypairToWallet } from "@cypher-zk/sdk";

const client = new CypherClient({
  connection: new Connection("https://api.devnet.solana.com", "confirmed"),
  wallet: keypairToWallet(keypair),
  cluster: "devnet",
});
```

***

## Constructor options

<ParamField body="connection" type="Connection" required>
  A `@solana/web3.js` `Connection` pointed at your target cluster. Pin `@solana/web3.js` to `^1.95.4` - the SDK is not compatible with v2 or `@solana/kit`.
</ParamField>

<ParamField body="wallet" type="Wallet" required>
  An Anchor-compatible wallet. Use `keypairToWallet(keypair)` for scripts, or pass a browser wallet adapter directly (they already implement the `Wallet` interface). Use `readonlyWallet(pubkey)` when the user is not connected.

  ```typescript theme={null}
  interface Wallet {
    publicKey: PublicKey;
    signTransaction<T>(tx: T): Promise<T>;
    signAllTransactions<T>(txs: T[]): Promise<T[]>;
  }
  ```
</ParamField>

<ParamField body="cluster" type="'devnet' | 'mainnet' | 'localnet' | ClusterConfig">
  Cluster preset for Arcium-specific configuration. If omitted, the SDK infers from the connection's RPC URL. Pass a full `ClusterConfig` to override the RPC, Arcium cluster offset, or expected mint.

  ```typescript theme={null}
  interface ClusterConfig {
    name: "devnet" | "mainnet" | "localnet";
    rpc: string;
    arciumClusterOffset: number;
    expectedMint: PublicKey;
  }
  ```
</ParamField>

<ParamField body="commitment" type="Commitment">
  Commitment used by the underlying Anchor provider. Defaults to `"confirmed"`.
</ParamField>

<ParamField body="programId" type="PublicKey">
  Override the program ID. Only needed for local redeployments with a fresh keypair. Defaults to the ID from the synced IDL.
</ParamField>

<ParamField body="tokenProgram" type="PublicKey">
  The SPL token program owning the accepted mint. Defaults to auto-detection on the first `globalState.fetch()`. Pass `TOKEN_2022_PROGRAM_ID` explicitly to skip the detection RPC call.
</ParamField>

<ParamField body="confirmOptions" type="ConfirmOptions">
  Extra options forwarded to the Anchor provider (e.g., `skipPreflight`).
</ParamField>

<ParamField body="rpcOptions" type="Partial<BatchOptions>">
  Tunables for the SDK's bulk RPC reads — chunking, concurrency, and retry policy. Defaults are conservative enough for free-tier RPCs; bump `concurrency` on paid plans (Helius, Triton) to speed up large list views.

  ```typescript theme={null}
  interface BatchOptions {
    chunkSize: number;     // default 100 (Solana RPC cap)
    concurrency: number;   // default 5
    retries: number;       // default 3
    retryBaseMs: number;   // default 200 — exponential backoff
    commitment?: Commitment;
  }
  ```

  ```typescript TypeScript theme={null}
  const client = new CypherClient({
    connection,
    wallet,
    cluster: "devnet",
    rpcOptions: { concurrency: 10 }, // Helius / Triton paid tiers
  });
  ```

  Available since v0.8.8.
</ParamField>

***

## Namespaces

`CypherClient` exposes high-level namespaces as read-only properties.

<Tree>
  <Tree.Folder name="client" defaultOpen>
    <Tree.Folder name="actions" defaultOpen>
      <Tree.File name="placeBet(inputs)" />

      <Tree.File name="createMarket(inputs)" />

      <Tree.File name="createMarketMulti(inputs)" />

      <Tree.File name="cancelMarket(inputs)" />

      <Tree.File name="withdrawCreatorFunds(inputs)" />

      <Tree.File name="resolveMarket(inputs)" />

      <Tree.File name="claimPayout(inputs)" />

      <Tree.File name="claimRefund(inputs)" />

      <Tree.File name="flagResolution(inputs)" />

      <Tree.File name="finalizeResolution(inputs)" />

      <Tree.File name="adminOverrideResolution(inputs)" />
    </Tree.Folder>

    <Tree.Folder name="markets">
      <Tree.File name="fetch(marketId)" />

      <Tree.File name="fetchByPda(pda)" />

      <Tree.File name="all()" />

      <Tree.File name="byCreator(creator)" />

      <Tree.File name="byState(state)" />

      <Tree.File name="byIds(ids)" />
    </Tree.Folder>

    <Tree.Folder name="positions">
      <Tree.File name="fetch(market, user, betIndex?)" />

      <Tree.File name="byUser(user)" />

      <Tree.File name="forMarket(market)" />
    </Tree.Folder>

    <Tree.Folder name="globalState">
      <Tree.File name="fetch(opts?)" />

      <Tree.File name="invalidate()" />
    </Tree.Folder>

    <Tree.Folder name="lpPositions">
      <Tree.File name="fetch(market, creator)" />

      <Tree.File name="byProvider(provider)" />
    </Tree.Folder>

    <Tree.Folder name="marketQuestions">
      <Tree.File name="fetch(market)" />

      <Tree.File name="fetchMany(markets)" />
    </Tree.Folder>

    <Tree.Folder name="events">
      <Tree.File name="subscribeAll(callback, opts?)" />

      <Tree.File name="subscribe(name, callback, opts?)" />

      <Tree.File name="onMarketCreated(callback, opts?)" />

      <Tree.File name="onBetPlaced(callback, opts?)" />

      <Tree.File name="onMarketResolved(callback, opts?)" />

      <Tree.File name="pollEvents(opts?)" />

      <Tree.File name="parseLogs(logs)" />
    </Tree.Folder>
  </Tree.Folder>
</Tree>

### `client.actions`

High-level action helpers. Each orchestrates a full flow: validate → encrypt (if needed) → build instructions → send transaction → await Arcium callback → refetch.

### `client.markets`

Account fetch helpers for `MarketAccount`.

| Method               | Description                                                                                                                                                                                        |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fetch(marketId)`    | Fetch by numeric ID                                                                                                                                                                                |
| `fetchByPda(pda)`    | Fetch by public key                                                                                                                                                                                |
| `all()`              | All markets                                                                                                                                                                                        |
| `byCreator(creator)` | Filter by creator                                                                                                                                                                                  |
| `byState(state)`     | Filter by state enum value                                                                                                                                                                         |
| `byIds(ids)`         | Fetch a known list of markets (mixed `bigint`/`number`/`PublicKey`). Routes through the batched RPC layer with chunking, concurrency, and retries. <Badge color="purple" size="sm">v0.8.8+</Badge> |

### `client.positions`

Account fetch helpers for `EncryptedPositionAccount`.

| Method                           | Description                                   |
| -------------------------------- | --------------------------------------------- |
| `fetch(market, user, betIndex?)` | Single position (defaults `betIndex` to `0n`) |
| `byUser(user)`                   | All positions across all markets              |
| `forMarket(market)`              | All positions on a single market              |

### `client.globalState`

| Method         | Description                                              |
| -------------- | -------------------------------------------------------- |
| `fetch(opts?)` | Fetch singleton GlobalState (cached per client instance) |
| `invalidate()` | Clear cache; next `fetch()` hits RPC                     |

Pass `{ refresh: true }` to bypass the cache: `client.globalState.fetch({ refresh: true })`.

### `client.lpPositions`

| Method                   | Description                           |
| ------------------------ | ------------------------------------- |
| `fetch(market, creator)` | LP position for a market/creator pair |
| `byProvider(provider)`   | All LP positions for a creator        |

### `client.marketQuestions`

| Method               | Description                                                                                                                                                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `fetch(market)`      | Fetch the `MarketQuestion` PDA for a market (v0.2+ markets only)                                                                                             |
| `fetchMany(markets)` | Batch-fetch questions for many markets in chunked RPC calls. Returns `Map<marketPdaBase58, questionString>`. <Badge color="purple" size="sm">v0.8.8+</Badge> |

### `client.events`

| Method                                | Description                                         |
| ------------------------------------- | --------------------------------------------------- |
| `subscribeAll(callback, opts?)`       | WebSocket subscription to all events                |
| `subscribe(name, callback, opts?)`    | Typed subscription to a single event name           |
| `onMarketCreated(callback, opts?)`    | Convenience typed listener                          |
| `onBetPlaced(callback, opts?)`        | Convenience typed listener                          |
| `onMarketResolved(callback, opts?)`   | Convenience typed listener                          |
| `onMarketCancelled(callback, opts?)`  | Convenience typed listener                          |
| `onCreatorWithdrawn(callback, opts?)` | Convenience typed listener                          |
| `onPayoutClaimed(callback, opts?)`    | Convenience typed listener                          |
| `onRefundClaimed(callback, opts?)`    | Convenience typed listener                          |
| `pollEvents(opts?)`                   | Poll-based event fetch (no WebSocket required)      |
| `parseLogs(logs)`                     | Parse raw transaction log strings into typed events |

***

## Wallet helpers

### keypairToWallet

Wraps a `Keypair` as an Anchor-compatible `Wallet`. Use this for Node scripts, tests, and CLIs.

```typescript TypeScript theme={null}
import { Keypair } from "@solana/web3.js";
import { CypherClient, keypairToWallet } from "@cypher-zk/sdk";

const keypair = Keypair.fromSecretKey(secretKeyBytes);
const client = new CypherClient({
  connection,
  wallet: keypairToWallet(keypair),
  cluster: "devnet",
});
```

### readonlyWallet

Creates a wallet that can sign nothing - only fetch operations work. Calling `signTransaction` or `signAllTransactions` throws a `ReadonlyWalletError`. Use it before the user connects their browser wallet.

```typescript TypeScript theme={null}
import { readonlyWallet } from "@cypher-zk/sdk";

const client = new CypherClient({
  connection,
  wallet: readonlyWallet(someFallbackPublicKey),
  cluster: "devnet",
});
```

Detect the read-only case in a mutation handler to show a "connect wallet" prompt instead of leaking the SDK detail:

```typescript TypeScript theme={null}
import { ReadonlyWalletError } from "@cypher-zk/sdk";

placeBet.mutate(inputs, {
  onError: (err) => {
    if (err instanceof ReadonlyWalletError) {
      toast.error("Connect your wallet to place a bet.");
      return;
    }
    toast.error(err.message);
  },
});
```

See [Errors → ReadonlyWalletError](/sdk/reference/errors#readonlywalleterror) for the full type.
