The Contributor Voting application is built as a modern Single Page Application (SPA) using the following technology stack:
- Svelte - A modern, lightweight frontend framework
- TypeScript - For type-safe JavaScript development
- Vite - Next generation frontend tooling
- TailwindCSS - For utility-first styling
- Flowbite-Svelte - UI component library
The voting system is implemented as a Xian smart contract that enables token-weighted governance. Here's how it works:
-
Any token holder can create a proposal by providing:
- Title (10-50 characters)
- Description (minimum 100 characters)
- Expiration date and time
- Optional metadata
-
Creating a proposal requires paying a proposal fee (configurable by the contract owner)
-
Token holders can vote on active proposals with three options:
- "y" (Yes/For)
- "n" (No/Against)
- "-" (Abstain)
-
Key voting features:
- Each address can vote once per proposal
- Votes can be changed while the proposal is active
- Vote weight is determined by the voter's token balance
- Only votes from current token holders are counted
The system tracks two types of metrics for each proposal:
- Raw vote counts (total number of voters for each choice)
- Power-weighted totals (sum of token balances for each choice)
Tallies can be updated in two ways:
- Automatically after each vote (if enabled by contract settings)
- Manually by token holders during the voting period
-
Once a proposal expires:
- No more votes can be cast
- The proposal must be finalized to record final vote tallies
- Final tallies are calculated using current token balances at the time of finalization
-
The finalization process:
- Calculates and stores final vote counts and power-weighted totals
- Marks the proposal as "finalized"
- Emits an event with the final results
All voting actions emit blockchain events for:
- Proposal creation
- Vote casting (including vote changes)
- Proposal finalization with results
These events enable full transparency and auditability of the voting process.
Before running the SPA, ensure you have:
- Node.js (v18 or higher)
- npm (comes with Node.js)
-
Navigate to the SPA directory:
cd voting-spa
-
Install dependencies:
npm ci
-
Start the development server:
npm run dev
This will start the development server at
http://localhost:5173
(or another port if 5173 is in use)
To create a production build:
npm run build
The built files will be in the dist
directory, ready for deployment.
To preview the production build locally:
npm run preview
To run type checking:
npm run check
The SPA follows a standard Svelte project structure:
voting-spa/
├── src/
│ ├── routes/ # Page components
│ ├── components/ # Reusable UI components
│ ├── lib/ # Utilities and shared code
│ └── App.svelte # Root component
├── public/ # Static assets
└── index.html # Entry point
The application is automatically deployed to GitHub Pages when changes are pushed to the main branch. The deployment process is handled by GitHub Actions as defined in .github/workflows/deploy.yml
.
- The application uses Svelte's built-in reactivity system for state management
- TailwindCSS is used for styling with utility classes
- TypeScript is used throughout the project for better type safety and developer experience
- The SPA interacts with Xian smart contracts through the provided utilities in
src/lib/ts/js/xian-dapp-utils.ts