@crisp-e3/sdk 0.3.0-test → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,18 +1,79 @@
1
1
  # CRISP SDK
2
2
 
3
- This package is CRISP's TypeScript SDK for interacting with CRISP and the CRISP server.
3
+ TypeScript SDK for interacting with CRISP (Cryptographically Secure and Private voting protocol) and
4
+ the CRISP server.
4
5
 
5
6
  ## Installation
6
7
 
7
8
  ```bash
8
- npm install @enclave/crisp-sdk
9
+ npm install @crisp-e3/sdk
9
10
  ```
10
11
 
11
- ## Release
12
+ ## Features
12
13
 
13
- The SDK is published on npmjs and does not follow the same versioning as the main Enclave packages.
14
- To release a new version, run the following command:
14
+ - **Round Management**: Fetch round details, token requirements, and voting parameters
15
+ - **Token Operations**: Query token balances and total supply at specific blocks
16
+ - **Merkle Tree Utilities**: Generate proofs for voter inclusion in the eligibility tree
17
+ - **Vote Proof Generation**: Create zero-knowledge proofs for votes and mask votes
18
+ - **Proof Verification**: Verify generated proofs using Noir circuits
15
19
 
16
- ```bash
17
- pnpm release
20
+ ## Usage
21
+
22
+ ### Get Round Details
23
+
24
+ ```typescript
25
+ import { getRoundDetails } from '@crisp-e3/sdk'
26
+
27
+ const roundDetails = await getRoundDetails(serverUrl, e3Id)
28
+ ```
29
+
30
+ ### Get Token Balance
31
+
32
+ ```typescript
33
+ import { getBalanceAt } from '@crisp-e3/sdk'
34
+
35
+ const balance = await getBalanceAt(voterAddress, tokenAddress, snapshotBlock, chainId)
36
+ ```
37
+
38
+ ### Generate Vote Proof
39
+
40
+ ```typescript
41
+ import { generateVoteProof } from '@crisp-e3/sdk'
42
+
43
+ const proof = await generateVoteProof({
44
+ vote: { yes: 100n, no: 0n },
45
+ publicKey: publicKeyBytes,
46
+ signature: '0x...',
47
+ balance: 1000n,
48
+ merkleLeaves: [...],
49
+ })
50
+ ```
51
+
52
+ ### Generate Mask Vote Proof
53
+
54
+ ```typescript
55
+ import { generateMaskVoteProof } from '@crisp-e3/sdk'
56
+
57
+ const maskProof = await generateMaskVoteProof({
58
+ balance: 1000n,
59
+ slotAddress: '0x...',
60
+ publicKey: publicKeyBytes,
61
+ merkleLeaves: [...],
62
+ previousCiphertext: previousCiphertextBytes, // optional
63
+ })
18
64
  ```
65
+
66
+ ### Verify Proof
67
+
68
+ ```typescript
69
+ import { verifyProof } from '@crisp-e3/sdk'
70
+
71
+ const isValid = await verifyProof(proof)
72
+ ```
73
+
74
+ ## API
75
+
76
+ - **State**: `getRoundDetails`, `getRoundTokenDetails`
77
+ - **Token**: `getBalanceAt`, `getTotalSupplyAt`, `getTreeData`
78
+ - **Vote**: `generateVoteProof`, `generateMaskVoteProof`, `verifyProof`, `decodeTally`
79
+ - **Utils**: `generateMerkleProof`, `generateMerkleTree`, `hashLeaf`, `getAddressFromSignature`
package/dist/index.d.ts CHANGED
@@ -27,9 +27,9 @@ declare const getBalanceAt: (voterAddress: string, tokenAddress: string, snapsho
27
27
  declare const getTotalSupplyAt: (tokenAddress: string, snapshotBlock: number, chainId: number) => Promise<bigint>;
28
28
 
29
29
  /**
30
- * Interface representing the details of a specific round returned by the CRISP server
30
+ * Type representing the details of a specific round returned by the CRISP server
31
31
  */
32
- interface IRoundDetailsResponse {
32
+ type RoundDetailsResponse = {
33
33
  id: string;
34
34
  chain_id: string;
35
35
  enclave_address: string;
@@ -43,11 +43,11 @@ interface IRoundDetailsResponse {
43
43
  emojis: [string, string];
44
44
  token_address: string;
45
45
  balance_threshold: string;
46
- }
46
+ };
47
47
  /**
48
- * Interface representing the details of a specific round in a more convenient format
48
+ * Type representing the details of a specific round in a more convenient format
49
49
  */
50
- interface IRoundDetails {
50
+ type RoundDetails = {
51
51
  e3Id: bigint;
52
52
  chainId: bigint;
53
53
  enclaveAddress: string;
@@ -61,39 +61,29 @@ interface IRoundDetails {
61
61
  emojis: [string, string];
62
62
  tokenAddress: string;
63
63
  balanceThreshold: bigint;
64
- }
64
+ };
65
65
  /**
66
- * Interface representing the token details required for participation in a round
66
+ * Type representing the token details required for participation in a round
67
67
  */
68
- interface ITokenDetails {
68
+ type TokenDetails = {
69
69
  tokenAddress: string;
70
70
  threshold: bigint;
71
71
  snapshotBlock: bigint;
72
- }
72
+ };
73
73
  /**
74
- * Interface representing a Merkle proof
74
+ * Type representing a Merkle proof
75
75
  */
76
- interface IMerkleProof {
76
+ type MerkleProof = {
77
77
  leaf: bigint;
78
78
  index: number;
79
79
  proof: LeanIMTMerkleProof<bigint>;
80
80
  length: number;
81
81
  indices: number[];
82
- }
83
- /**
84
- * Enum representing the voting modes
85
- */
86
- declare enum VotingMode {
87
- /**
88
- * Governance voting requires to spend all credits on one option
89
- they cannot be split
90
- */
91
- GOVERNANCE = "GOVERNANCE"
92
- }
82
+ };
93
83
  /**
94
- * Interface representing a vote with power for 'yes' and 'no'
84
+ * Type representing a vote with power for 'yes' and 'no'
95
85
  */
96
- interface IVote {
86
+ type Vote = {
97
87
  /**
98
88
  * The voting power for 'yes' votes
99
89
  */
@@ -102,144 +92,45 @@ interface IVote {
102
92
  * The voting power for 'no' votes
103
93
  */
104
94
  no: bigint;
105
- }
106
- /**
107
- * Interface representing a vector with coefficients
108
- */
109
- interface Polynomial {
110
- coefficients: string[];
111
- }
112
- /**
113
- * Interface representing cryptographic parameters
114
- */
115
- interface GrecoCryptographicParams {
116
- q_mod_t: string;
117
- qis: string[];
118
- k0is: string[];
119
- }
120
- /**
121
- * Interface representing Greco bounds
122
- */
123
- interface GrecoBoundParams {
124
- e_bound: string;
125
- u_bound: string;
126
- k1_low_bound: string;
127
- k1_up_bound: string;
128
- p1_bounds: string[];
129
- p2_bounds: string[];
130
- pk_bounds: string[];
131
- r1_low_bounds: string[];
132
- r1_up_bounds: string[];
133
- r2_bounds: string[];
134
- }
135
- /**
136
- * Interface representing Greco parameters
137
- */
138
- interface GrecoParams {
139
- crypto: GrecoCryptographicParams;
140
- bounds: GrecoBoundParams;
141
- }
142
- /**
143
- * The inputs required for the CRISP circuit
144
- */
145
- interface CRISPCircuitInputs {
146
- prev_ct0is: Polynomial[];
147
- prev_ct1is: Polynomial[];
148
- sum_ct0is: Polynomial[];
149
- sum_ct1is: Polynomial[];
150
- sum_r0is: Polynomial[];
151
- sum_r1is: Polynomial[];
152
- params: GrecoParams;
153
- ct0is: Polynomial[];
154
- ct1is: Polynomial[];
155
- pk0is: Polynomial[];
156
- pk1is: Polynomial[];
157
- r1is: Polynomial[];
158
- r2is: Polynomial[];
159
- p1is: Polynomial[];
160
- p2is: Polynomial[];
161
- u: Polynomial;
162
- e0: Polynomial;
163
- e1: Polynomial;
164
- e0is: Polynomial[];
165
- k1: Polynomial;
166
- public_key_x: string[];
167
- public_key_y: string[];
168
- signature: string[];
169
- hashed_message: string[];
170
- merkle_root: string;
171
- merkle_proof_length: string;
172
- merkle_proof_indices: string[];
173
- merkle_proof_siblings: string[];
174
- slot_address: string;
175
- balance: string;
176
- is_first_vote: boolean;
177
- }
178
- /**
179
- * Interface representing the inputs for Noir signature verification
180
- */
181
- interface NoirSignatureInputs {
182
- /**
183
- * X coordinate of the public key
184
- */
185
- pub_key_x: Uint8Array;
186
- /**
187
- * Y coordinate of the public key
188
- */
189
- pub_key_y: Uint8Array;
190
- /**
191
- * The signature to verify
192
- */
193
- signature: Uint8Array;
194
- /**
195
- * The hashed message that was signed
196
- */
197
- hashed_message: Uint8Array;
198
- }
199
- /**
200
- * Parameters for encryptVoteAndGenerateCRISPInputs function
201
- */
202
- interface EncryptVoteAndGenerateCRISPInputsParams {
203
- encodedVote: string[];
95
+ };
96
+ type MaskVoteProofInputs = {
97
+ previousCiphertext?: Uint8Array;
98
+ merkleLeaves: string[] | bigint[];
204
99
  publicKey: Uint8Array;
205
- previousCiphertext: Uint8Array;
206
- signature: `0x${string}`;
207
- message: string;
208
- merkleData: IMerkleProof;
209
100
  balance: bigint;
210
101
  slotAddress: string;
211
- isFirstVote: boolean;
212
- }
102
+ };
103
+ type VoteProofInputs = {
104
+ merkleLeaves: string[] | bigint[];
105
+ publicKey: Uint8Array;
106
+ balance: bigint;
107
+ vote: Vote;
108
+ signature: `0x${string}`;
109
+ };
213
110
 
214
111
  /**
215
112
  * Get the details of a specific round
216
113
  */
217
- declare const getRoundDetails: (serverUrl: string, e3Id: number) => Promise<IRoundDetails>;
114
+ declare const getRoundDetails: (serverUrl: string, e3Id: number) => Promise<RoundDetails>;
218
115
  /**
219
116
  * Get the token address, balance threshold and snapshot block for a specific round
220
117
  * @param serverUrl - The base URL of the CRISP server
221
118
  * @param e3Id - The e3Id of the round
222
119
  * @returns The token address, balance threshold and snapshot block
223
120
  */
224
- declare const getRoundTokenDetails: (serverUrl: string, e3Id: number) => Promise<ITokenDetails>;
121
+ declare const getRoundTokenDetails: (serverUrl: string, e3Id: number) => Promise<TokenDetails>;
225
122
 
226
- declare const CRISP_SERVER_TOKEN_TREE_ENDPOINT = "state/token-holders";
227
- declare const CRISP_SERVER_STATE_LITE_ENDPOINT = "state/lite";
228
123
  declare const MERKLE_TREE_MAX_DEPTH = 20;
229
- /**
230
- * Half the minimum degree needed to support the maxium vote value
231
- * If you change MAXIMUM_VOTE_VALUE, make sure to update this value too.
232
- */
233
- declare const HALF_LARGEST_MINIMUM_DEGREE = 28;
234
124
  /**
235
125
  * This is the maximum value for a vote (Yes or No). This is 2^28 - 1
236
126
  * The minimum degree that BFV should use is 56 (to accommodate both Yes and No votes)
237
127
  */
238
128
  declare const MAXIMUM_VOTE_VALUE: bigint;
239
129
  /**
240
- * Mock message for masking signature
130
+ * Message used by users to prove ownership of their Ethereum account
131
+ * This message is signed by the user's private key to authenticate their identity
241
132
  */
242
- declare const MESSAGE = "Vote for round 0";
133
+ declare const SIGNATURE_MESSAGE = "CRISP: Sign this message to prove ownership of your Ethereum account";
243
134
 
244
135
  /**
245
136
  * Hash a leaf node for the Merkle tree
@@ -247,7 +138,7 @@ declare const MESSAGE = "Vote for round 0";
247
138
  * @param balance The voter's balance
248
139
  * @returns The hashed leaf as a bigint
249
140
  */
250
- declare const hashLeaf: (address: string, balance: string) => bigint;
141
+ declare const hashLeaf: (address: string, balance: bigint) => bigint;
251
142
  /**
252
143
  * Generate a new LeanIMT with the leaves provided
253
144
  * @param leaves The leaves of the Merkle tree
@@ -256,91 +147,23 @@ declare const hashLeaf: (address: string, balance: string) => bigint;
256
147
  declare const generateMerkleTree: (leaves: bigint[]) => LeanIMT;
257
148
  /**
258
149
  * Generate a Merkle proof for a given address to prove inclusion in the voters' list
259
- * @param threshold The minimum balance required to be eligible
260
150
  * @param balance The voter's balance
261
151
  * @param address The voter's address
262
152
  * @param leaves The leaves of the Merkle tree
263
153
  */
264
- declare const generateMerkleProof: (threshold: bigint, balance: bigint, address: string, leaves: bigint[]) => IMerkleProof;
265
- /**
266
- * Convert a number to its binary representation
267
- * @param number The number to convert to binary
268
- * @returns The binary representation of the number as a string
269
- */
270
- declare const toBinary: (number: bigint) => string;
154
+ declare const generateMerkleProof: (balance: bigint, address: string, leaves: bigint[] | string[]) => MerkleProof;
155
+ declare const getAddressFromSignature: (signature: `0x${string}`) => Promise<string>;
271
156
 
272
157
  /**
273
- * This utility function calculates the first valid index for vote options
274
- * based on the total voting power and degree.
275
- * @dev This is needed to calculate the decoded plaintext
276
- * @dev Also, we will need to check in the circuit that anything within these indices is
277
- * either 0 or 1.
278
- * @param totalVotingPower The maximum vote amount (if a single voter had all of the power)
279
- * @param degree The degree of the polynomial
280
- */
281
- declare const calculateValidIndicesForPlaintext: (totalVotingPower: bigint, degree: number) => {
282
- yesIndex: number;
283
- noIndex: number;
284
- };
285
- /**
286
- * Encode a vote based on the voting mode
287
- * @param vote The vote to encode
288
- * @param votingMode The voting mode to use for encoding
289
- * @param votingPower The voting power of the voter
290
- * @param bfvParams The BFV parameters to use for encoding
291
- * @returns The encoded vote as a string
292
- */
293
- declare const encodeVote: (vote: IVote, votingMode: VotingMode, votingPower: bigint) => string[];
294
- /**
295
- * Given an encoded tally, decode it into its decimal representation
296
- * @param tally The encoded tally to decode
297
- * @param votingMode The voting mode
298
- */
299
- declare const decodeTally: (tally: string[], votingMode: VotingMode) => IVote;
300
- /**
301
- * Validate whether a vote is valid for a given voting mode
302
- * @param votingMode The voting mode to validate against
303
- * @param vote The vote to validate
304
- * @param votingPower The voting power of the voter
305
- */
306
- declare const validateVote: (votingMode: VotingMode, vote: IVote, votingPower: bigint) => void;
307
- declare const encryptVote: (encodedVote: string[], publicKey: Uint8Array) => Promise<Uint8Array>;
308
- declare const generatePublicKey: () => Promise<Uint8Array>;
309
- /**
310
- * This is a wrapper around enclave-e3/sdk encryption functions as CRISP circuit will require some more
311
- * input values which generic Greco do not need.
312
- * @param encodedVote The encoded vote as string array
313
- * @param publicKey The public key to use for encryption
314
- * @param previousCiphertext The previous ciphertext to use for addition operation
315
- * @param bfvParams The BFV parameters to use for encryption
316
- * @param merkleData The merkle proof data
317
- * @param message The message that was signed
318
- * @param signature The signature of the message
319
- * @param balance The voter's balance
320
- * @param slotAddress The voter's slot address
321
- * @param isFirstVote Whether this is the first vote for this slot
322
- * @returns The CRISP circuit inputs
323
- */
324
- declare const encryptVoteAndGenerateCRISPInputs: ({ encodedVote, publicKey, previousCiphertext, merkleData, message, signature, balance, slotAddress, isFirstVote, }: EncryptVoteAndGenerateCRISPInputsParams) => Promise<CRISPCircuitInputs>;
325
- /**
326
- * A function to generate the data required to mask a vote
327
- * @param voter The voter's address
328
- * @param publicKey The voter's public key
329
- * @param previousCiphertext The previous ciphertext
330
- * @param merkleRoot The merkle root of the census tree
331
- * @param slotAddress The voter's slot address
332
- * @param isFirstVote Whether this is the first vote for this slot
333
- * @returns The CRISP circuit inputs for a mask vote
158
+ * Decode an encoded tally into its decimal representation.
159
+ * @param tally The encoded tally to decode.
160
+ * @returns The decoded tally as an IVote.
334
161
  */
335
- declare const generateMaskVote: (publicKey: Uint8Array, previousCiphertext: Uint8Array, merkleRoot: bigint, slotAddress: string, isFirstVote: boolean) => Promise<CRISPCircuitInputs>;
336
- declare const generateProof: (crispInputs: CRISPCircuitInputs) => Promise<ProofData>;
337
- declare const generateProofWithReturnValue: (crispInputs: CRISPCircuitInputs) => Promise<{
338
- returnValue: unknown;
339
- proof: ProofData;
340
- }>;
341
- declare const getCircuitOutputValue: (crispInputs: CRISPCircuitInputs) => Promise<{
342
- returnValue: unknown;
343
- }>;
162
+ declare const decodeTally: (tally: string[]) => Vote;
163
+ declare const encryptVote: (vote: Vote, publicKey: Uint8Array) => Uint8Array;
164
+ declare const generatePublicKey: () => Uint8Array;
165
+ declare const generateVoteProof: (voteProofInputs: VoteProofInputs) => Promise<ProofData>;
166
+ declare const generateMaskVoteProof: (maskVoteProofInputs: MaskVoteProofInputs) => Promise<ProofData>;
344
167
  declare const verifyProof: (proof: ProofData) => Promise<boolean>;
345
168
  /**
346
169
  * Encode the proof data into a format that can be used by the CRISP program in Solidity
@@ -350,12 +173,4 @@ declare const verifyProof: (proof: ProofData) => Promise<boolean>;
350
173
  */
351
174
  declare const encodeSolidityProof: (proof: ProofData) => Hex;
352
175
 
353
- /**
354
- * Given a message and its signed version, extract the signature components
355
- * @param message The original message
356
- * @param signedMessage The signed message (signature)
357
- * @returns The extracted signature components
358
- */
359
- declare const extractSignature: (message: string, signedMessage: `0x${string}`) => Promise<NoirSignatureInputs>;
360
-
361
- export { type CRISPCircuitInputs, CRISP_SERVER_STATE_LITE_ENDPOINT, CRISP_SERVER_TOKEN_TREE_ENDPOINT, HALF_LARGEST_MINIMUM_DEGREE, type IMerkleProof, type IRoundDetails, type IRoundDetailsResponse, type ITokenDetails, type IVote, MAXIMUM_VOTE_VALUE, MERKLE_TREE_MAX_DEPTH, MESSAGE, type NoirSignatureInputs, VotingMode, calculateValidIndicesForPlaintext, decodeTally, encodeSolidityProof, encodeVote, encryptVote, encryptVoteAndGenerateCRISPInputs, extractSignature, generateMaskVote, generateMerkleProof, generateMerkleTree, generateProof, generateProofWithReturnValue, generatePublicKey, getBalanceAt, getCircuitOutputValue, getRoundDetails, getRoundTokenDetails, getTotalSupplyAt, getTreeData, hashLeaf, toBinary, validateVote, verifyProof };
176
+ export { MAXIMUM_VOTE_VALUE, MERKLE_TREE_MAX_DEPTH, type MaskVoteProofInputs, type RoundDetails, type RoundDetailsResponse, SIGNATURE_MESSAGE, type TokenDetails, type Vote, type VoteProofInputs, decodeTally, encodeSolidityProof, encryptVote, generateMaskVoteProof, generateMerkleProof, generateMerkleTree, generatePublicKey, generateVoteProof, getAddressFromSignature, getBalanceAt, getRoundDetails, getRoundTokenDetails, getTotalSupplyAt, getTreeData, hashLeaf, verifyProof };