Pixel Kingdom Wars

HomeDocs › Under the hood

Smart contracts and what lives on-chain

What Pixel Kingdom Wars puts on Solana (payments, Land Deeds, KEEP, weekly balance roots) versus the game server, with devnet addresses and verification tips.

Pixel Kingdom Wars is a server-authoritative game that uses Solana for a small, well-defined set of things: taking SOL payments, holding your Land Deed as an NFT, moving the KEEP token in and out, and publishing a weekly proof of player balances. Everything else — your base, army, raids, and shards — lives on the game server. This page explains where that line is drawn, what each on-chain program does, and how to check it yourself.

Everything described here runs on Solana devnet. Devnet SOL and devnet KEEP are test-net tokens with no real-world value, and there is no mainnet deployment.

Quick facts

On-chain vs. off-chain

Lives on Solana (devnet)Lives on the game server
SOL payment routing and entry receipts (shardkeep-core)Base layouts, structures, timers, Keep level
Weekly Merkle root of player KEEP balancesSHARDS, Mines, GOLD FORGE, armies, heroes, items
Land Deed NFTs and their collection (Metaplex Core)Quests, clans, chat, mail, shop listings
The KEEP SPL mint; deposits and withdrawalsRaid snapshots, battle simulation, settlement, replays
The inactive distributor programSign-in, admission, rate limits, anti-cheat, ledger accounting

Why: Putting every battle and building on-chain would make the game slow and expensive and would expose its rules to front-running. Keeping the game state on the server and using the chain only where ownership or money changes hands keeps play fast while still letting you hold your land and tokens in your own wallet.

One consequence worth knowing: gameplay never reads the NFT. Attackability, production, and in-game ownership are server state, so nothing you do to the deed in your wallet (freezing, delegating, listing) protects your base.

The shardkeep-core program

Program ID (devnet): mYYQFnpyGofG31y5oJkiKVmNwifbSXBMnQ5aUgQkL6b

This is the program your wallet talks to when you buy land, hire extra builders, or buy raid energy and shields. It does three jobs.

1. Route SOL payments

Every payment instruction sends SOL from your wallet to three treasury accounts in one transaction, using the split stored in the program's Config: 40% liquidity, 35% dev, 25% ops. The treasuries are fixed in Config, so a client cannot substitute its own addresses. Rounding dust always lands in the liquidity leg.

Each payment emits a PaymentMade event (wallet, kind, lamports, reference). The game server watches for that event, waits for the transaction to be finalized, and only then grants the item. If a transaction underpays, the program still accepts it but the server grants nothing — the server, not the chain, is the price authority.

InstructionWho signsWhat it does
pay_entryyouOne-time first-land purchase. Creates your Player receipt account; a second call fails on-chain.
buy_sink(kind, amount)youRepeatable payment tagged with a kind (energy, shield, builder, extra deed, and so on). No counters.
buy_builder, buy_expansionyouLegacy paths capped at 2 each; the current client does not use them.

2. Hold an entry receipt

pay_entry creates a Player account derived from your wallet address. Because it is created with init (not "init if needed"), one wallet gets exactly one entry receipt, enforced by the program itself. The server also uses this account as a fallback: if its scan for your payment reference ever misses, a finalized Player account is enough proof that you paid.

3. Post weekly balance roots

Once a week (Monday 00:10 UTC) the server snapshots every player's in-game KEEP balance, builds a Merkle root, and posts it with post_root. Each EpochRoot account is created once and cannot be rewritten. This is the start of a proof-of-liabilities system: the public GET /por endpoint shows coverage, and an authenticated GET /por/proof returns your inclusion proof. There is no in-game screen for this yet.

Admin instructions

set_paused blocks all payments; propose_admin / accept_admin transfer the admin key in two steps (the new admin must sign to accept). The program has no price-update instruction — the land price stored on-chain can only change through a program upgrade.

What each purchase does on-chain

PurchaseOn-chain pathPrice (devnet SOL)Where it goes
First landpay_entry0.240/35/25
Additional deedbuy_sink (kind 9)0.240/35/25
Builders 2–6buy_sink (kind 8)0.5, 0.75, 1, 1.5, 340/35/25
Raid energy ×1 / pack ×6buy_sink (kinds 3 / 7)0.03 / 0.0940/35/25
Shield +12 hbuy_sink (kind 4)0.0540/35/25
Warzone shield (48 h)direct transfer + buy_sink (kind 6) in one tx1050% liquidity direct, 50% via 40/35/25

Some purchases skip the program entirely and are plain SOL transfers, tagged with a reference key so the server can find them:

PurchasePrice (devnet SOL)Where it goes
Land expansions 1–60.15, 0.25, 0.40, 0.65, 1.00, 1.50100% liquidity
Mine upgrade to L5 … L200.5 … 3.2100% liquidity
GOLD FORGE upgrade to L2 … L200.10, +0.05 per level, up to 1.00100% liquidity
Item-market buyseller's price95% to seller, 5% fee treasury, one buyer-signed tx, no program

