> For the complete documentation index, see [llms.txt](https://docs.fast.poker/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fast.poker/building-on-the-protocol/reference-ids-pdas.md).

# Program IDs, PDAs, discriminators and enums

> Verified against the public fastpoker IDL (PokerXYdXL2SKNnfGbv1WE7vJHipTpNsfZbZeVvoJLn) released 2026-07-17.

**Capability: read-side constants only, no signing**

> Beta software on mainnet. Examples can fail. Test with small amounts.

## Purpose

This page is the constant reference for Fast Poker integrations. It lists the program IDs, the full PDA seed set, the discriminator method and key discriminator values, the gameType and tier enums, and account sizes. Every value here is taken from the fastpoker IDL or the program source, not invented.

The values match the shared helper in [setup.md](/building-on-the-protocol/setup.md). This page is the lookup table behind that helper. It does not redefine the helper functions or repeat field layouts. For account field meaning and byte offsets, see [../04-architecture/state-accounts.md](/architecture/state-accounts.md). For the read-and-decode pattern, see [reading-accounts.md](/building-on-the-protocol/reading-accounts.md).

## When to use / who signs

Use this page when you need an exact constant: a program ID for an account-owner check, a seed for a PDA you derive yourself, a discriminator to tag a fetched account, or an enum byte for a filter. Nothing on this page signs or sends. These are read-side constants.

## Inputs and constants

### Program IDs

All five IDs are verified from `programs/fastpoker/src/constants.rs` and the IDL `address` fields. Import them from [setup.md](/building-on-the-protocol/setup.md) rather than retyping them.

| Program                         | Pubkey                                         | Source                                 |
| ------------------------------- | ---------------------------------------------- | -------------------------------------- |
| FastPoker (main)                | `PokerXYdXL2SKNnfGbv1WE7vJHipTpNsfZbZeVvoJLn`  | fastpoker IDL `address`, `declare_id!` |
| fastpoker\_registry             | `pokerQBdo685uLSkpVSyZ1vWooPYYTUhGkeKAHyCmax`  | fastpoker\_registry IDL `address`      |
| Permission program (MagicBlock) | `ACLseoPoyC3cBqoUtkbjZ4aDrkurZW86v19pXz2XQnp1` | `PERMISSION_PROGRAM_BYTES`             |
| Steel tokenomics program        | `FASTPjXb68fPW9JRYSBS3EDoaT6inz84GoqkPK52dsA9` | `STEEL_PROGRAM_BYTES`                  |
| MagicBlock Delegation program   | `DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh` | `DELEGATION_PROGRAM_BYTES`             |

The Delegation program is also the L1 `owner` of any account that is delegated to an Ephemeral Rollup. Use it to tell live L1 state from a delegated stub. See [reading-accounts.md](/building-on-the-protocol/reading-accounts.md).

### PDA seeds

The IDL declares discriminators and field layouts but does not declare the seed arrays. These seeds come from the on-chain `seeds = [...]` constraints in the program source. All PDAs derive against the FastPoker program ID unless noted. `table_id` is a 32-byte array. `seat_index`, `game_type`, and `tier` are single bytes. `page_index` is a `u16` little-endian. `match_id`, `hand_number`, and `start_hand` are `u64` little-endian.

| PDA                      | Seeds                                            |
| ------------------------ | ------------------------------------------------ |
| Table                    | `["table", table_id]`                            |
| PlayerSeat               | `["seat", table, seat_index]`                    |
| SeatCards                | `["seat_cards", table, seat_index]`              |
| DeckState                | `["deck_state", table]`                          |
| SlimBuffer               | `["slim_buffer", table]`                         |
| HandReportBuffer         | `["hand_report_buf", table]`                     |
| HandReportFlushState     | `["hand_report_flush", table]`                   |
| PlayerAccount            | `["player", wallet]`                             |
| PlayerTableMarker        | `["player_table", wallet, table]`                |
| TableVault               | `["vault", table]`                               |
| TipJar                   | `["tip_jar", table]`                             |
| CrankAction (ER)         | `["crank_action_er", table, operator]`           |
| CrankAction (L1)         | `["crank_action_l1", table, operator]`           |
| OperatorRewardTotal (ER) | `["op_reward_total_er", table]`                  |
| OperatorRewardTotal (L1) | `["op_reward_total_l1", table]`                  |
| CrankRewardState         | `["crank_reward_state", table]`                  |
| OperatorClaim            | `["op_claim", table, operator]`                  |
| SngPool                  | `["sng_pool", game_type, tier]`                  |
| SngPoolVault             | `["sng_pool_vault", game_type, tier]`            |
| SngMatch                 | `["sng_match", sng_pool, match_id]`              |
| SngQueueMarker           | `["sng_queue_marker", sng_pool, player]`         |
| SngQueuePage             | `["sng_queue_page", sng_pool, page_index]`       |
| SngJackpotSettlement     | `["sng_jackpot_settlement", table, hand_number]` |
| SngDuelState             | `["sng_duel", table]`                            |
| SngSettlementRecord      | `["sng_settlement", table, start_hand]`          |
| EmissionCtrl             | `["emission_ctrl"]`                              |
| PoolIdle                 | `["pool_idle", game_type, tier]`                 |

The shared helper in [setup.md](/building-on-the-protocol/setup.md) ships derivation functions for the most-used PDAs (Table, PlayerSeat, SeatCards, DeckState, PlayerAccount, TableVault, SngPool, SngPoolVault, SngMatch, SngQueueMarker, SngQueuePage). The remaining seeds above are listed for direct derivation when you need them.

### The discriminator method

Every Anchor account and instruction carries an 8-byte discriminator. The IDL stores each one explicitly, so the correct path is to read it from the IDL rather than recompute it. The underlying method is a SHA-256 preimage truncated to 8 bytes:

* Account: `SHA256("account:" + <AccountName>)[0..8]`, where `<AccountName>` is the IDL `PascalCase` name (for example `Table`, `PlayerSeat`).
* Instruction: `SHA256("global:" + <instruction_name>)[0..8]`, where `<instruction_name>` is the IDL `snake_case` name (for example `player_action`).

Both formulas are verified to reproduce the IDL values byte-for-byte. The seat struct is `PlayerSeat`, not `Seat`. Using the wrong name yields a different discriminator and a silent mismatch.

### Account discriminators (fastpoker)

These are the 8-byte tags for the accounts you read most. Read them with the Anchor `BorshAccountsCoder` from the IDL; the table is for reference and offline checks.

| Account              | Discriminator                             |
| -------------------- | ----------------------------------------- |
| Table                | `[34, 100, 138, 97, 236, 129, 230, 112]`  |
| PlayerSeat           | `[100, 254, 179, 67, 8, 150, 238, 232]`   |
| SeatCards            | `[25, 69, 52, 64, 109, 17, 43, 215]`      |
| DeckState            | `[190, 100, 169, 83, 107, 23, 168, 21]`   |
| PlayerAccount        | `[224, 184, 224, 50, 98, 72, 48, 236]`    |
| PlayerTableMarker    | `[124, 89, 140, 43, 170, 207, 251, 230]`  |
| TableVault           | `[7, 14, 145, 251, 151, 162, 15, 125]`    |
| SlimBuffer           | `[161, 168, 197, 74, 34, 90, 92, 17]`     |
| TipJar               | `[1, 2, 42, 158, 102, 246, 174, 210]`     |
| SngPool              | `[50, 24, 213, 231, 96, 31, 42, 143]`     |
| SngMatch             | `[227, 171, 157, 238, 167, 208, 97, 89]`  |
| SngQueueMarker       | `[82, 88, 69, 12, 195, 143, 39, 180]`     |
| SngQueuePage         | `[58, 141, 38, 41, 239, 170, 130, 6]`     |
| SngJackpotSettlement | `[168, 50, 42, 23, 111, 86, 120, 206]`    |
| SngDuelState         | `[187, 105, 215, 92, 106, 127, 211, 184]` |
| SngSettlementRecord  | `[106, 241, 75, 227, 64, 147, 124, 173]`  |
| EmissionCtrl         | `[41, 171, 243, 212, 6, 6, 72, 94]`       |
| PoolIdle             | `[107, 28, 178, 1, 234, 172, 111, 208]`   |
| CrankAction          | `[229, 62, 23, 25, 108, 57, 87, 33]`      |
| CrankRewardState     | `[97, 246, 120, 206, 40, 237, 74, 116]`   |
| OperatorClaim        | `[61, 131, 237, 220, 17, 24, 245, 161]`   |
| OperatorRewardTotal  | `[177, 97, 180, 184, 150, 182, 54, 236]`  |

The fastpoker IDL declares 36 account types in total. The full list is in the IDL `accounts` array.

### Instruction discriminators (sample)

The fastpoker IDL exposes 168 instructions. Most are crank, admin, settlement, and lifecycle calls. A small subset is player-facing. The discriminators below are the common player-facing entry points.

| Instruction                     | Discriminator                             |
| ------------------------------- | ----------------------------------------- |
| `seat_player`                   | `[7, 38, 253, 140, 213, 3, 208, 119]`     |
| `deposit_for_join`              | `[99, 149, 87, 125, 87, 44, 45, 46]`      |
| `join_sng_pool`                 | `[213, 144, 203, 165, 20, 91, 35, 180]`   |
| `player_action`                 | `[37, 85, 25, 135, 200, 116, 96, 101]`    |
| `create_table`                  | `[214, 142, 131, 250, 242, 83, 135, 185]` |
| `start_game`                    | `[249, 47, 252, 172, 184, 162, 245, 14]`  |
| `distribute_prizes`             | `[154, 99, 201, 93, 82, 104, 73, 232]`    |
| `sng_duel_action`               | `[244, 170, 13, 219, 245, 65, 228, 150]`  |
| `claim_sol_winnings`            | `[47, 206, 17, 43, 28, 213, 74, 12]`      |
| `distribute_prizes_from_record` | `[52, 82, 139, 197, 251, 211, 175, 154]`  |
| `deposit_tip`                   | (read from the IDL `instructions` array)  |

For any instruction not listed here, read its discriminator from the IDL `instructions[].discriminator` array. Do not hard-code values you have not verified against the IDL you ship.

### The 168-instruction full surface vs the player-facing subset

The 168-instruction count is the full program surface: gameplay, Flat Bounty duels, SNG lifecycle and settlement records, governed emission, the crank and settlement pipeline, reward accrual and pull-claim, jackpots, validator and whitelist administration, and recovery. Most are called by the crank service, TEE validator, or admin tooling. Players directly call only the relevant join, gameplay/duel, cashout, and claim subset.

### GameType enum

The `GameType` discriminant is the Table game-type byte. Only 0, 1, and 2 have SNG pools. Game type 3 is cash.

| Value | Variant         | Players per table       |
| ----- | --------------- | ----------------------- |
| 0     | SitAndGoHeadsUp | 2                       |
| 1     | SitAndGo6Max    | 6                       |
| 2     | SitAndGo9Max    | 9                       |
| 3     | CashGame        | n/a (cash, no SNG pool) |

### SnGTier enum

The `SnGTier` enum byte keys SNG pools and vaults. The total buy-in splits 90% to the prize and 10% to the fee. Values are mainnet (`TIER_SCALE = 1`). The discriminant-0 enum name is `Micro`; the public display name is Copper.

| Tier byte | Enum name | Public name | Total buy-in (SOL) | Prize (SOL) | Fee (SOL) |
| --------- | --------- | ----------- | ------------------ | ----------- | --------- |
| 0         | Micro     | Copper      | 0.05               | 0.045       | 0.005     |
| 1         | Bronze    | Bronze      | 0.10               | 0.09        | 0.01      |
| 2         | Silver    | Silver      | 0.25               | 0.225       | 0.025     |
| 3         | Gold      | Gold        | 0.50               | 0.45        | 0.05      |
| 4         | Platinum  | Platinum    | 1.00               | 0.90        | 0.10      |
| 5         | Diamond   | Diamond     | 2.00               | 1.80        | 0.20      |
| 6         | Black     | Black       | 5.00               | 4.50        | 0.50      |

Read `entry_amount` and `fee_amount` from each pool account for the live numbers. The table is for display.

### Other enums

These are the remaining IDL enums you encounter when decoding state. Each variant index is its byte value.

| Enum        | Variants (index = byte)                                                                                                     |
| ----------- | --------------------------------------------------------------------------------------------------------------------------- |
| SeatStatus  | Empty, Active, Folded, AllIn, SittingOut, Busted, Leaving                                                                   |
| GamePhase   | Waiting, Starting, Preflop, Flop, Turn, River, Showdown, Complete, FlopRevealPending, TurnRevealPending, RiverRevealPending |
| PokerAction | Fold, Check, Call, Bet, Raise, AllIn, SitOut, ReturnToPlay, LeaveCashGame, RebuyTopUp                                       |
| BlindType   | SmallBlind, BigBlind, DeadSmall                                                                                             |
| KickReason  | SitOutTimeout, LegacyOrbit, BustTimeout                                                                                     |
| CrankMode   | AcceptAll, SolOnly, TipsOnly, RakeOnly, AcceptListed, Free                                                                  |
| Stakes      | Micro, Low, Mid, High                                                                                                       |

### Account sizes

Sizes are the data length the program allocates, in bytes. The first 8 bytes of each are the discriminator. Some accounts allocate extra shadow bytes beyond the declared struct; those are noted in the architecture page.

| Account              | Size (bytes)                             |
| -------------------- | ---------------------------------------- |
| Table                | 459 (478 allocated with 19 shadow bytes) |
| PlayerSeat           | 281 (284 allocated)                      |
| SeatCards            | 76                                       |
| DeckState            | 241                                      |
| SlimBuffer           | 81                                       |
| HandReportFlushState | 88                                       |
| PlayerTableMarker    | 99                                       |
| TableVault           | 113                                      |
| TipJar               | 75                                       |
| CrankAction          | 97                                       |
| OperatorRewardTotal  | 57                                       |
| OperatorClaim        | 134                                      |
| SngPool              | 150                                      |
| SngJackpotSettlement | 209                                      |
| SngDuelState         | 415                                      |
| SngSettlementRecord  | 634                                      |
| EmissionCtrl         | 437                                      |
| PoolIdle             | 83                                       |

For the field-by-field layout behind each size, see [../04-architecture/state-accounts.md](/architecture/state-accounts.md).

### Public IDL repo

The fastpoker and fastpoker\_registry IDLs are published for direct download at [github.com/FastPoker/idl](https://github.com/FastPoker/idl). Pull the IDL from there or from your own `target/idl/` build output. The discriminators and field layouts in this page derive from that IDL.

## Steps

1. Take the program IDs and PDA seeds from [setup.md](/building-on-the-protocol/setup.md), which mirrors the tables above.
2. To tag a fetched account, read its discriminator from the IDL `accounts[].discriminator` array, or compare against the values in this page.
3. To filter or decode an enum field, map the byte to the variant index in the enum tables above.
4. To size or budget an account read, use the account-size table.
5. When in doubt, treat the IDL you ship as the source of truth and re-verify against it.

## Example

This example imports the shared helper from [./setup.md](/building-on-the-protocol/setup.md), builds an Anchor coder from the IDL, and prints the verified program ID, a recomputed account discriminator (to show the method), and the GameType and SnGTier enums. It sends nothing.

```ts
import { createHash } from 'crypto';
import { BorshAccountsCoder } from '@coral-xyz/anchor';
import {
  FASTPOKER_IDL,
  FASTPOKER_PROGRAM_ID,
} from './setup'; // shared helper from ./setup.md

// Discriminator method, verified to match the IDL byte-for-byte:
//   account:     SHA256("account:" + <PascalCaseName>)[0..8]
//   instruction: SHA256("global:"  + <snake_case_name>)[0..8]
function accountDiscriminator(name: string): Buffer {
  return createHash('sha256').update(`account:${name}`).digest().subarray(0, 8);
}
function instructionDiscriminator(name: string): Buffer {
  return createHash('sha256').update(`global:${name}`).digest().subarray(0, 8);
}

const GAME_TYPES = ['SitAndGoHeadsUp', 'SitAndGo6Max', 'SitAndGo9Max', 'CashGame'];
const SNG_TIERS = ['Micro', 'Bronze', 'Silver', 'Gold', 'Platinum', 'Diamond', 'Black'];
const TIER_PUBLIC = ['Copper', 'Bronze', 'Silver', 'Gold', 'Platinum', 'Diamond', 'Black'];

function main() {
  console.log('program id:', FASTPOKER_PROGRAM_ID.toBase58());

  // The coder reads discriminators straight from the IDL. Use this for real reads.
  const coder = new BorshAccountsCoder(FASTPOKER_IDL as any);
  const fromIdl = coder.accountDiscriminator('Table');
  const recomputed = accountDiscriminator('Table');
  console.log('Table disc (IDL):       ', [...fromIdl]);
  console.log('Table disc (recomputed):', [...recomputed]);
  console.log('match:', Buffer.from(fromIdl).equals(recomputed));

  // Instruction discriminator for a player-facing entry point.
  console.log('player_action disc:', [...instructionDiscriminator('player_action')]);

  // Enum byte -> variant lookups.
  GAME_TYPES.forEach((name, byte) => console.log(`GameType ${byte} = ${name}`));
  SNG_TIERS.forEach((name, byte) =>
    console.log(`SnGTier ${byte} = ${name} (public: ${TIER_PUBLIC[byte]})`),
  );
}

main();
```

## Result

You have the verified constants for a Fast Poker integration in one place: the five program IDs, the full PDA seed set, the discriminator method with key values, the gameType and tier enum bytes, the secondary enums, and account sizes. The discriminator method is shown to reproduce the IDL values exactly, so you can verify any tag offline. The IDL you ship remains the canonical source for anything not listed here.

## Pitfalls

* Do not invent a seed, discriminator, offset, or account order. If a value is not in this page or the IDL you ship, do not use it. The IDL declares discriminators and layouts but not seed arrays; seeds come from the program source and are listed above.
* Do not use `Seat` as the account name. The seat struct is `PlayerSeat`. The wrong name yields a different discriminator and a silent mismatch.
* Do not confuse `Micro` and `Copper`. The tier-0 enum name is `Micro`; the public name is Copper. The byte is 0 for both.
* Do not assume an unlisted instruction is player-callable. Of the 168 instructions, most are crank, TEE, admin, or settlement calls. Build against the named player-facing subset only.
* Do not hard-code tier lamports. Read `entry_amount` and `fee_amount` from the pool account. The SOL table is for display.
* Do not encode `game_type`, `tier`, or `seat_index` as multi-byte integers in a seed. They are single bytes. `page_index` is `u16` little-endian, and `match_id`, `hand_number`, and `start_hand` are `u64` little-endian.
* Do not check the FastPoker program ID alone for the account owner. A delegated account is owned on L1 by the Delegation program `DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh`. See [reading-accounts.md](/building-on-the-protocol/reading-accounts.md).

## See also

* [setup.md](/building-on-the-protocol/setup.md): the shared helper with program IDs and PDA-derivation functions.
* [reading-accounts.md](/building-on-the-protocol/reading-accounts.md): the read-and-decode pattern, owner checks, and free-RPC limits.
* [errors-troubleshooting.md](/building-on-the-protocol/errors-troubleshooting.md): mapping failures back to constants and instruction calls.
* [../04-architecture/state-accounts.md](/architecture/state-accounts.md): account sizes, seeds, and field-by-field layouts.
