@crisp-e3/sdk 0.5.2 → 0.5.4

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
@@ -19,23 +19,60 @@ npm install @crisp-e3/sdk
19
19
 
20
20
  ## Usage
21
21
 
22
- ### Get Round Details
22
+ ### CrispSDK Class (Recommended)
23
+
24
+ The `CrispSDK` class provides a convenient interface that automatically handles server communication
25
+ for fetching previous ciphertexts and checking slot status.
26
+
27
+ ```typescript
28
+ import { CrispSDK } from '@crisp-e3/sdk'
29
+
30
+ const sdk = new CrispSDK(serverUrl)
31
+
32
+ // Generate a vote proof (automatically fetches previous ciphertext if needed)
33
+ const voteProof = await sdk.generateVoteProof({
34
+ e3Id: 1,
35
+ vote: { yes: 100n, no: 0n },
36
+ publicKey: publicKeyBytes,
37
+ signature: '0x...',
38
+ messageHash: '0x...',
39
+ balance: 1000n,
40
+ slotAddress: '0x...',
41
+ merkleLeaves: [...],
42
+ })
43
+
44
+ // Generate a mask vote proof (automatically fetches previous ciphertext if needed)
45
+ const maskProof = await sdk.generateMaskVoteProof({
46
+ e3Id: 1,
47
+ balance: 1000n,
48
+ slotAddress: '0x...',
49
+ publicKey: publicKeyBytes,
50
+ merkleLeaves: [...],
51
+ })
52
+ ```
53
+
54
+ ### Standalone Functions
55
+
56
+ #### Get Round Details
23
57
 
24
58
  ```typescript
25
- import { getRoundDetails } from '@crisp-e3/sdk'
59
+ import { getRoundDetails, getRoundTokenDetails } from '@crisp-e3/sdk'
26
60
 
27
61
  const roundDetails = await getRoundDetails(serverUrl, e3Id)
62
+ const tokenDetails = await getRoundTokenDetails(serverUrl, e3Id)
28
63
  ```
29
64
 
30
- ### Get Token Balance
65
+ #### Get Token Balance and Supply
31
66
 
32
67
  ```typescript
33
- import { getBalanceAt } from '@crisp-e3/sdk'
68
+ import { getBalanceAt, getTotalSupplyAt, getTreeData } from '@crisp-e3/sdk'
34
69
 
35
70
  const balance = await getBalanceAt(voterAddress, tokenAddress, snapshotBlock, chainId)
71
+ const totalSupply = await getTotalSupplyAt(tokenAddress, snapshotBlock, chainId)
72
+ const merkleLeaves = await getTreeData(serverUrl, e3Id)
36
73
  ```
37
74
 
38
- ### Generate Vote Proof
75
+ #### Generate Vote Proof (Low-level)
39
76
 
40
77
  ```typescript
41
78
  import { generateVoteProof } from '@crisp-e3/sdk'
@@ -44,12 +81,15 @@ const proof = await generateVoteProof({
44
81
  vote: { yes: 100n, no: 0n },
45
82
  publicKey: publicKeyBytes,
46
83
  signature: '0x...',
84
+ messageHash: '0x...',
47
85
  balance: 1000n,
86
+ slotAddress: '0x...',
48
87
  merkleLeaves: [...],
88
+ previousCiphertext: previousCiphertextBytes, // optional
49
89
  })
50
90
  ```
51
91
 
52
- ### Generate Mask Vote Proof
92
+ #### Generate Mask Vote Proof (Low-level)
53
93
 
54
94
  ```typescript
55
95
  import { generateMaskVoteProof } from '@crisp-e3/sdk'
@@ -63,7 +103,7 @@ const maskProof = await generateMaskVoteProof({
63
103
  })
64
104
  ```
65
105
 
66
- ### Verify Proof
106
+ #### Verify Proof
67
107
 
68
108
  ```typescript
69
109
  import { verifyProof } from '@crisp-e3/sdk'
@@ -71,9 +111,112 @@ import { verifyProof } from '@crisp-e3/sdk'
71
111
  const isValid = await verifyProof(proof)
72
112
  ```
73
113
 
