1
- import { createPublicClient , createWalletClient , http , Hex , getContract } from "viem" ;
1
+ import { createPublicClient , createWalletClient , http , Hex , getContract , Address , decodeEventLog } from "viem" ;
2
2
import { mnemonicToAccount } from "viem/accounts" ;
3
3
import { hardhat } from "viem/chains" ;
4
4
import { encrypt , decrypt , DECRYPTION_DELAY } from "./shutter" ;
@@ -11,11 +11,10 @@ const SEPARATOR = "␟"; // U+241F
11
11
// Store encrypted votes for later decryption
12
12
type EncryptedVote = {
13
13
coreDisputeID : bigint ;
14
- encryptedCommitment : string ;
14
+ juror : Address ;
15
15
identity : Hex ;
16
+ encryptedVote : string ;
16
17
timestamp : number ;
17
- voteIDs : bigint [ ] ;
18
- salt : Hex ;
19
18
} ;
20
19
21
20
const encryptedVotes : EncryptedVote [ ] = [ ] ;
@@ -43,6 +42,15 @@ const disputeKit = getContract({
43
42
client : { public : publicClient , wallet : walletClient } ,
44
43
} ) ;
45
44
45
+ type CommitCastEventArgs = {
46
+ _coreDisputeID : bigint ;
47
+ _juror : Address ;
48
+ _voteIDs : bigint [ ] ;
49
+ _commit : Hex ;
50
+ _identity : Hex ;
51
+ _encryptedVote : string ;
52
+ } ;
53
+
46
54
/**
47
55
* Generate a random salt
48
56
*/
@@ -97,13 +105,19 @@ async function castCommit({
97
105
} ) ;
98
106
99
107
// Encrypt the message using shutter.ts
100
- const { encryptedCommitment, identity } = await encrypt ( message ) ;
108
+ const { encryptedCommitment : encryptedVote , identity } = await encrypt ( message ) ;
101
109
102
110
// Compute hash using all vote IDs
103
111
const commitHash = await disputeKit . read . hashVote ( [ choice , salt , justification ] ) ;
104
112
105
113
// Cast the commit on-chain
106
- const txHash = await disputeKit . write . castCommit ( [ coreDisputeID , voteIDs , commitHash , identity as Hex ] ) ;
114
+ const txHash = await disputeKit . write . castCommit ( [
115
+ coreDisputeID ,
116
+ voteIDs ,
117
+ commitHash ,
118
+ identity as Hex ,
119
+ encryptedVote ,
120
+ ] ) ;
107
121
108
122
// Wait for transaction to be mined
109
123
await publicClient . waitForTransactionReceipt ( { hash : txHash } ) ;
@@ -115,11 +129,10 @@ async function castCommit({
115
129
// Store encrypted vote for later decryption
116
130
encryptedVotes . push ( {
117
131
coreDisputeID,
118
- encryptedCommitment ,
132
+ juror : account . address ,
119
133
identity : identity as Hex ,
134
+ encryptedVote,
120
135
timestamp : Math . floor ( Date . now ( ) / 1000 ) ,
121
- voteIDs,
122
- salt,
123
136
} ) ;
124
137
125
138
return { commitHash, identity, salt } ;
@@ -143,16 +156,34 @@ export async function autoVote() {
143
156
144
157
for ( const vote of readyVotes ) {
145
158
try {
159
+ // Retrieve the CommitCast event
160
+ const filter = await publicClient . createContractEventFilter ( {
161
+ abi : DisputeKitShutterPoCAbi ,
162
+ eventName : "CommitCast" ,
163
+ args : [ vote . coreDisputeID , vote . juror ] ,
164
+ } ) ;
165
+ let events = await publicClient . getLogs ( filter ) ;
166
+ if ( events . length !== 1 ) {
167
+ throw new Error ( "No CommitCast event found" ) ;
168
+ }
169
+ const { args } = decodeEventLog ( {
170
+ abi : DisputeKitShutterPoCAbi ,
171
+ eventName : "CommitCast" ,
172
+ topics : events [ 0 ] . topics ,
173
+ data : events [ 0 ] . data ,
174
+ } ) ;
175
+ const commitCast = args as unknown as CommitCastEventArgs ; // Workaround getLogs type inference issue
176
+
146
177
// Attempt to decrypt the vote
147
- const decryptedMessage = await decrypt ( vote . encryptedCommitment , vote . identity ) ;
178
+ const decryptedMessage = await decrypt ( commitCast . _encryptedVote , commitCast . _identity ) ;
148
179
149
180
// Decode the decrypted message
150
181
const { choice, salt, justification } = decode ( decryptedMessage ) ;
151
182
152
183
// Cast the vote on-chain
153
184
const txHash = await disputeKit . write . castVote ( [
154
185
vote . coreDisputeID ,
155
- vote . voteIDs ,
186
+ commitCast . _voteIDs ,
156
187
choice ,
157
188
salt ,
158
189
justification ,
@@ -162,14 +193,14 @@ export async function autoVote() {
162
193
await publicClient . waitForTransactionReceipt ( { hash : txHash } ) ;
163
194
164
195
// Watch for VoteCast event
165
- const events = await disputeKit . getEvents . VoteCast ( ) ;
196
+ events = await disputeKit . getEvents . VoteCast ( ) ;
166
197
console . log ( "VoteCast event:" , ( events [ 0 ] as any ) . args ) ;
167
198
168
199
// Remove the processed vote
169
200
const index = encryptedVotes . indexOf ( vote ) ;
170
201
if ( index > - 1 ) encryptedVotes . splice ( index , 1 ) ;
171
202
} catch ( error ) {
172
- console . error ( `Error processing vote ${ vote . voteIDs . join ( "," ) } :` , error ) ;
203
+ console . error ( `Error processing vote for identity ${ vote . identity } :` , error ) ;
173
204
}
174
205
}
175
206
0 commit comments