📄 src/web3/vue/handlers/sessionVoteHandler.ts
D-OPEN SOVEREIGN
1import { sessionStore } from '../../session/store';
2import type { ChainMutation, MutationHandler } from '../MutationBus';
3
4type VoteMutation = Extract<ChainMutation, { type: 'vote' }>;
5
6interface VoteSnapshot {
7  chainId: number;
8  account: string;
9  donationsPerProject?: number[];
10  projectBalance?: { contributions: number; allocated: number; remaining: number };
11}
12
13export const sessionVoteHandler: MutationHandler<VoteMutation> = {
14  applyOptimistic: (mutation): VoteSnapshot | null => {
15    const account = sessionStore
16      .getState()
17      .known.find((a) => a.account.toLowerCase() === mutation.account.toLowerCase() && a.chainId === mutation.chainId);
18    if (!account) return null;
19
20    const snapshot: VoteSnapshot = {
21      chainId: mutation.chainId,
22      account: mutation.account,
23      donationsPerProject: account.donationsPerProject ? [...account.donationsPerProject] : undefined,
24      projectBalance: account.projectBalance ? { ...account.projectBalance } : undefined,
25    };
26
27    const votes = account.donationsPerProject ? [...account.donationsPerProject] : [];
28    votes[mutation.projectId - 1] = (votes[mutation.projectId - 1] || 0) + mutation.amount;
29
30    const patch: { donationsPerProject: number[]; projectBalance?: typeof account.projectBalance } = {
31      donationsPerProject: votes,
32    };
33    if (account.projectBalance) {
34      patch.projectBalance = {
35        ...account.projectBalance,
36        allocated: account.projectBalance.allocated + mutation.amount,
37        remaining: account.projectBalance.remaining - mutation.amount,
38      };
39    }
40
41    sessionStore.updateAccount(mutation.account, mutation.chainId, patch);
42    return snapshot;
43  },
44
45  rollback: (snapshot: VoteSnapshot | null) => {
46    if (!snapshot) return;
47    sessionStore.updateAccount(snapshot.account, snapshot.chainId, {
48      donationsPerProject: snapshot.donationsPerProject,
49      projectBalance: snapshot.projectBalance,
50    });
51  },
52};
53