114
+ #### Decode Tally
115
+
116
+ ```typescript
117
+ import { decodeTally } from '@crisp-e3/sdk'
118
+
119
+ const tally = decodeTally(tallyBytes)
120
+ // Returns: { yes: bigint, no: bigint }
121
+ ```
122
+
123
+ #### Cryptographic Utilities
124
+
125
+ ```typescript
126
+ import { generatePublicKey, encryptVote, encodeSolidityProof } from '@crisp-e3/sdk'
127
+
128
+ const publicKey = generatePublicKey()
129
+ const encryptedVote = encryptVote(vote, publicKey)
130
+ const encodedProof = encodeSolidityProof(proof)
131
+ ```
132
+
133
+ #### Merkle Tree Utilities
134
+
135
+ ```typescript
136
+ import {
137
+ generateMerkleProof,
138
+ generateMerkleTree,
139
+ hashLeaf,
140
+ getAddressFromSignature,
141
+ } from '@crisp-e3/sdk'
142
+
143
+ const leaf = hashLeaf(address, balance)
144
+ const tree = generateMerkleTree(leaves)
145
+ const proof = generateMerkleProof(balance, address, merkleLeaves)
146
+ const address = await getAddressFromSignature(signature, messageHash)
147
+ ```
148
+
149
+ #### State Utilities
150
+
151
+ ```typescript
152
+ import { getPreviousCiphertext, getIsSlotEmpty } from '@crisp-e3/sdk'
153
+
154
+ const previousCiphertext = await getPreviousCiphertext(serverUrl, e3Id, slotAddress)
155
+ const isEmpty = await getIsSlotEmpty(serverUrl, e3Id, slotAddress)
156
+ ```
157
+
74
158
  ## API
75
159
 
76
- - **State**: `getRoundDetails`, `getRoundTokenDetails`
77
- - **Token**: `getBalanceAt`, `getTotalSupplyAt`, `getTreeData`
78
- - **Vote**: `generateVoteProof`, `generateMaskVoteProof`, `verifyProof`, `decodeTally`
79
- - **Utils**: `generateMerkleProof`, `generateMerkleTree`, `hashLeaf`, `getAddressFromSignature`
160
+ ### CrispSDK Class
161
+
162
+ - `constructor(serverUrl: string)` - Create a new SDK instance
163
+ - `generateVoteProof(voteProofRequest: VoteProofRequest): Promise<ProofData>` - Generate a vote
164
+ proof (automatically handles previous ciphertext)
165
+ - `generateMaskVoteProof(maskVoteProofRequest: MaskVoteProofRequest): Promise<ProofData>` - Generate
166
+ a mask vote proof (automatically handles previous ciphertext)
167
+
168
+ ### State Functions
169
+
170
+ - `getRoundDetails(serverUrl: string, e3Id: number): Promise<RoundDetails>` - Get round details
171
+ - `getRoundTokenDetails(serverUrl: string, e3Id: number): Promise<TokenDetails>` - Get token details
172
+ for a round
173
+ - `getPreviousCiphertext(serverUrl: string, e3Id: number, address: string): Promise<Uint8Array>` -
174
+ Get previous ciphertext for a slot
175
+ - `getIsSlotEmpty(serverUrl: string, e3Id: number, address: string): Promise<boolean>` - Check if a
176
+ slot is empty
177
+
178
+ ### Token Functions
179
+
180
+ - `getBalanceAt(voterAddress: string, tokenAddress: string, snapshotBlock: number, chainId: number): Promise<bigint>` -
181
+ Get token balance at a specific block
182
+ - `getTotalSupplyAt(tokenAddress: string, snapshotBlock: number, chainId: number): Promise<bigint>` -
183
+ Get total supply at a specific block
184
+ - `getTreeData(serverUrl: string, e3Id: number): Promise<bigint[]>` - Get merkle tree leaves from
185
+ server
186
+
187
+ ### Vote Functions
188
+
189
+ - `generateVoteProof(voteProofInputs: VoteProofInputs): Promise<ProofData>` - Generate a vote proof
190
+ (low-level)
191
+ - `generateMaskVoteProof(maskVoteProofInputs: MaskVoteProofInputs): Promise<ProofData>` - Generate a
192
+ mask vote proof (low-level)
193
+ - `verifyProof(proof: ProofData): Promise<boolean>` - Verify a proof locally
194
+ - `decodeTally(tallyBytes: string): Vote` - Decode an encoded tally
195
+ - `generatePublicKey(): Uint8Array` - Generate a random public key
196
+ - `encryptVote(vote: Vote, publicKey: Uint8Array): Uint8Array` - Encrypt a vote
197
+ - `encodeSolidityProof(proof: ProofData): Hex` - Encode proof for Solidity contract
198
+
199
+ ### Utility Functions
200
+
201
+ - `generateMerkleProof(balance: bigint, address: string, leaves: bigint[] | string[]): MerkleProof` -
202
+ Generate merkle proof
203
+ - `generateMerkleTree(leaves: bigint[]): LeanIMT` - Generate merkle tree
204
+ - `hashLeaf(address: string, balance: bigint): bigint` - Hash a leaf node
205
+ - `getAddressFromSignature(signature: \`0x${string}\`, messageHash?: \`0x${string}\`):
206
+ Promise<string>` - Extract address from signature
207
+
208
+ ### Constants
209
+
210
+ - `MERKLE_TREE_MAX_DEPTH` - Maximum depth of the merkle tree
211
+ - `SIGNATURE_MESSAGE` - Message used for signature verification
212
+ - `MAXIMUM_VOTE_VALUE` - Maximum allowed vote value
213
+ - `SIGNATURE_MESSAGE_HASH` - Hash of the signature message
214
+
215
+ ### Types
216
+
217
+ - `RoundDetails` - Round details type
218
+ - `RoundDetailsResponse` - Server response type for round details
219
+ - `TokenDetails` - Token details type
220
+ - `Vote` - Vote type with `yes` and `no` bigint fields
221
+ - `MaskVoteProofInputs` - Inputs for mask vote proof generation
222
+ - `VoteProofInputs` - Inputs for vote proof generation
package/dist/index.d.ts CHANGED
@@ -94,11 +94,18 @@ type Vote = {
94
94
  no: bigint;
95
95
  };
