Full lesson
mons-dot-rehab
play mons on solana
What it does
From the project README:
You can use any normal anchor commands. Either move to the `anchor` directory and run the `anchor` command or prefix the command with `npm run`, eg: `npm run anchor`.
- Original
- supermetalmons/mons-dot-rehab
- SuperStack fork
- Blockchains/mons-dot-rehab @
0359070 - Stars
- 0
- Last push (original)
- 2024-09-17
- Languages
- TypeScript, Rust, JavaScript, CSS, HTML
- Detected stack
- Anchorweb3.js
- Categories
- NFTs & Digital AssetsGaming
- Licence
- CC0-1.0
- Homepage
- https://mons.rehab
Architecture
25 source files. By extension: .tsx ×14, .ts ×6, .js ×4, .rs ×1.
| Top-level directory | Source files |
|---|---|
web | 18 |
anchor | 5 |
(root) | 2 |
On-chain programs: anchor/programs/mons-dot-rehab
🟡 Builds, verified 2026-11-02 Tested on 2026-11-02: full log results.json
Build it yourself: step-by-step guide
Every command below was run on 2026-11-02 by tests/run_fork.py against the pinned commit, and the results come from that run. The full output is in the committed log.
1. Prerequisites (versions we tested with)
- Rust:
rustc 1.99.1 (58cf8f9c3 2026-10-13) - Solana CLI (Agave):
solana-cli 1.18.17 (src:c027cfc3; feat:4215500110, client:Agave) - Anchor (via avm):
0.29.0 - Node.js:
v24.22.1 - npm:
11.21.1 - pnpm:
10.34.6 - Go:
go version go1.27.3 linux/amd64
cargo install --git https://github.com/coral-xyz/anchor avm --locked
avm install 0.29.0 && avm use 0.29.0
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"2. Clone at the tested commit
git clone https://github.com/Blockchains/mons-dot-rehab.git && cd mons-dot-rehab
git checkout 035907012795bd356240a4e6667f63d740b9b9ab3. Configure
No environment file is needed.
4. Install dependencies
| Directory | Command | Result | Time |
|---|---|---|---|
. | npm install --no-audit --no-fund --legacy-peer-deps | ✅ pass | 12s |
anchor | npm install --no-audit --no-fund --legacy-peer-deps | ✅ pass | 3s |
anchor | npm install --no-audit --no-fund --legacy-peer-deps | ✅ pass | 0s |
5. Build
| Directory | Command | Result | Time |
|---|---|---|---|
anchor | anchor@0.29.0 build | ✅ pass | 91s |
. | npm run build | ✅ pass | 12s |
7. Deploy to a local validator
solana-test-validator --reset # separate terminal
solana config set -ul && solana airdrop 100
anchor deploy --provider.cluster localnet| Directory | Command | Result | Time |
|---|---|---|---|
anchor | solana airdrop 100 -u localhost >/dev/null; anchor@0.29.0 deploy --provider.cluster localnet --provider.wallet ~/.config/solana/id.json | ✅ pass | 5s |
Proof: program IDs and transactions
mons_dot_rehab:EMAwPxwMDP76YB4yCva9DGgMbedEQjzduEiJXVgfGr4Z(local validator)
Transaction signatures recorded on the local validator (1 shown). Local ledgers are thrown away after the run, so these work as receipts in the log and can't be looked up on an explorer:
mons_dot_rehab4zDx3TbTvbvA5QgjXzim…QXCdWFwn
Deploy to devnet (free)
solana config set --url devnet
solana airdrop 2 # or https://faucet.solana.com
anchor deploy --provider.cluster devnet # native: solana program deploy target/deploy/<name>.so
# point the frontend RPC env var at https://api.devnet.solana.comHow it works
Every instruction handler in the program, with the accounts struct it validates. Each link points to the line at the pinned commit.
| Instruction | Accounts | Where |
|---|---|---|
create_game | CreateGame | anchor/programs/mons-dot-rehab/src/lib.rs:15 |
join_game | JoinGame | anchor/programs/mons-dot-rehab/src/lib.rs:38 |
end_game | EndGame | anchor/programs/mons-dot-rehab/src/lib.rs:62 |
Extend it
- Add an integration test that runs the main flow end to end and asserts every account state change.
- Add a negative test: call each instruction with the wrong signer or account and check that it fails.
- Add an event (
emit!) to each state-changing instruction and subscribe to it from the client. - Replace any unchecked
AccountInfowith typed accounts plushas_one/seedsconstraints. - Make the frontend read the cluster from an env var, deploy it to GitHub Pages and point it at your devnet program.
- Wire the build into CI by copying this site's verify-forks workflow.
Open the dapp
✅ Operational on devnet, verified 2026-11-02
Open the dapp Connect Phantom or Solflare. Every transaction is signed in your own wallet.
- Devnet (test tokens): program
EMAwPxwMDP76YB4yCva9DGgMbedEQjzduEiJXVgfGr4Z. Get free devnet SOL at faucet.solana.com. - Mainnet: not yet deployed on mainnet (needs owner approval), so it is disabled
Devnet proof, verified 2026-11-02: real transactions sent through this program on devnet.
create_game37oLWG5vAGjovAPVfkxs…join_game3ytwYTQjTm8WGKJGn3cV…
Key code, explained
Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.
anchor/programs/mons-dot-rehab/src/lib.rs L73–96 @ 0359070 · CC0-1.0 · original } } #[derive(Accounts)]#[instruction(game_id: u64)]pub struct CreateGame<'info> { #[account(init, payer = host, space = 1 + 8 + 8 + 32 + 32, seeds = [b"game", &game_id.to_le_bytes()[..]], bump)] pub game: Account<'info, Game>, #[account(mut)] pub host: Signer<'info>, pub system_program: Program<'info, System>,} #[account]pub struct Game { pub game_id: u64, pub host_id: Pubkey, pub guest_id: Pubkey, pub bump: u8,} #[derive(Accounts)]pub struct JoinGame<'info> {- Line 80
#[account(init, payer = host, space = 1 + 8 + 8 + 32 + 32, seeds = [b"game", &game_id.to_l: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 80
#[account(init, payer = host, space = 1 + 8 + 8 + 32 + 32, seeds = [b"game", &game_id.to_l: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve. - Line 80
#[account(init, payer = host, space = 1 + 8 + 8 + 32 + 32, seeds = [b"game", &game_id.to_l: Creates and pays for a new account. Space and payer must be specified. - Line 83
pub host: Signer<'info>,: Requires this account to have signed the transaction.
web/src/app/dashboard/program-data-access.tsx L37–60 @ 0359070 · CC0-1.0 · original }); }, onSuccess: (signature) => { transactionToast(signature); toast.success('Game created successfully!'); }, onError: (error) => toast.error(`Failed to create game: ${error.message}`), }); const joinGame = useMutation({ mutationKey: ['monsDotRehab', 'joinGame', { cluster }], mutationFn: async (gameIdString: string) => { const gameID = convertBase62StringToBN(gameIdString); const seeds = [Buffer.from('game'), Buffer.from(new BN(gameID).toArrayLike(Buffer, 'le', 8))]; const [gamePDA, bump] = await PublicKey.findProgramAddress(seeds, program.programId); return program.rpc.joinGame(new BN(gameID), { accounts: { game: gamePDA, guest: provider.wallet.publicKey, systemProgram: SystemProgram.programId, }, signers: [], }); },- Line 50
const seeds = [Buffer.from('game'), Buffer.from(new BN(gameID).toArrayLike(Buffer, 'le', 8: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 51
const [gamePDA, bump] = await PublicKey.findProgramAddress(seeds, program.programId);: Derives a PDA from seeds and the program ID and returns the address with its canonical bump. - Line 51
const [gamePDA, bump] = await PublicKey.findProgramAddress(seeds, program.programId);: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
How to run, build and test
These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.
| Directory | Command | Runs |
|---|---|---|
. | npm run dev | nx serve web |
. | npm run build | nx build web |
anchor | anchor build | compile programs and generate IDLs |
anchor | anchor test | local validator + test suite |
anchor | anchor run test | ../node_modules/.bin/nx run anchor:jest |
What you could build from it
- Fork the SuperStack copy and extend it within the NFTs & Digital Assets gaps listed on the idea page.
- Learn the pattern first: NFTs with Metaplex
- Learn the pattern first: Compressed NFTs and state compression
- Learn the pattern first: Token-2022 (Token Extensions)