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

# Accounts

> On-chain account types, fetchers, filters, and display helpers.

## Account types

### MarketAccount

The central account for a prediction market. Exists at the `market` PDA.

| Field                | Type        | Description                                                                            |
| -------------------- | ----------- | -------------------------------------------------------------------------------------- |
| `marketId`           | `bigint`    | Auto-incrementing ID assigned at creation                                              |
| `marketType`         | `number`    | `0` = YesNo, `1` = MultiOutcome                                                        |
| `numOutcomes`        | `number`    | Number of outcome options (2 for YesNo, 2-4 for multi)                                 |
| `category`           | `number`    | Market category enum (0-6)                                                             |
| `creator`            | `PublicKey` | Market creator                                                                         |
| `resolver`           | `PublicKey` | Wallet authorized to post the outcome                                                  |
| `creatorBond`        | `bigint`    | Bond deposited by creator at market creation (micro-USDC)                              |
| `bondWithdrawn`      | `boolean`   | Whether the creator has already withdrawn their bond                                   |
| `totalBetsCount`     | `bigint`    | Total number of bets placed                                                            |
| `revealedPool0`      | `bigint`    | Revealed pool for outcome 0 (set by MPC callback after resolution)                     |
| `revealedPool1`      | `bigint`    | Revealed pool for outcome 1                                                            |
| `revealedPool2`      | `bigint`    | Revealed pool for outcome 2 (multi only)                                               |
| `revealedPool3`      | `bigint`    | Revealed pool for outcome 3 (multi only)                                               |
| `state`              | `number`    | Current state (0=Active, 1=Closed, 2=Resolved, 3=Unresolved, 4=PendingResolution)      |
| `outcome`            | `number`    | Confirmed winning outcome index (set after resolution is finalized)                    |
| `pendingOutcome`     | `number`    | Outcome posted by the resolver - not yet finalized (0 until `resolveMarket` is called) |
| `closeTime`          | `bigint`    | Unix timestamp when betting closes                                                     |
| `resolutionTime`     | `bigint`    | Unix timestamp when `resolveMarket` was called                                         |
| `payoutRatio`        | `bigint`    | Payout per unit stake × `ODDS_SCALE` (1e9)                                             |
| `minBet`             | `bigint`    | Market-specific minimum bet in micro-USDC                                              |
| `resolutionDeadline` | `bigint`    | Timestamp by which the resolver must post an outcome, or refunds open                  |
| `claimDeadline`      | `bigint`    | Timestamp when the claim period ends                                                   |
| `refundDeadline`     | `bigint`    | Timestamp when the refund period ends                                                  |
| `challengePeriod`    | `bigint`    | Dispute window duration in seconds (24-48h, set at creation)                           |
| `challengeDeadline`  | `bigint`    | `resolutionTime + challengePeriod` - when the window closes                            |
| `disputed`           | `boolean`   | Whether `flagResolution` was called during the challenge window                        |
| `inlineQuestion`     | `string`    | Question text for legacy (v1/v2) market accounts only - always `""` on v3+             |
| `bump`               | `number`    | PDA bump seed                                                                          |

<Note>
  v3 markets (393-byte accounts, all markets created with the current program) store the question in a separate `MarketQuestion` PDA - `inlineQuestion` will be `""`. Use `fetchMarketQuestions` to hydrate questions in batch.
</Note>

***

### EncryptedPositionAccount

Records an encrypted bet. Exists at the `position` PDA keyed by `(market, user, betIndex)`.

| Field               | Type         | Description                                                        |
| ------------------- | ------------ | ------------------------------------------------------------------ |
| `user`              | `PublicKey`  | Bettor's wallet                                                    |
| `market`            | `PublicKey`  | Market PDA                                                         |
| `encryptedAmount`   | `Uint8Array` | 32-byte ciphertext of the bet stake                                |
| `encryptedSide`     | `Uint8Array` | 32-byte ciphertext of the chosen outcome                           |
| `userPubkey`        | `Uint8Array` | Bettor's x25519 public key (needed for decryption)                 |
| `nonce`             | `bigint`     | u128 nonce used for encryption (convert to 16 LE bytes to decrypt) |
| `entryOdds`         | `bigint`     | Locked-in odds × `ODDS_SCALE` at bet time                          |
| `netAmount`         | `bigint`     | Plaintext net stake after fees (asserted by circuit)               |
| `betIndex`          | `bigint`     | Index of this bet for the (user, market) pair                      |
| `claimed`           | `boolean`    | Whether payout or refund was claimed                               |
| `computationQueued` | `boolean`    | Whether the MPC computation was queued                             |
| `bump`              | `number`     | PDA bump seed                                                      |

***

### GlobalStateAccount

Singleton protocol config. There is only one per deployment.