96
96
  type MaskVoteProofInputs = {
97
- previousCiphertext?: Uint8Array;
97
+ publicKey: Uint8Array;
98
+ balance: bigint;
99
+ slotAddress: string;
98
100
  merkleLeaves: string[] | bigint[];
101
+ previousCiphertext?: Uint8Array;
102
+ };
103
+ type MaskVoteProofRequest = {
104
+ e3Id: number;
99
105
  publicKey: Uint8Array;
100
106
  balance: bigint;
101
107
  slotAddress: string;
108
+ merkleLeaves: string[] | bigint[];
102
109
  };
103
110
  type VoteProofInputs = {
104
111
  merkleLeaves: string[] | bigint[];
@@ -106,8 +113,19 @@ type VoteProofInputs = {
106
113
  balance: bigint;
107
114
  vote: Vote;
108
115
  signature: `0x${string}`;
116
+ messageHash: `0x${string}`;
117
+ slotAddress: string;
109
118
  previousCiphertext?: Uint8Array;
119
+ };
120
+ type VoteProofRequest = {
121
+ e3Id: number;
122
+ merkleLeaves: string[] | bigint[];
123
+ publicKey: Uint8Array;
124
+ balance: bigint;
125
+ vote: Vote;
126
+ signature: `0x${string}`;
110
127
  messageHash: `0x${string}`;
128
+ slotAddress: string;
111
129
  };
112
130
 
113
131
  /**
@@ -121,13 +139,29 @@ declare const getRoundDetails: (serverUrl: string, e3Id: number) => Promise<Roun
121
139
  * @returns The token address, balance threshold and snapshot block
122
140
  */
123
141
  declare const getRoundTokenDetails: (serverUrl: string, e3Id: number) => Promise<TokenDetails>;
142
+ /**
143
+ * Get the previous ciphertext for a slot from the CRISP server
144
+ * @param serverUrl - The base URL of the CRISP server
145
+ * @param e3Id - The e3Id of the round
146
+ * @param address - The address of the slot
147
+ * @returns The previous ciphertext for the slot
148
+ */
149
+ declare const getPreviousCiphertext: (serverUrl: string, e3Id: number, address: string) => Promise<Uint8Array>;
150
+ /**
151
+ * Check if a slot is empty for a given E3 ID and slot address
152
+ * @param serverUrl - The base URL of the CRISP server
153
+ * @param e3Id - The e3Id of the round
154
+ * @param address - The address of the slot
155
+ * @returns Whether the slot is empty or not
156
+ */
157
+ declare const getIsSlotEmpty: (serverUrl: string, e3Id: number, address: string) => Promise<boolean>;
124
158
 
125
159
  declare const MERKLE_TREE_MAX_DEPTH = 20;
126
160
  /**
127
161
  * This is the maximum value for a vote (Yes or No). This is 2^50 - 1
128
162
  * The minimum degree that BFV should use is 100 (to accommodate both Yes and No votes)
129
163
  */
130
- declare const MAXIMUM_VOTE_VALUE: bigint;
164
+ declare const MAXIMUM_VOTE_VALUE: number;
131
165
  /**
132
166
  * Message used by users to prove ownership of their Ethereum account
133
167
  * This message is signed by the user's private key to authenticate their identity
@@ -156,18 +190,43 @@ declare const generateMerkleTree: (leaves: bigint[]) => LeanIMT;
156
190
  * @param leaves The leaves of the Merkle tree
157
191
  */
158
192
  declare const generateMerkleProof: (balance: bigint, address: string, leaves: bigint[] | string[]) => MerkleProof;
159
- declare const getAddressFromSignature: (signature: `0x${string}`, messageHash: `0x${string}`) => Promise<string>;
193
+ declare const getAddressFromSignature: (signature: `0x${string}`, messageHash?: `0x${string}`) => Promise<string>;
160
194
 
161
195
  /**
162
196
  * Decode an encoded tally into its decimal representation.
163
- * @param tally The encoded tally to decode.
197
+ * @param tallyBytes The encoded tally as a hex string (bytes).
164
198
  * @returns The decoded tally as an IVote.
165
199
  */
166
- declare const decodeTally: (tally: string[]) => Vote;
200
+ declare const decodeTally: (tallyBytes: string) => Vote;
201
+ /**
202
+ * Encrypt the vote using the public key.
203
+ * @param vote - The vote to encrypt.
204
+ * @param publicKey - The public key to use for encryption.
205
+ * @returns The encrypted vote as a Uint8Array.
206
+ */
167
207
  declare const encryptVote: (vote: Vote, publicKey: Uint8Array) => Uint8Array;
208
+ /**
209
+ * Generate a random public key.
210
+ * @returns The generated public key as a Uint8Array.
211
+ */
168
212
  declare const generatePublicKey: () => Uint8Array;
213
+ /**
214
+ * Generate a vote proof for the CRISP circuit given the vote proof inputs.
215
+ * @param voteProofInputs - The vote proof inputs.
216
+ * @returns The vote proof.
217
+ */
169
218
  declare const generateVoteProof: (voteProofInputs: VoteProofInputs) => Promise<ProofData>;
219
+ /**
220
+ * Generate a proof for a vote masking operation.
221
+ * @param maskVoteProofInputs The mask vote proof inputs.
222
+ * @returns
223
+ */
170
224
  declare const generateMaskVoteProof: (maskVoteProofInputs: MaskVoteProofInputs) => Promise<ProofData>;
225
+ /**
226
+ * Locally verify a Noir proof.
227
+ * @param proof - The proof to verify.
228
+ * @returns True if the proof is valid, false otherwise.
229
+ */
171
230
  declare const verifyProof: (proof: ProofData) => Promise<boolean>;
172
231
  /**
173
232
  * Encode the proof data into a format that can be used by the CRISP program in Solidity
@@ -177,4 +236,32 @@ declare const verifyProof: (proof: ProofData) => Promise<boolean>;
177
236
  */
178
237
  declare const encodeSolidityProof: (proof: ProofData) => Hex;
179
238
 
180
- export { MAXIMUM_VOTE_VALUE, MERKLE_TREE_MAX_DEPTH, type MaskVoteProofInputs, type RoundDetails, type RoundDetailsResponse, SIGNATURE_MESSAGE, SIGNATURE_MESSAGE_HASH, type TokenDetails, type Vote, type VoteProofInputs, decodeTally, encodeSolidityProof, encryptVote, generateMaskVoteProof, generateMerkleProof, generateMerkleTree, generatePublicKey, generateVoteProof, getAddressFromSignature, getBalanceAt, getRoundDetails, getRoundTokenDetails, getTotalSupplyAt, getTreeData, hashLeaf, verifyProof };
239
+ /**
240
+ * A class representing the CRISP SDK.
241
+ */
242
+ declare class CrispSDK {
243
+ /**
244
+ * The server URL for the CRISP SDK.
245
+ * It's used by methods that communicate directly with the CRISP server.
246
+ */
247
+ private serverUrl;
248
+ /**
249
+ * Create a new instance.
250
+ * @param serverUrl
251
+ */
252
+ constructor(serverUrl: string);
253
+ /**
254
+ * Generate a proof for a vote masking.
255
+ * @param maskProofInputs - The inputs required to generate the mask vote proof.
256
+ * @returns A promise that resolves to the generated proof data.
257
+ */
258
+ generateMaskVoteProof(maskProofInputs: MaskVoteProofRequest): Promise<ProofData>;
259
+ /**
260
+ * Generate a proof for a vote.
261
+ * @param voteProofInputs - The inputs required to generate the vote proof.
262
+ * @returns A promise that resolves to the generated proof data.
263
+ */
264
+ generateVoteProof(voteProofInputs: VoteProofRequest): Promise<ProofData>;
265
+ }
266
+
267
+ export { CrispSDK, MAXIMUM_VOTE_VALUE, MERKLE_TREE_MAX_DEPTH, type MaskVoteProofInputs, type RoundDetails, type RoundDetailsResponse, SIGNATURE_MESSAGE, SIGNATURE_MESSAGE_HASH, type TokenDetails, type Vote, type VoteProofInputs, decodeTally, encodeSolidityProof, encryptVote, generateMaskVoteProof, generateMerkleProof, generateMerkleTree, generatePublicKey, generateVoteProof, getAddressFromSignature, getBalanceAt, getIsSlotEmpty, getPreviousCiphertext, getRoundDetails, getRoundTokenDetails, getTotalSupplyAt, getTreeData, hashLeaf, verifyProof };