See Economy: Shards and KEEP and Shop and marketplace for how these fit into play.

The shardkeep-distributor program (not live)

Program ID (devnet): 6Tgc32nfuEDwvVQii47eLKZXeu39evzG5142UheuxpKU

This is a one-claim Merkle distributor meant for a future token-generation event. An admin initializes a Distributor (per mint) with a root, a claim window, and a clawback date; a wallet proves its leaf (wallet, amount, version) with claim and receives tokens from the vault; set_root replaces the snapshot and bumps the version so old proofs stop working; clawback sweeps leftovers after the window closes. Each wallet can claim once per Distributor lifetime.

Today it is deployed but switched off: there is no Distributor account for the current KEEP mint, no vault, no funds, and no production code calls it. It is also not how gameplay rewards are paid — the emission pool that funds mining and the GOLD FORGE is a ledger account on the server, not this program.

Land Deeds (Metaplex Core)

Collection (devnet): 56RemMwZRxL7xMMV8TbiErZX2YfrnuY65x3t7sTQxKrT

Your deed is a Metaplex Core NFT — not a compressed NFT — minted by the server into the game's collection once your land payment is finalized. A few properties matter to players:

A parcel's detail sheet, including deed status

Full details are on Land Deeds and the globe.

The KEEP token and custody

KEEP mint (devnet): 5GQh8Dg2BFtH3Yso5drRA2K8omw46m3KAQrhH3TMpWJC

KEEP is a classic SPL token (not Token-2022) with 9 decimals and Metaplex fungible metadata. Your in-game KEEP is a balance on the server's ledger; the game's payout hot wallet holds the only counted reserve.

The design target in the game's constants is a fixed 1,000,000,000 KEEP supply with revoked authorities. The project's own docs (checked 2026-08-18) describe the live devnet mint as 500,000,000 KEEP minted with mint and freeze authority retained — a devnet state, not the final mainnet policy, which is undecided. All of it is devnet KEEP with no real value. See Deposits, withdrawals, and 2FA.

Addresses and PDAs at a glance

All addresses are from the published devnet registry (infra/devnet.addresses.json, updated 2026-08-18).

WhatAddress (devnet)
shardkeep-core programmYYQFnpyGofG31y5oJkiKVmNwifbSXBMnQ5aUgQkL6b
shardkeep-distributor program6Tgc32nfuEDwvVQii47eLKZXeu39evzG5142UheuxpKU
Core Config PDAAEtsnqdSXDwGDBeovnD9XoutQmNptcPWC8ygieZSkKHH
KEEP mint5GQh8Dg2BFtH3Yso5drRA2K8omw46m3KAQrhH3TMpWJC
Land Deed collection56RemMwZRxL7xMMV8TbiErZX2YfrnuY65x3t7sTQxKrT
TreasuryAddress (devnet)
Liquidity (40%, plus all direct transfers)A1ja8GwrTM2KvS4tKJJaVaLk57xJeehuk2F9Exbz82QA
Dev (35%)5sYVCRd1onSre8EKujE5vDKa9KeF2KuJvPA3rpRonfif
Ops (25%)fCTc8TgJCvHUkn1aaME2gDcs69LpgtVXq1rmBSvS3Bx

Program-derived accounts, for developers:

Program IDs are identical on localnet and devnet, and the TypeScript clients read them from the committed IDLs.

Who holds the keys

Security posture in brief

Every program change must keep: release-mode overflow checks; a signer on every authority; typed accounts with owner and discriminator checks; canonical PDA seeds; init (never re-init) for receipts and roots; fixed treasury and mint constraints; multiply-before-divide basis-point math; an event for every value movement; and adversarial validator tests (wrong signers, substituted treasuries, duplicate entries, out-of-order purchases, pause bypass, forged Merkle proofs, node-as-leaf attacks, window timing).

On the server side: every payment is verified at finalized before any grant, payment events are only trusted from shardkeep-core's own execution frames so another program cannot forge one, and custody transactions are persisted before broadcast so retries resend identical bytes. Note that the Anchor validator tests are a manual release gate rather than a CI job.

How to verify on an explorer

  1. Open Solana Explorer or Solscan and switch the cluster to Devnet.
  2. Paste a program ID above. You should see the program account and, for shardkeep-core, the IDL.
  3. After a land purchase, open your wallet's transaction: it should show three SOL transfers to the treasury addresses above (for 0.2 SOL: 0.08 / 0.07 / 0.05) and a PaymentMade event log.
  4. Paste the KEEP mint to see its metadata, or the collection address to browse minted deeds; your own deed appears under your wallet's assets.
The in-game WALLET view

Tip: The exact-split check is the quickest way to confirm you signed the real program. If the transfers do not match the treasuries listed here, stop and ask in the community channels before signing anything else.

See also