A minimal landing page for Agent Town with two entry paths:
- Co-op unlock with a human + OpenClaw agent (Team Code + sigil match + dual Open press).
- Token-holder solo unlock using $ELIZATOWN on Solana.
The only identity is a session cookie for the human and a Team Code for the agent. No external auth providers.
- Human visits
/and gets a Team Code (session cookieet_session). - Agent connects via API, matches the same sigil, and both press Open.
/createopens a 16x16 co-op pixel canvas to generate entropy.- House ceremony combines human + agent entropy to derive a
houseIdand shared keys. /house?house=...unlocks with a Solana wallet signature and shows a descriptor QR, ERC-8004 statement, and optional ERC-8004 mint (Agent0 SDK).- Create a public share link and show up on the leaderboard; referrals are counted.
Token-holder path:
Use the token check on / to verify a Solana wallet holds $ELIZATOWN, then create a house without an agent via /create?mode=token.
npm install
npm run devnpm testTests reset state via POST /__test__/reset (header x-test-reset uses TEST_RESET_TOKEN, default test-reset).
Optional local integration check (reused Sepolia wallet):
REAL_SEPOLIA_WALLET_TEST=1 npx playwright test e2e/10_sepolia_wallet_reuse.spec.jsNotes:
- Setup command:
npm run setup:sepolia-wallet- Fresh setup auto-generates an EVM private key + address and stores it in
data/local.sepolia.wallet.json. - If balance is below threshold on fresh generation, setup attempts a Google Sepolia faucet request automatically.
- Test checks on-chain Sepolia ETH balance and fails with the faucet URL if below threshold.
- Override threshold with
MIN_SEPOLIA_ETH(default0.001). - Non-interactive setup (automation):
npm run setup:sepolia-wallet -- --no-balance-check- Provide your own wallet:
npm run setup:sepolia-wallet -- --address 0x...- Disable faucet automation:
npm run setup:sepolia-wallet -- --no-faucet- The agent skill is served at
/skill.md(source:public/skill.md). - Core agent endpoints:
/api/agent/connect,/api/agent/state,/api/agent/select,/api/agent/open/press. - Co-op actions:
/api/agent/canvas/paint,/api/agent/house/*. - House API auth and ceremony details are documented in
specs/02_api_contract.md.
/— onboarding, Team Code, token check, reconnect./create— co-op canvas + house generation./house— house unlock, descriptor QR, ERC-8004, encrypted log./s/:id— public share page./leaderboard— public teams and referrals (/wallredirects here).
- Store file:
data/store.sqlite(orSTORE_PATH). - Test store:
data/store.test.sqlitewhenNODE_ENV=test. - Legacy
data/store.jsonis imported automatically on first boot (non-test) if the SQLite store is empty. - Session state is in memory; signups/shares/public teams/houses persist in the store.
House entries are end-to-end encrypted. The server only stores ciphertext and never sees plaintext.
What the server stores:
- Encrypted house log entries (
ciphertextonly). - House metadata, including a wallet-wrapped
K_root(keyWrap) for recovery. houseAuthKey(HMAC key) for authenticating/api/house/:id/*requests.
What the server does not store:
- The raw
K_rootorK_encused to decrypt entries. - Any unencrypted house content.
- The
keyWrapSig(clients re-sign the wrap message during recovery).
Unlocking a house in the UI is gated by a Solana wallet signature. Decryption happens client-side after deriving keys from the ceremony materials.
PORT(default4173)NODE_ENV(productionenables HTTPS redirect + HSTS;testenables reset endpoint)STORE_PATH(override store file)SOLANA_RPC_URL(token check RPC, default mainnet-beta)TEST_RESET_TOKEN(required for/__test__/resetin tests)TEST_TOKEN_ADDRESS(test-only override for token-holder flow)
- API contract:
specs/02_api_contract.md - Experience flow:
specs/01_experience_flow.md - TDD milestones:
specs/04_tdd_milestones.md