Authority-Based State Derivation
What is Authority-Based State Derivation?
All game state and player state accounts in Shrimp Farm are tied to an authority key.
This means every piece of on-chain data is derived using the authority's public key as a seed.
The authority key acts as a unique identifier that creates isolated game instances.
Different authority keys = completely separate games with their own state.
This design started as a necessity for our Anchor tests, but turned into a clean architectural pattern.
Why We Built It This Way
Testing Requirements
The local Solana validator used by anchor test doesn't support resetting state between tests.
Without authority-based derivation, all tests would share the same game state—causing interference.
Our solution: generate a fresh authority keypair for each test, creating isolated game instances.
Show the test setup
beforeEach(async () => {
await new Promise(r => setTimeout(r, 1000)); // prevent validator crashes
/* fresh game for every test */
authority = Keypair.generate();
gameStateAccount = utils.findGameDataAcc(authority.publicKey);
playerAccount = await utils.findPlayerDataAcc(
wallet.publicKey,
authority.publicKey
);
refAccount = Keypair.generate();
refStateAccount = await utils.findPlayerDataAcc(
refAccount.publicKey,
authority.publicKey
);
});
Clean Architecture
Authority-based derivation creates predictable, collision-free account addresses.
Every account type follows the same pattern: [specific_seeds, authority_key].
How Accounts Are Derived
All Program Derived Addresses (PDAs) include the authority key as the final seed:
Game State: ["shrimp", authority]
Player State: [player_pubkey, "shrimp", authority]
Contract Data: ["contractdata", authority]
Show the derivation utilities
const findPlayerDataAcc = (player: PublicKey, authority: PublicKey) => {
const [playerDataAcc, _] = PublicKey.findProgramAddressSync(
[player.toBuffer(), Buffer.from("shrimp"), authority.toBuffer()],
SHRIMP_PROGRAM_ID
);
return playerDataAcc;
};
const findGameDataAcc = (authority: PublicKey) => {
const [gameDataAcc] = PublicKey.findProgramAddressSync(
[Buffer.from("shrimp"), authority.toBuffer()],
SHRIMP_PROGRAM_ID
);
return gameDataAcc;
};
const findContractDataAcc = (authority: PublicKey) => {
const [contractDataAcc] = PublicKey.findProgramAddressSync(
[Buffer.from("contractdata"), authority.toBuffer()],
SHRIMP_PROGRAM_ID
);
return contractDataAcc;
};
Authority-Only Functions
The authority key also controls several admin functions that only work during initialization or in test environments:
set_market - Manually adjust market state (test env only)
end_premarket - Force pre-market to end early (test env only)
testnet_bonus - Toggle 1% bonus for specific accounts
set_collection - Set NFT collection (called once at deployment)
These functions verify the signer matches the stored authority before executing.