PROD-003: Add analytics tracking for proposal and vote activity - #3
Open
ZainabJanee wants to merge 78 commits into
Open
PROD-003: Add analytics tracking for proposal and vote activity#3ZainabJanee wants to merge 78 commits into
ZainabJanee wants to merge 78 commits into
Conversation
…3289#315) - Integrate Freighter wallet connection - Require explicit wallet signature for voting and proposal creation - Ensure unsigned transactions are never submitted
…3289#321) - Integrate Plausible analytics - Track wallet connections, proposal views, and action submissions - Collect metrics for confirmed transactions
- Install Vitest, @testing-library/react, jest-dom, user-event, jsdom - Configure Vitest in vite.config.ts with jsdom environment - Add test/test:watch scripts to package.json - Add 4 tests covering all acceptance criteria: - connect button triggers Freighter connection - connected state shows truncated address - disconnect clears wallet state - Freighter not installed shows install prompt - Freighter API mocked via window.freighter
…-013) Adds 8 tests covering all acceptance criteria for issue Vera3289#300: - AC1: transfer_admin succeeds with valid new admin; new admin can cancel - AC2: non-admin cannot call execute, cancel, or pause (NotAdmin #2) - AC3: old admin loses execute, cancel, and pause after transfer - AC4: transfer to zero address reverts with InvalidAddress (Vera3289#28) Tests follow existing patterns (mock_all_auths, setup_passed_proposal, setup_active_proposal helpers) and are grouped under TEST-013 section.
Triggers on push and PR to main. Builds both governance and token WASM contracts via stellar contract build, verifies both binaries exist, and uploads them as artifacts. Fails fast on any build error. Closes Vera3289#258
Covers all acceptance criteria: - Full event schema tables for governance and token contracts - JavaScript examples for subscribing via Horizon/RPC getEvents - Paginated event replay for historical data - Continuous indexer class for live polling - Proposal index builder from event stream Closes Vera3289#283
- Add docs/soroban-gotchas.md covering: - Storage TTL and expiry across all three tiers - Contract size limits and optimisation tips - Cross-contract call costs and budget model - Auth model differences from EVM (no msg.sender, require_auth) - WASM determinism requirements and forbidden features - Link new page from docs/GETTING_STARTED.md Next Steps section
…289#289) Three end-to-end tests covering all acceptance criteria: - test_lifecycle_passed_and_executed: create → vote Yes → finalise Passed → execute - test_lifecycle_rejected: create → vote No (below quorum) → finalise Rejected - test_lifecycle_cancelled_mid_vote: create → vote → cancel mid-vote Tests use env.register() to run against the compiled WASM contract.
…ra3289#281) Add 'Storage Cost Estimates' section to docs/storage.md covering: - Fee model overview (inclusion fee + resource fee) - Cost table for create_proposal, cast_vote, finalise, execute, cancel - Storage rent estimates for long-running proposals per entry type - Cost-saving notes (read-only calls, instance storage, cast_vote overhead) - How to get exact estimates via simulateTransaction
- Add contracts/governance/fuzz/Cargo.toml with libfuzzer-sys 0.4 and testutils features for governance + token contracts - Add fuzz_create_proposal target that exercises all four inputs: title, description, quorum, and duration with arbitrary byte data - Invariant: create_proposal must never panic; only Ok or ContractError - Add .github/workflows/fuzz.yml as an optional nightly CI job (continue-on-error, uploads crash artifacts on failure) Closes Vera3289#288
- Add tags: Vec<String> field to Proposal struct - Add TooManyTags (Vera3289#35) and TagTooLong (Vera3289#36) error variants - create_proposal accepts optional tags (max 5, max 32 chars each) - Tags stored and returned as part of Proposal via get_proposal - Add MAX_TAGS=5 and MAX_TAG_LEN=32 constants - Update all existing create_proposal call sites to pass empty tags - Add 7 tests covering tag storage, validation, and isolation Closes Vera3289#253
- Add InvalidTokenContract (Vera3289#35) error variant - Call try_balance() and try_total_supply() on token at init - Revert with InvalidTokenContract if either call fails - Add tests for valid and invalid token contracts Closes Vera3289#247
- Add useOgMeta hook to set og:title, og:description, og:image, og:url, og:type, og:site_name, and all twitter:card tags - Truncates description to 200 chars for card previews - Falls back to votechain.dev/og-default.png when no custom image - Wire hook into ProposalDetail, restores default title on unmount - Add static fallback OG/Twitter tags to index.html for non-JS crawlers Closes Vera3289#329
- SVG logo in light and dark variants (assets/logo-light.svg, logo-dark.svg) - Full design token set in styles/tokens.css: - Color palette: brand (9 steps), neutral (11 steps), status, dark-mode aliases - Typography: font families, scale (xs–4xl), weights, line-heights, tracking - Spacing scale (4px base, 0–24) - Border radius, shadows, motion, z-index - Dark mode via prefers-color-scheme and html.dark class - JS/TS token export in styles/tokens.ts for charting libs and dynamic styles Closes Vera3289#324
… enforcement tests
…(SEC-016) PROD-005: NotificationSubscribe component with email/webhook form, event selection (created/voting_ended/executed), and unsubscribe list persisted in localStorage. Rendered in GovernanceDashboard. SEC-016: PhishingWarning modal shown on first wallet connect, displays current domain, requires acknowledgement, supports 'don't show again' via localStorage. Wired into FreighterWallet.
Display a warning modal on first wallet connect showing the current domain. User must acknowledge before proceeding. Supports 'don't show again' via localStorage.
Closes Vera3289#292 — TEST-005: Add tests for all ContractError variants ───────────────────────────────────────────────────────────────── Every ContractError variant in both contracts now has at least one test that triggers it and asserts the correct error is returned. Governance (contracts/governance/src/test.rs): - AdminNotSet (1): call execute() on an uninitialised contract - VotingTokenNotSet (3): discriminant assertion (unreachable via public API since initialize sets both atomically; variant confirmed) - InvalidDuration (5): create_proposal with duration = 0 - ProposalNotFound (6): get_proposal with a non-existent ID - VotingPeriodEnded (8): cast_vote after the voting window closes - VotingStillOpen (9): finalise before the voting window closes - NoVotingPower (11): cast_vote with zero token balance - ProposalNotPassed (12): execute an Active (not Passed) proposal Previously untested variants now all have dedicated #[should_panic] or assertion tests. Variants already covered (NotAdmin, InvalidQuorum, ProposalNotActive, AlreadyVoted, AlreadyInitialized) are unchanged. Token (contracts/token/src/test.rs): - AdminNotSet (1): call mint() before initialize() - InvalidAmount (3): transfer with amount = 0; mint with amount = 0 - AllowanceExceeded (5): transfer_from exceeding approved allowance Previously untested variants now covered. NotAdmin and InsufficientBalance were already tested. Closes Vera3289#291 — TEST-004: Configure cargo-tarpaulin coverage in CI ───────────────────────────────────────────────────────────────── Added a new 'coverage' job to .github/workflows/ci.yml that: 1. Installs cargo-tarpaulin (pinned via --locked) 2. Runs tarpaulin across the whole workspace with a 120 s timeout and outputs a Cobertura XML report 3. Enforces a 70 % line-coverage minimum threshold — the build fails if coverage drops below this floor 4. Uploads the coverage report as a CI artifact for inspection The job depends on the existing 'test' job so it only runs after tests pass. Closes Vera3289#293 — TEST-006: Add snapshot tests for contract event payloads ─────────────────────────────────────────────────────────────────────── Added explicit event-payload assertion tests for every governance state transition in contracts/governance/src/test.rs. Each test calls env.events().all() and asserts that an event with the exact expected topics tuple and data value was emitted: - test_event_proposal_created → ("created", id) / proposer address - test_event_vote_cast → ("vote", id) / (voter, Vote::Yes, weight) - test_event_proposal_finalised_passed → ("final", id) / ProposalStatus::Passed - test_event_proposal_finalised_rejected → ("final", id) / ProposalStatus::Rejected - test_event_proposal_executed → ("final", id) / ProposalStatus::Executed - test_event_proposal_cancelled → ("final", id) / ProposalStatus::Cancelled - test_event_quorum_updated → ("qupdate", id) / new_quorum i128 These tests pin the exact event schema so any accidental change to topic keys, argument order, or data type will break CI immediately. Closes Vera3289#307 — SEC-005: Add overflow protection for vote weight accumulation ──────────────────────────────────────────────────────────────────────────── The three .expect("vote tally overflow") calls in cast_vote (contracts/governance/src/lib.rs) were replaced with: .ok_or(ContractError::Overflow)? This converts an i128 arithmetic overflow from a contract panic into a clean, catchable ContractError::Overflow (discriminant 14), which is returned to the caller instead of aborting the transaction with an unstructured panic message. A new Overflow = 14 variant was added to the ContractError enum in contracts/governance/src/types.rs. All three vote branches (Yes, No, Abstain) are protected.
added 30 commits
June 2, 2026 08:51
…esolution docs: expand errors.md with all error codes, causes, and resolution steps
do: add pre-commit hooks for fmt and clippy checks
do: add SBOM generation workflow via cargo-cyclonedx
do: add release workflow with CHANGELOG notes and WASM artifacts
…ui-enhancements feat: implement responsive proposal layout and empty state UI (closes Vera3289#215, closes Vera3289#231)
…ing-warning feat: add phishing protection warning for wallet connection (SEC-016)
feat: add notification subscriptions (PROD-005) and phishing warning …
…acts227 feature:Implement optimistic UI updates for vote submission
…-secrets SC-015: Audit deployment scripts for secret exposure
…ylesheet FE-025: Add print stylesheet for proposal detail page
…-admin SC-003: Add multi-sig admin support for governance contract
…d-design-system feat(PROD-006): add brand identity and design system
feat(PROD-011): add OG and Twitter Card meta tags for proposal sharing
…validation feat(SC-008): validate SEP-41 compliance at initialization
…al-tags feat(SC-014): add proposal categories/tags support
…creation test(Vera3289#288): add cargo-fuzz target for create_proposal inputs
…timates docs: add storage cost estimates for governance operations (closes Vera3289#281)
…ycle-integration test: add integration tests for full proposal lifecycle (closes Vera3289#289)
docs: add Soroban gotchas and limitations page (closes Vera3289#287)
…-indexing-guide docs: event indexing guide for off-chain applications (DOC-011)
…ld-workflow ci: add dedicated WASM build workflow (DO-001)
…n-transfer-privilege-tests test(governance): admin transfer and privilege escalation tests (TEST-013)
…et-connection-unit-tests test(frontend): wallet connection unit tests (TEST-010)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements PROD-003 (Issue Vera3289#321) by integrating Plausible analytics to track critical user flows including wallet connections, proposal views, and transaction submissions.
Closes Vera3289#321