AGENTS.md watermarks refreshed to HEAD (4dedc72). Watermark bump only —
no code changes since last gardener run.
Pending actions (3): re-queue promotion of #1155 pitch-deck to backlog
(pending actions from PR #1162 were not executed by orchestrator).
Escalate: #1158 (Phase 1 completion accuracy) — still needs planner/human decision.
3.3 KiB
Web App - Agent Guide
Vue 3 + TypeScript staking interface for KRAIKEN, enabling users to stake tokens, manage positions, and interact with Harberger-tax mechanics.
Technology Snapshot
- Vue 3 (Composition API) with TypeScript and Vite toolchain
- Wagmi/Viem for wallet connection and blockchain interaction
- Vue Router for navigation
- Axios for GraphQL queries to Ponder indexer
- Sass-based component styling
Architecture
Chain Configuration
src/services/chainConfig.ts centralizes endpoint resolution. All composables accept chainId as a parameter and resolve endpoints via chainConfigService.getEndpoint(chainId, type). Supported chains: 31337 (Anvil), 84532 (Base Sepolia), 8453 (Base Mainnet).
Wagmi Integration
src/wagmi.ts manages wallet connection. Wagmi is the source of truth for which chain the wallet is on. Composables don't import wallet state directly — they accept chainId for testability.
Key Composables
useWallet()— Wallet connection, balance, account stateusePositions(chainId)— Loads staking positions from Ponder GraphQLuseStatCollection(chainId)— Protocol-wide statisticsuseSnatchSelection(demo, taxRateIndex, chainId)— Calculates snatchable positionsuseStake()— Executes staking transactionsuseAdjustTaxRate()— Tax rate adjustmentuseUnstake()— Position exit transactions
Key Components
StakeView.vue— Main staking dashboard (route:/dashboard)StakeHolder.vue— Staking form with accessibility-focused UIConnectWallet.vue— Wallet connection modalChartComplete.vue— Position visualizationCollapseActive.vue— Expandable position card with actions
Development Workflow
- Boot full stack:
./scripts/dev.sh start(see root AGENTS.md) - Targeted:
npm run dev(assumes Ponder/Anvil already running) - Build:
npm run build - E2E tests:
npm run test:e2efrom repo root (Playwright)
Testing
- E2E tests in
tests/e2e/(repo root) cover complete user journeys - Uses mocked wallet provider with Anvil accounts
- Relies on semantic HTML and ARIA attributes for selectors
- StakeHolder test hooks:
page.getByRole('slider', { name: 'Token Amount' }),page.getByLabel('Tax')
Analytics
The web app uses @harb/analytics (self-hosted Umami wrapper) for funnel event tracking. initAnalytics(VITE_UMAMI_URL, VITE_UMAMI_WEBSITE_ID) is called in main.ts. Tracked events:
| Event | Where | Helper |
|---|---|---|
wallet_connect |
useWallet.ts — on first address set |
trackWalletConnect() |
swap_initiated |
useSwapKrk.ts — before buy/sell tx |
trackSwapInitiated('buy'|'sell') |
stake_created |
useStake.ts — after PositionCreated event |
trackStakeCreated() |
All calls are silent no-ops if Umami is unavailable. Env vars: VITE_UMAMI_URL, VITE_UMAMI_WEBSITE_ID.
Quality Guidelines
- Composables accept
chainIdparameter instead of importing wallet state directly - Each composable maintains its own
watchChainId()listener for independence - Always expose
xxxErrorandloadingrefs for UI feedback - Use strongly typed interfaces for Position, StatsRecord, etc.
- Use semantic HTML, ARIA attributes, and keyboard navigation
- Clear watchers and retry timers in
onUnmounted()