SHOOK / OFFICIAL PROTOCOLDocumentation
MAINNET EDITIONOpen SHOOK
Reference / SHOOK

Integration guide

Read state, simulate transactions, and reconcile events against the correct official deployment.

Resolve the deployment

Obtain the complete official deployment manifest before constructing clients. Require the expected chain ID and nonzero contract addresses with deployed bytecode. Do not fall back to local, demonstration, or another network’s addresses when mainnet data is missing.

The documentation includes downloadable ABIs, generated from the compiled contracts, including inherited token methods and inherited game methods. Addresses and ABIs are different inputs; an ABI is not evidence of deployment.

Amounts and simulation

Pass ETH and SHOOK amounts as 18-decimal integer base units. Use bigint or another exact integer type, not JavaScript number. Deadlines are Unix seconds, also represented as integers. V4 fee values use millionths, while protocol fee split constants use basis points.

Quote and simulate close to execution, preferably using a consistent block for reads. Verify the simulated spender, receiver, chain, value, and protections before asking a wallet to sign. Wait for the receipt before displaying final success.

Formation buy example

This illustrative viem flow assumes publicClient, walletClient, account, verified formationAddress, and the compiled formationAbi have already been configured. Production code must also handle chain changes, stale quotes, reverts, and receipts.

const budget = 1000000000000000000n; // 1 ETH
const [quotedOut] = await publicClient.readContract({
  address: formationAddress, abi: formationAbi,
  functionName: 'quoteBuyExactInput', args: [budget],
});
const minimumOut = quotedOut * 9900n / 10000n; // chosen 1% tolerance
const deadline = BigInt(Math.floor(Date.now() / 1000) + 300);
const { request } = await publicClient.simulateContract({
  account, address: formationAddress, abi: formationAbi,
  functionName: 'buyExactETHIn',
  args: [minimumOut, account.address, deadline], value: budget,
});
const hash = await walletClient.writeContract(request);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== 'success') throw new Error('Trade reverted');

Allowance boundaries

Formation sells approve FormationMarket. Permanent sells approve PermanentMarketRouter. Stakes approve StakingVault. Game creation and entry approve the relevant game escrow. User claims and vault withdrawals transfer assets outward and do not require the user to approve a spender.

ERC20Permit does not imply every downstream contract has a combined permit-and-action method. Use the actual ABI. Do not assume Permit2 or a generic router multicall is part of the SHOOK wrapper.

Signed game state

Tic-Tac-Toe signs GameState under EIP-712 name SHOOK TicTacToe, version 1, the chain ID, and the game contract address. Signers are registered per game. Use hashState and the exact tuple fields and enum encoding in the compiled ABI as cross-checks.

Session keys authorize gameplay evidence, not token claims. Start and openDispute still require the main participant wallet. A relayer can carry valid evidence for other permitted methods but cannot bypass their status or signature rules.

Runtime and data services

The monorepo SDK, API, and indexer provide runtime loading, ABIs, reads, and product data. They are not consensus. An integration can use contracts directly, and should expose indexing delay and failed transactions instead of treating optimistic application state as final. Read Events and accounting.

Source reference

Checked against the source shipped with this documentation. Contract calls and units are detailed in the contract reference.

Imported source files 67

Supporting contracts, interfaces, and libraries imported by the sources above, including their dependencies.

SHOOK docs Official protocol · Mainnet parameters