A modern React application for interacting with Sekiva's privacy-preserving voting system on Partisia Blockchain. Built with React, TypeScript, and Partisia's blockchain SDK.
- Core: React 18 + TypeScript + Vite
- Routing: React Router v7
- State Management: Tanstack Query v5
- Styling: Tailwind CSS v4 + shadcn/ui
- Blockchain: Partisia Blockchain SDK + ABI Client
- Package Manager: Bun
The frontend integrates with three main contracts through generated ABIs:
- Factory Contract (
useFactoryContract.ts) - Organization Contract (
useOrganizationContract.ts) - Ballot Contract (
useBallotContract.ts)
Each contract has a dedicated hook that:
- Uses generated ABIs for type-safe contract interactions
- Handles contract state management
- Manages transaction submission
- Provides real-time updates
Located in src/auth/:
AuthProvider.tsx: Manages wallet connections and session stateuseAuth.ts: Hook for accessing auth contextSessionManager.ts: Handles session persistence and recoveryAuthContext.ts: Type definitions for auth state
TransactionDialog.tsx: Reusable dialog for transaction status and feedbackuseTransactionStatus.ts: Hook for tracking transaction states across shards- Implements shard-aware polling
- Handles contract address derivation
- Provides real-time status updates
The application is designed to work with Partisia's sharded architecture:
- Transactions are submitted to specific shards
- Status polling checks multiple shards for transaction updates
- Contract addresses are derived based on transaction IDs and contract type
- Priority-based shard fallback for reliability
- Node.js 18+
- Bun package manager
- Partisia Blockchain testnet account
-
Install dependencies:
bun install
-
Generate contract ABIs:
# Build and generate ABI cd ../ballot && cargo pbc build --release && \ cargo pbc abi codegen --ts target/wasm32-unknown-unknown/release/ballot.abi ../sekiva-frontend/src/contracts/BallotGenerated.ts --deserialize-rpc
-
Start development server:
cd sekiva-fronted && bun dev
-
Contract Hooks
// Example usage of a contract hook const { deployOrganization, isLoading } = useFactoryContract(); const handleDeploy = async () => { const tx = await deployOrganization({ name: "My Org", description: "Description" }); // TransactionDialog handles the rest };
-
Transaction Handling
// TransactionDialog usage <TransactionDialog action="deploy" id={txId} destinationShard={shard} trait="collective" onSuccess={handleSuccess} />
-
Authentication
const { connect, account, isConnected } = useAuth();
src/
├── auth/ # Authentication and session management
├── components/ # React components
│ ├── shared/ # Reusable components
│ ├── ui/ # shadcn/ui components
│ └── ...
├── hooks/ # Custom hooks
│ ├── useFactoryContract.ts
│ ├── useOrganizationContract.ts
│ ├── useBallotContract.ts
│ └── useTransactionStatus.ts
├── lib/ # Utilities and helpers
├── partisia-config.ts # Blockchain configuration
└── ...
- Follow the TypeScript and React patterns established in the codebase
- Use the existing hooks for contract interactions
- Implement new features using the transaction dialog for UX consistency
- Add proper error handling for blockchain operations
- Update ABIs when contract interfaces change
-
Transaction Not Found
- Check the destination shard
- Verify transaction ID format
- Ensure proper contract address derivation
- Check explorer (link below)
-
Authentication Issues
- Clear browser storage
- Verify wallet connection
- Check network configuration
-
Contract Interaction Errors
- Verify ABI generation
- Check contract address
- Validate input parameters