| Field              | Type        | Description                                           |
| ------------------ | ----------- | ----------------------------------------------------- |
| `marketCounter`    | `bigint`    | Next market ID to assign                              |
| `protocolFeeRate`  | `number`    | Protocol fee in basis points (e.g., `50` = 0.5%)      |
| `lpFeeRate`        | `number`    | LP (creator) fee in basis points (e.g., `150` = 1.5%) |
| `protocolTreasury` | `PublicKey` | Wallet receiving protocol fees                        |
| `acceptedMint`     | `PublicKey` | USDC mint accepted by this deployment                 |
| `admin`            | `PublicKey` | Admin wallet for overrides                            |
| `bump`             | `number`    | PDA bump seed                                         |

***

### LpPositionAccount

Tracks the creator's liquidity and accumulated fees per market.

| Field               | Type        | Description                                                                            |
| ------------------- | ----------- | -------------------------------------------------------------------------------------- |
| `lpProvider`        | `PublicKey` | Market creator wallet                                                                  |
| `market`            | `PublicKey` | Market PDA                                                                             |
| `liquidityProvided` | `bigint`    | Bond deposited at market creation (micro-USDC)                                         |
| `feesEarned`        | `bigint`    | Accumulated LP fees (reserved - currently always `0n`; use `Market.accumulatedLpFees`) |
| `feesClaimed`       | `boolean`   | Whether `withdrawCreatorFunds` has been called                                         |
| `feesClaimedAmount` | `bigint`    | Actual payout amount at withdrawal time                                                |
| `bump`              | `number`    | PDA bump seed                                                                          |

***

### MarketQuestionAccount <Badge color="purple" size="sm">v0.2+</Badge>

Stores the question text for v0.2+ markets (separate PDA to save space in `MarketAccount`).

| Field         | Type     | Description                                    |
| ------------- | -------- | ---------------------------------------------- |
| `question`    | `string` | Full question text decoded from on-chain bytes |
| `questionLen` | `number` | Length of the question in bytes (max 200)      |
| `bump`        | `number` | PDA bump seed                                  |

***

## Fetchers

All fetchers are also available as methods on the `CypherClient` namespaces.

```typescript TypeScript theme={null}
import {
  fetchMarket,
  fetchAllMarkets,
  fetchMarketsByIds,
  fetchUserPositions,
  fetchMarketQuestions,
} from "@cypher-zk/sdk";

// Fetch a single market by ID
const market = await client.markets.fetch(42n);

// Fetch all markets — expensive at scale, prefer byIds for paginated views
const markets = await client.markets.all();

// Fetch only the markets you actually need (mixed bigint / number / PublicKey).
// Routes through the batched RPC layer (chunking + concurrency + retries).
const page = await client.markets.byIds([1n, 2n, 3n]);

// Fetch all positions for a user
const positions = await client.positions.byUser(userPublicKey);

// Batch-fetch questions for a page of markets (v0.2+).
// `fetchMany` is the client-namespace wrapper around `fetchMarketQuestions`.
const questionMap = await client.marketQuestions.fetchMany(page);

// Merge questions
const withQuestions = page.map(({ publicKey, account }) => ({
  publicKey,
  account,
  question: questionMap.get(publicKey.toBase58()) ?? account.inlineQuestion,
}));
```

<Note>
  `client.markets.byIds` and `client.marketQuestions.fetchMany` were added in v0.8.8. Both chunk pubkey lists past Solana's 100-key `getMultipleAccountsInfo` cap and retry transient errors. Tune via [`CypherClientOptions.rpcOptions`](/sdk/reference/client#constructor-options) or pass per-call overrides.
</Note>

***

## Display helpers

```typescript TypeScript theme={null}
import {
  marketPhase,
  marketStateName,
  marketTypeName,
  marketCategoryName,
  cancelEligibility,
  marketFormatVersion,
  parseEmbeddedOptions,
} from "@cypher-zk/sdk";
```

### marketPhase

Returns a human-readable phase string based on the market's state and timestamps. Use this to drive UI state.

```typescript TypeScript theme={null}
type MarketPhase =
  | "betting"
  | "awaitingResolve"
  | "pendingResolution"
  | "awaitingFinalize"
  | "disputed"
  | "claimable"
  | "refundable"
  | "expired"
  | "cancelled";

const phase = marketPhase(market.account);
```

### cancelEligibility

Pre-flight check before showing a cancel button.

```typescript TypeScript theme={null}
const { ok, reason } = cancelEligibility(market.account);
if (!ok) console.log("Cannot cancel:", reason);
```

### parseEmbeddedOptions

Extracts option labels from a `[A|B|C]` question suffix.

```typescript TypeScript theme={null}
const labels = parseEmbeddedOptions("Which chain leads TVL? [Solana|Ethereum|Base]");
// ["Solana", "Ethereum", "Base"]

// Map side index to label
const sideLabel = labels[position.side] ?? `Option ${position.side}`;
```

### marketFormatVersion

Detects the market account layout version from byte length.

```typescript TypeScript theme={null}
const version = marketFormatVersion(accountData.length); // "v1" | "v2" | "v3" | null
```

Legacy v1 and v2 accounts have inline questions; v3 accounts use the `MarketQuestion` PDA.
