AbdelStark/ringable
Anonymous Voting platform using Nostringer ring signatures for Nostr keys.
๐ Ringable
A client-side anonymous voting platform using Nostr-compatible ring signatures.
Ringable allows users to create proposals and vote anonymously as part of a predefined group (a "ring" of public keys). It leverages the cryptographic power of bLSAG ring signatures to ensure that while votes are verified as coming from a valid member of the ring, the specific voter's identity remains hidden.
The cryptographic functions are powered by the Nostringer Rust library, compiled to WebAssembly (WASM) for use in the browser.
Built with a fun, retro pixel-art aesthetic, Ringable demonstrates modern cryptography in an engaging, user-friendly way.
โจ Key Features
- True Anonymity: Votes are cryptographically signed by a ring member without revealing which member signed.
- Linkability (Duplicate Prevention): Uses bLSAG signatures, which generate a unique "key image" per voter per proposal, preventing the same person from voting multiple times anonymously.
- Client-Side Only: No backend server required! All data (keys, rings, proposals, votes) is stored locally in the browser's
localStorage, managed via Zustand. - Retro Pixel-Art UI: A unique, game-inspired interface built with React and Tailwind CSS.
- Nostr Compatible Keys: Uses secp256k1 keys, compatible with the Nostr ecosystem.
- Monorepo Structure: Organized using Turborepo for better code sharing and maintainability.
๐ ๏ธ Tech Stack
- Monorepo: Turborepo
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- State Management: Zustand (with
persistmiddleware forlocalStorage) - UI Components: React (within shared
packages/ui) - Cryptography: Nostringer (Rust library supporting WASM)
- Package Manager: pnpm
- Linting/Formatting: ESLint, Prettier
๐ Project Structure
This project uses a Turborepo monorepo structure:
.
โโโ apps
โ โโโ web/ # Main Next.js web application (Ringable UI)
โ โโโ docs/ # (Optional) Placeholder for documentation site
โโโ packages
โ โโโ crypto/ # Wrapper for cryptography functions (Nostringer WASM - currently mocked)
โ โโโ eslint-config/ # Shared ESLint configuration
โ โโโ tailwind-config/ # Shared Tailwind CSS configuration
โ โโโ tsconfig/ # Shared TypeScript configuration
โ โโโ ui/ # Shared React UI components (Button, Card, Input, etc.)
โโโ package.json # Root configuration
๐ Getting Started
Prerequisites
- Node.js (Version specified in root
package.jsonengines field, e.g., >=18) - pnpm (Version specified in root
package.jsonpackageManager field, e.g., 8.x) - (Future Step) Rust toolchain and
wasm-packfor compiling thenostringerlibrary if replacing mocks.
Installation
- Clone the repository:
git clone https://github.com/AbdelStark/ringable.git cd ringable - Install dependencies from the root directory:
pnpm install
Running the Development Server
- Start the development server (this will run the Next.js app and watch for changes in shared packages):
pnpm run dev
- Open your browser to
http://localhost:3000to see the Ringable web application.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Built with love by AbdelStark ๐งก
Feel free to follow me on Nostr if you'd like, using my public key:
npub1hr6v96g0phtxwys4x0tm3khawuuykz6s28uzwtj5j0zc7lunu99snw2e29
Or just scan this QR code to find me:
