@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 +154 -11
- package/dist/index.d.ts +93 -6
- package/dist/index.js +136 -29
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -19,23 +19,60 @@ npm install @crisp-e3/sdk
|
|
|
19
19
|
|
|
20
20
|
## Usage
|
|
21
21
|
|
|
22
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
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
|
-
|
|
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:
|
|
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
|
|
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
|
|
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: (
|
|
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
|
-
|
|
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 };
|