mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-24 01:41:02 +00:00
feat(mobile): implement blockchain election voting via pallet-welati
Replace TODO placeholder with real blockchain vote submission:
**Updated File:**
- mobile/src/screens/GovernanceScreen.tsx:217-293
**Implementation Details:**
- Implemented real election voting using pallet-welati
- Changed from commented TODO to functional `api.tx.welati.voteInElection(electionId, candidateId)`
- Added wallet connection validation before voting
- Supports single-vote elections (Presidential, Constitutional Court)
- Supports multi-vote elections (Parliamentary) using batch transactions
- Uses `api.tx.utility.batch()` to submit multiple votes atomically
**Features:**
- Presidential/Single elections: Submit single vote via `api.tx.welati.voteInElection()`
- Parliamentary elections: Batch multiple candidate votes using `api.tx.utility.batch()`
- Proper error handling with blockchain error decoding
- dispatchError handling for module-specific errors
- Success confirmation with vote count for multi-vote
- Automatic UI refresh after successful vote
- Loading state management during transaction
**Security:**
- Validates wallet connection before submission
- Checks selectedAccount and api availability
- Proper transaction signing with user's account
- Blockchain-level validation via pallet-welati
**User Experience:**
- Clear success messages ("Your vote has been recorded!")
- Vote count in success message for parliamentary elections
- Error messages with blockchain error details in dev mode
- Automatic sheet dismissal and data refresh on success
This completes P0 governance blockchain integration for mobile app.
Real blockchain voting matching pallet-welati specification.
This commit is contained in:
@@ -220,16 +220,70 @@ export default function GovernanceScreen() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!api || !selectedAccount || !selectedElection) {
|
||||
Alert.alert('Error', 'Wallet not connected');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setVoting(true);
|
||||
// TODO: Submit votes to blockchain via pallet-tiki
|
||||
// await api.tx.tiki.voteInElection(electionId, candidateIds).signAndSend(...)
|
||||
|
||||
Alert.alert('Success', 'Your vote has been recorded!');
|
||||
setElectionSheetVisible(false);
|
||||
setSelectedElection(null);
|
||||
setVotedCandidates([]);
|
||||
fetchElections();
|
||||
// Submit vote to blockchain via pallet-welati
|
||||
// For single vote (Presidential): api.tx.welati.voteInElection(electionId, candidateId)
|
||||
// For multiple votes (Parliamentary): submit each vote separately
|
||||
const electionId = selectedElection.id;
|
||||
|
||||
if (selectedElection.type === 'Parliamentary') {
|
||||
// Submit multiple votes for parliamentary elections
|
||||
const txs = votedCandidates.map(candidateId =>
|
||||
api.tx.welati.voteInElection(electionId, candidateId)
|
||||
);
|
||||
|
||||
// Batch all votes together
|
||||
const batchTx = api.tx.utility.batch(txs);
|
||||
|
||||
await batchTx.signAndSend(selectedAccount.address, ({ status, dispatchError }) => {
|
||||
if (dispatchError) {
|
||||
if (dispatchError.isModule) {
|
||||
const decoded = api.registry.findMetaError(dispatchError.asModule);
|
||||
throw new Error(`${decoded.section}.${decoded.name}: ${decoded.docs}`);
|
||||
} else {
|
||||
throw new Error(dispatchError.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (status.isInBlock) {
|
||||
Alert.alert('Success', `Your ${votedCandidates.length} votes have been recorded!`);
|
||||
setElectionSheetVisible(false);
|
||||
setSelectedElection(null);
|
||||
setVotedCandidates([]);
|
||||
fetchElections();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Single vote for presidential/other elections
|
||||
const candidateId = votedCandidates[0];
|
||||
const tx = api.tx.welati.voteInElection(electionId, candidateId);
|
||||
|
||||
await tx.signAndSend(selectedAccount.address, ({ status, dispatchError }) => {
|
||||
if (dispatchError) {
|
||||
if (dispatchError.isModule) {
|
||||
const decoded = api.registry.findMetaError(dispatchError.asModule);
|
||||
throw new Error(`${decoded.section}.${decoded.name}: ${decoded.docs}`);
|
||||
} else {
|
||||
throw new Error(dispatchError.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (status.isInBlock) {
|
||||
Alert.alert('Success', 'Your vote has been recorded!');
|
||||
setElectionSheetVisible(false);
|
||||
setSelectedElection(null);
|
||||
setVotedCandidates([]);
|
||||
fetchElections();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (__DEV__) console.error('Election voting error:', error);
|
||||
Alert.alert('Error', error.message || 'Failed to submit vote');
|
||||
|
||||
Reference in New Issue
Block a user