@izi-noir/sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +458 -0
- package/dist/IProvingSystem-D9TnEig0.d.ts +140 -0
- package/dist/IProvingSystem-TKNofoo8.d.cts +140 -0
- package/dist/index.cjs +2793 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1196 -0
- package/dist/index.d.ts +1196 -0
- package/dist/index.js +2730 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/arkworks.cjs +824 -0
- package/dist/providers/arkworks.cjs.map +1 -0
- package/dist/providers/arkworks.d.cts +121 -0
- package/dist/providers/arkworks.d.ts +121 -0
- package/dist/providers/arkworks.js +791 -0
- package/dist/providers/arkworks.js.map +1 -0
- package/dist/providers/barretenberg.cjs +822 -0
- package/dist/providers/barretenberg.cjs.map +1 -0
- package/dist/providers/barretenberg.d.cts +18 -0
- package/dist/providers/barretenberg.d.ts +18 -0
- package/dist/providers/barretenberg.js +790 -0
- package/dist/providers/barretenberg.js.map +1 -0
- package/dist/providers/solana.cjs +262 -0
- package/dist/providers/solana.cjs.map +1 -0
- package/dist/providers/solana.d.cts +223 -0
- package/dist/providers/solana.d.ts +223 -0
- package/dist/providers/solana.js +222 -0
- package/dist/providers/solana.js.map +1 -0
- package/dist/providers/sunspot.cjs +475 -0
- package/dist/providers/sunspot.cjs.map +1 -0
- package/dist/providers/sunspot.d.cts +210 -0
- package/dist/providers/sunspot.d.ts +210 -0
- package/dist/providers/sunspot.js +443 -0
- package/dist/providers/sunspot.js.map +1 -0
- package/dist/types-CaaigonG.d.cts +93 -0
- package/dist/types-CaaigonG.d.ts +93 -0
- package/dist/wasm/nodejs/arkworks_groth16_wasm.js +448 -0
- package/dist/wasm/nodejs/arkworks_groth16_wasm_bg.wasm +0 -0
- package/dist/wasm/web/arkworks_groth16_wasm.js +536 -0
- package/dist/wasm/web/arkworks_groth16_wasm_bg.wasm +0 -0
- package/dist/wasmInit-KV6DTj4J.d.ts +282 -0
- package/dist/wasmInit-iEYiiB8M.d.cts +282 -0
- package/package.json +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Franco Perez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# @izi-noir/sdk
|
|
2
|
+
|
|
3
|
+
> Privacy for Solana in one SDK
|
|
4
|
+
|
|
5
|
+
Write ZK circuits in JavaScript, generate proofs in the browser, verify on Solana. No cryptography PhD required.
|
|
6
|
+
|
|
7
|
+
## Why IZI-NOIR?
|
|
8
|
+
|
|
9
|
+
**Traditional ZK workflow (4+ tools, new language):**
|
|
10
|
+
```
|
|
11
|
+
Write .nr file → nargo compile → nargo execute → bb prove → bb write_verifier → Deploy manually
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**IZI-NOIR workflow (one SDK, JavaScript):**
|
|
15
|
+
```
|
|
16
|
+
Write JS function → izi.createProof() → izi.proveForSolana() → builder.deploy() → Done
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| Traditional Noir | IZI-NOIR |
|
|
20
|
+
|-----------------|----------|
|
|
21
|
+
| Learn a new language | Write JavaScript you know |
|
|
22
|
+
| 4+ CLI tools | One SDK |
|
|
23
|
+
| Manual deployment | Automated helpers |
|
|
24
|
+
| Complex setup | `npm install` and go |
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @izi-noir/sdk
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
### 1. Write a Circuit in JavaScript
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { IziNoir, Provider } from '@izi-noir/sdk';
|
|
38
|
+
|
|
39
|
+
const izi = await IziNoir.init({ provider: Provider.Arkworks });
|
|
40
|
+
|
|
41
|
+
// Write your circuit as a JavaScript function
|
|
42
|
+
await izi.compile(`
|
|
43
|
+
fn main(secret: Field, expected: pub Field) {
|
|
44
|
+
assert(secret * secret == expected);
|
|
45
|
+
}
|
|
46
|
+
`);
|
|
47
|
+
|
|
48
|
+
// Or use the transpiler (JS → Noir → compile)
|
|
49
|
+
const result = await createProof(
|
|
50
|
+
[100], // public inputs (what everyone sees)
|
|
51
|
+
[10], // private inputs (your secret)
|
|
52
|
+
([expected], [secret]) => {
|
|
53
|
+
assert(secret * secret == expected); // Prove you know the square root
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
console.log('Verified:', result.verified);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. Generate Solana-Ready Proofs
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const solanaProof = await izi.proveForSolana({
|
|
64
|
+
secret: '10',
|
|
65
|
+
expected: '100'
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// 256-byte proof ready for on-chain verification
|
|
69
|
+
console.log('Proof size:', solanaProof.proof.bytes.length, 'bytes');
|
|
70
|
+
console.log('Estimated rent:', solanaProof.estimatedRent, 'lamports');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3. Deploy and Verify On-Chain
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { SolanaTransactionBuilder } from '@izi-noir/sdk';
|
|
77
|
+
|
|
78
|
+
const builder = new SolanaTransactionBuilder({ computeUnits: 400_000 });
|
|
79
|
+
|
|
80
|
+
// Build transactions for your wallet adapter
|
|
81
|
+
const { initVk, verifyProof, computeBudget } = builder.buildInitAndVerifyInstructions(
|
|
82
|
+
solanaProof,
|
|
83
|
+
vkKeypair.publicKey.toBase58(),
|
|
84
|
+
wallet.publicKey.toBase58(),
|
|
85
|
+
wallet.publicKey.toBase58()
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Send with your preferred wallet adapter
|
|
89
|
+
await sendTransaction([computeBudget, initVk, verifyProof]);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Full Workflow Examples
|
|
93
|
+
|
|
94
|
+
### Age Verification (Prove you're over 18 without revealing your age)
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { IziNoir, Provider, CircuitRegistry, VkDeploymentManager } from '@izi-noir/sdk';
|
|
98
|
+
|
|
99
|
+
// 1. Register your circuit
|
|
100
|
+
const registry = new CircuitRegistry();
|
|
101
|
+
registry.register({
|
|
102
|
+
name: 'age-check',
|
|
103
|
+
version: '1.0.0',
|
|
104
|
+
description: 'Proves age >= minimum without revealing actual age',
|
|
105
|
+
jsCircuit: ([minAge], [birthYear, currentYear]) => {
|
|
106
|
+
assert(currentYear - birthYear >= minAge);
|
|
107
|
+
},
|
|
108
|
+
publicInputs: [{ name: 'minAge', type: 'Field', description: 'Minimum age required' }],
|
|
109
|
+
privateInputs: [
|
|
110
|
+
{ name: 'birthYear', type: 'Field', description: 'Year of birth' },
|
|
111
|
+
{ name: 'currentYear', type: 'Field', description: 'Current year' }
|
|
112
|
+
],
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// 2. Create a proof
|
|
116
|
+
const izi = await IziNoir.init({ provider: Provider.Arkworks });
|
|
117
|
+
const circuit = registry.get('age-check');
|
|
118
|
+
|
|
119
|
+
await izi.compile(`
|
|
120
|
+
fn main(minAge: pub Field, birthYear: Field, currentYear: Field) {
|
|
121
|
+
assert(currentYear - birthYear >= minAge);
|
|
122
|
+
}
|
|
123
|
+
`);
|
|
124
|
+
|
|
125
|
+
const proof = await izi.proveForSolana({
|
|
126
|
+
minAge: '18',
|
|
127
|
+
birthYear: '1990',
|
|
128
|
+
currentYear: '2024'
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// 3. Deploy to Solana
|
|
132
|
+
const deploymentManager = new VkDeploymentManager({
|
|
133
|
+
network: 'devnet',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const deployment = await deploymentManager.ensureDeployed({
|
|
137
|
+
circuitName: 'age-check',
|
|
138
|
+
solanaProofData: proof,
|
|
139
|
+
authority: wallet.publicKey.toBase58(),
|
|
140
|
+
payer: wallet.publicKey.toBase58(),
|
|
141
|
+
sendTransaction: async (instructions, signers) => {
|
|
142
|
+
// Your wallet adapter logic here
|
|
143
|
+
return txSignature;
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
console.log('VK deployed at:', deployment.vkAccount);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Backend API Verification (Off-chain)
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import express from 'express';
|
|
154
|
+
import { OffchainVerifier, createVerifierMiddleware } from '@izi-noir/sdk';
|
|
155
|
+
|
|
156
|
+
const app = express();
|
|
157
|
+
app.use(express.json());
|
|
158
|
+
|
|
159
|
+
// Create verifier with your compiled circuit
|
|
160
|
+
const verifier = new OffchainVerifier({
|
|
161
|
+
verifier: async (circuit, proof, publicInputs) => {
|
|
162
|
+
// Use your proving system's verify method
|
|
163
|
+
return await provingSystem.verify(circuit, proof, publicInputs);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Register circuits
|
|
168
|
+
await verifier.registerCircuit('api-auth', {
|
|
169
|
+
jsCircuit: ([apiKeyHash], [apiKey]) => {
|
|
170
|
+
// In real use, you'd hash the apiKey and compare
|
|
171
|
+
assert(apiKey == apiKeyHash);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Add verification endpoint
|
|
176
|
+
app.post('/verify', createVerifierMiddleware(verifier));
|
|
177
|
+
|
|
178
|
+
// Client sends: { circuitName: 'api-auth', proof: '0x...', publicInputs: [12345] }
|
|
179
|
+
// Server responds: { verified: true, verificationTimeMs: 42 }
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Proving Backends
|
|
183
|
+
|
|
184
|
+
| Provider | Proof Size | Environment | Best For |
|
|
185
|
+
|----------|------------|-------------|----------|
|
|
186
|
+
| **Arkworks** | ~256 bytes | Browser + Node.js | Solana on-chain verification |
|
|
187
|
+
| **Barretenberg** | ~16 KB | Browser + Node.js | Development, fast iteration |
|
|
188
|
+
| **Sunspot** | ~324 bytes | Node.js only | Pre-compiled production circuits |
|
|
189
|
+
|
|
190
|
+
### Arkworks (Recommended for Solana)
|
|
191
|
+
|
|
192
|
+
Groth16 proofs that fit in a single Solana transaction.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const izi = await IziNoir.init({ provider: Provider.Arkworks });
|
|
196
|
+
const solanaProof = await izi.proveForSolana(inputs);
|
|
197
|
+
// solanaProof.proof.bytes.length === 256
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Barretenberg (Development)
|
|
201
|
+
|
|
202
|
+
Faster proving, larger proofs. Great for testing.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
const izi = await IziNoir.init({ provider: Provider.Barretenberg });
|
|
206
|
+
const { proof, verified } = await izi.createProof(noirCode, inputs);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## New APIs
|
|
210
|
+
|
|
211
|
+
### SolanaTransactionBuilder
|
|
212
|
+
|
|
213
|
+
Build Solana transactions without Anchor dependency.
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { SolanaTransactionBuilder } from '@izi-noir/sdk';
|
|
217
|
+
|
|
218
|
+
const builder = new SolanaTransactionBuilder({
|
|
219
|
+
programId: 'EYhRED7EuMyyVjx57aDXUD9h6ArnEKng64qtz8999KrS', // optional
|
|
220
|
+
computeUnits: 400_000,
|
|
221
|
+
priorityFee: 1000, // microLamports per CU
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Build individual instructions
|
|
225
|
+
const initInstruction = builder.buildInitVkInstruction(solanaProof, {
|
|
226
|
+
vkAccount: vkPubkey,
|
|
227
|
+
authority: authorityPubkey,
|
|
228
|
+
payer: payerPubkey,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const verifyInstruction = builder.buildVerifyProofInstruction(
|
|
232
|
+
solanaProof.proof.bytes,
|
|
233
|
+
solanaProof.publicInputs.bytes,
|
|
234
|
+
{ vkAccount: vkPubkey }
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
// Or build everything at once
|
|
238
|
+
const { initVk, verifyProof, computeBudget, rentLamports } =
|
|
239
|
+
builder.buildInitAndVerifyInstructions(
|
|
240
|
+
solanaProof,
|
|
241
|
+
vkPubkey,
|
|
242
|
+
authorityPubkey,
|
|
243
|
+
payerPubkey
|
|
244
|
+
);
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### VkDeploymentManager
|
|
248
|
+
|
|
249
|
+
Idempotent deployment with local persistence.
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { VkDeploymentManager } from '@izi-noir/sdk';
|
|
253
|
+
|
|
254
|
+
const manager = new VkDeploymentManager({
|
|
255
|
+
network: 'devnet',
|
|
256
|
+
configDir: './.izi-noir', // stores deployment state
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Won't redeploy if same circuit already deployed
|
|
260
|
+
const result = await manager.ensureDeployed({
|
|
261
|
+
circuitName: 'my-circuit',
|
|
262
|
+
solanaProofData,
|
|
263
|
+
authority: wallet.publicKey.toBase58(),
|
|
264
|
+
payer: wallet.publicKey.toBase58(),
|
|
265
|
+
sendTransaction: myWalletSendFn,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (result.deployed) {
|
|
269
|
+
console.log('Deployed new VK:', result.vkAccount);
|
|
270
|
+
} else {
|
|
271
|
+
console.log('Using existing VK:', result.vkAccount);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Save state for next time
|
|
275
|
+
await manager.save();
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### CircuitRegistry
|
|
279
|
+
|
|
280
|
+
Name, version, and document your circuits.
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
import { CircuitRegistry, defineCircuit } from '@izi-noir/sdk';
|
|
284
|
+
|
|
285
|
+
const registry = new CircuitRegistry();
|
|
286
|
+
|
|
287
|
+
// Full registration
|
|
288
|
+
registry.register({
|
|
289
|
+
name: 'balance-proof',
|
|
290
|
+
version: '1.0.0',
|
|
291
|
+
description: 'Proves balance >= threshold',
|
|
292
|
+
jsCircuit: ([threshold], [balance]) => { assert(balance >= threshold); },
|
|
293
|
+
publicInputs: [{ name: 'threshold', type: 'Field' }],
|
|
294
|
+
privateInputs: [{ name: 'balance', type: 'Field' }],
|
|
295
|
+
tags: ['finance', 'defi'],
|
|
296
|
+
author: 'Your Name',
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// Quick registration with defineCircuit
|
|
300
|
+
const circuit = defineCircuit(
|
|
301
|
+
{ name: 'quick-check', version: '1.0.0', publicInputs: [], privateInputs: [] },
|
|
302
|
+
([], [secret]) => { assert(secret != 0); }
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
// Lookup
|
|
306
|
+
const myCircuit = registry.get('balance-proof');
|
|
307
|
+
const allVersions = registry.getVersions('balance-proof');
|
|
308
|
+
const financeCircuits = registry.findByTag('finance');
|
|
309
|
+
|
|
310
|
+
// Generate docs
|
|
311
|
+
console.log(registry.generateDocs('balance-proof'));
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### OffchainVerifier
|
|
315
|
+
|
|
316
|
+
Verify proofs without blockchain transactions.
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import { OffchainVerifier, batchVerify } from '@izi-noir/sdk';
|
|
320
|
+
|
|
321
|
+
const verifier = new OffchainVerifier({
|
|
322
|
+
compiler: async (jsCircuit) => { /* compile circuit */ },
|
|
323
|
+
verifier: async (circuit, proof, publicInputs) => { /* verify */ return true; },
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// Single verification
|
|
327
|
+
const result = await verifier.verify({
|
|
328
|
+
circuitName: 'my-circuit',
|
|
329
|
+
proof: proofBytes,
|
|
330
|
+
publicInputs: [123, 456],
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Batch verification
|
|
334
|
+
const batchResult = await batchVerify(verifier, [
|
|
335
|
+
{ circuitName: 'circuit-a', proof: proof1, publicInputs: [1] },
|
|
336
|
+
{ circuitName: 'circuit-b', proof: proof2, publicInputs: [2] },
|
|
337
|
+
]);
|
|
338
|
+
|
|
339
|
+
console.log(`Verified: ${batchResult.verifiedCount}/${batchResult.results.length}`);
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Writing Circuit Functions
|
|
343
|
+
|
|
344
|
+
### Function Signature
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
([public1, public2, ...], [private1, private2, ...]) => {
|
|
348
|
+
// assertions here
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
- **Public inputs**: Values everyone can see (e.g., minimum age requirement)
|
|
353
|
+
- **Private inputs**: Your secret values (e.g., actual birth year)
|
|
354
|
+
|
|
355
|
+
### Supported Operations
|
|
356
|
+
|
|
357
|
+
| JavaScript | Noir | Notes |
|
|
358
|
+
|------------|------|-------|
|
|
359
|
+
| `assert(cond)` | `assert(cond)` | Core constraint |
|
|
360
|
+
| `==` / `===` | `==` | Equality |
|
|
361
|
+
| `+`, `-`, `*`, `/`, `%` | Same | Arithmetic |
|
|
362
|
+
| `<`, `>`, `<=`, `>=` | Same | Comparison |
|
|
363
|
+
| `let x = 5` | `let x: Field = 5` | Immutable |
|
|
364
|
+
| `let mut_x = 5` | `let mut x: Field = 5` | Mutable (use `mut_` prefix) |
|
|
365
|
+
| `if/else` | Same | Conditionals |
|
|
366
|
+
| `for (let i=0; i<n; i++)` | Same | Fixed-bound loops |
|
|
367
|
+
| `[a, b, c]` | `[Field; 3]` | Fixed-size arrays |
|
|
368
|
+
|
|
369
|
+
### Examples
|
|
370
|
+
|
|
371
|
+
**Simple equality:**
|
|
372
|
+
```typescript
|
|
373
|
+
([expected], [secret]) => { assert(secret == expected); }
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Range proof:**
|
|
377
|
+
```typescript
|
|
378
|
+
([min, max], [value]) => {
|
|
379
|
+
assert(value >= min);
|
|
380
|
+
assert(value <= max);
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Sum verification:**
|
|
385
|
+
```typescript
|
|
386
|
+
([sum], [a, b, c]) => {
|
|
387
|
+
let arr = [a, b, c];
|
|
388
|
+
let mut_total = 0;
|
|
389
|
+
for (let i = 0; i < 3; i++) {
|
|
390
|
+
mut_total = mut_total + arr[i];
|
|
391
|
+
}
|
|
392
|
+
assert(mut_total == sum);
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Browser Usage (Vite)
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import initNoirC from "@noir-lang/noirc_abi";
|
|
400
|
+
import initACVM from "@noir-lang/acvm_js";
|
|
401
|
+
import acvm from "@noir-lang/acvm_js/web/acvm_js_bg.wasm?url";
|
|
402
|
+
import noirc from "@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm?url";
|
|
403
|
+
import { IziNoir, Provider, markWasmInitialized } from "@izi-noir/sdk";
|
|
404
|
+
|
|
405
|
+
// Initialize WASM first
|
|
406
|
+
await Promise.all([initACVM(fetch(acvm)), initNoirC(fetch(noirc))]);
|
|
407
|
+
markWasmInitialized();
|
|
408
|
+
|
|
409
|
+
// Now use IziNoir
|
|
410
|
+
const izi = await IziNoir.init({ provider: Provider.Arkworks });
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Type Reference
|
|
414
|
+
|
|
415
|
+
### SolanaProofData
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
interface SolanaProofData {
|
|
419
|
+
verifyingKey: {
|
|
420
|
+
base64: string;
|
|
421
|
+
bytes: Uint8Array;
|
|
422
|
+
nrPublicInputs: number;
|
|
423
|
+
};
|
|
424
|
+
proof: {
|
|
425
|
+
base64: string;
|
|
426
|
+
bytes: Uint8Array; // Always 256 bytes
|
|
427
|
+
};
|
|
428
|
+
publicInputs: {
|
|
429
|
+
hex: string[];
|
|
430
|
+
bytes: Uint8Array[]; // 32-byte big-endian field elements
|
|
431
|
+
};
|
|
432
|
+
accountSize: number;
|
|
433
|
+
estimatedRent: number; // Lamports for VK account
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### InstructionData
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
interface InstructionData {
|
|
441
|
+
data: Uint8Array;
|
|
442
|
+
programId: string;
|
|
443
|
+
keys: Array<{
|
|
444
|
+
pubkey: string;
|
|
445
|
+
isSigner: boolean;
|
|
446
|
+
isWritable: boolean;
|
|
447
|
+
}>;
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## Requirements
|
|
452
|
+
|
|
453
|
+
- Node.js 22.12.0+
|
|
454
|
+
- For Solana deployment: Solana CLI + Anchor CLI
|
|
455
|
+
|
|
456
|
+
## License
|
|
457
|
+
|
|
458
|
+
MIT
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { CompiledCircuit, InputMap } from '@noir-lang/types';
|
|
2
|
+
import { P as ProofData } from './types-CaaigonG.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Chain types for multi-chain proof formatting
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Supported blockchain targets for proof verification
|
|
9
|
+
*/
|
|
10
|
+
type ChainId = 'solana' | 'ethereum';
|
|
11
|
+
/**
|
|
12
|
+
* Chain enum for IziNoir initialization.
|
|
13
|
+
* Use undefined (don't pass chain) for offchain mode.
|
|
14
|
+
*/
|
|
15
|
+
declare enum Chain {
|
|
16
|
+
/** Solana blockchain - uses Groth16 proofs with gnark format VK */
|
|
17
|
+
Solana = "solana",
|
|
18
|
+
/** Ethereum blockchain - uses Groth16 proofs (future support) */
|
|
19
|
+
Ethereum = "ethereum"
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Metadata about the compiled circuit
|
|
23
|
+
*/
|
|
24
|
+
interface CircuitMetadata {
|
|
25
|
+
/** Number of public inputs in the circuit */
|
|
26
|
+
numPublicInputs: number;
|
|
27
|
+
/** Optional circuit name for identification */
|
|
28
|
+
circuitName?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Base interface for chain-specific metadata
|
|
32
|
+
*/
|
|
33
|
+
interface ChainMetadata {
|
|
34
|
+
chainId: ChainId;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Solana-specific metadata for VK account sizing and rent
|
|
38
|
+
*/
|
|
39
|
+
interface SolanaChainMetadata extends ChainMetadata {
|
|
40
|
+
chainId: 'solana';
|
|
41
|
+
/** Size of the VK account in bytes */
|
|
42
|
+
accountSize: number;
|
|
43
|
+
/** Estimated rent-exempt balance in lamports */
|
|
44
|
+
estimatedRent: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Ethereum-specific metadata (future)
|
|
48
|
+
*/
|
|
49
|
+
interface EthereumChainMetadata extends ChainMetadata {
|
|
50
|
+
chainId: 'ethereum';
|
|
51
|
+
/** Estimated gas for verification */
|
|
52
|
+
estimatedGas: bigint;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Type helper to get chain-specific metadata
|
|
56
|
+
*/
|
|
57
|
+
type ChainMetadataFor<T extends ChainId> = T extends 'solana' ? SolanaChainMetadata : T extends 'ethereum' ? EthereumChainMetadata : ChainMetadata;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Available proving system providers
|
|
61
|
+
*/
|
|
62
|
+
declare enum Provider {
|
|
63
|
+
/** Barretenberg backend - browser compatible, UltraHonk proofs (~16KB) */
|
|
64
|
+
Barretenberg = "barretenberg",
|
|
65
|
+
/** Arkworks WASM backend - browser compatible, Groth16 proofs (~256 bytes) */
|
|
66
|
+
Arkworks = "arkworks",
|
|
67
|
+
/** Sunspot CLI backend - Node.js only, Groth16 proofs (~256 bytes) */
|
|
68
|
+
Sunspot = "sunspot"
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Configuration for circuit paths (required for Sunspot)
|
|
72
|
+
*/
|
|
73
|
+
interface CircuitPaths {
|
|
74
|
+
/** Path to the proving key file */
|
|
75
|
+
pkPath: string;
|
|
76
|
+
/** Path to the verification key file */
|
|
77
|
+
vkPath: string;
|
|
78
|
+
/** Path to the compiled circuit JSON file */
|
|
79
|
+
circuitPath: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Configuration for IziNoir initialization
|
|
83
|
+
*/
|
|
84
|
+
interface IziNoirConfig {
|
|
85
|
+
/** The proving system provider to use */
|
|
86
|
+
provider: Provider;
|
|
87
|
+
/**
|
|
88
|
+
* Target blockchain for proof formatting.
|
|
89
|
+
* If omitted, operates in offchain mode (raw proofs, no chain formatting).
|
|
90
|
+
*/
|
|
91
|
+
chain?: Chain;
|
|
92
|
+
/** Circuit paths - required for Sunspot provider */
|
|
93
|
+
circuitPaths?: CircuitPaths;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface ICompiler {
|
|
97
|
+
compile(noirCode: string): Promise<CompiledCircuit>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Interface for generating zero-knowledge proofs
|
|
102
|
+
*/
|
|
103
|
+
interface IProver {
|
|
104
|
+
/**
|
|
105
|
+
* Generate a proof for the given circuit and inputs
|
|
106
|
+
*
|
|
107
|
+
* @param circuit - The compiled circuit to prove
|
|
108
|
+
* @param inputs - The inputs (both public and private) for the circuit
|
|
109
|
+
* @returns The proof data including proof bytes and public inputs
|
|
110
|
+
*/
|
|
111
|
+
generateProof(circuit: CompiledCircuit, inputs: InputMap): Promise<ProofData>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Interface for verifying zero-knowledge proofs
|
|
116
|
+
*/
|
|
117
|
+
interface IVerifier {
|
|
118
|
+
/**
|
|
119
|
+
* Verify a proof against a compiled circuit
|
|
120
|
+
*
|
|
121
|
+
* @param circuit - The compiled circuit used to generate the proof
|
|
122
|
+
* @param proof - The proof bytes to verify
|
|
123
|
+
* @param publicInputs - The public inputs that were used
|
|
124
|
+
* @returns true if the proof is valid, false otherwise
|
|
125
|
+
*/
|
|
126
|
+
verifyProof(circuit: CompiledCircuit, proof: Uint8Array, publicInputs: string[]): Promise<boolean>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Unified interface for a complete proving system.
|
|
131
|
+
* Combines compilation, proof generation, and verification into a single abstraction.
|
|
132
|
+
*
|
|
133
|
+
* Implementations:
|
|
134
|
+
* - Barretenberg: WASM-based (browser compatible), UltraHonk proofs
|
|
135
|
+
* - Sunspot: CLI-based (Node.js only), Groth16 proofs for Solana
|
|
136
|
+
*/
|
|
137
|
+
interface IProvingSystem extends ICompiler, IProver, IVerifier {
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { type ChainId as C, type EthereumChainMetadata as E, type IziNoirConfig as I, Provider as P, type SolanaChainMetadata as S, type CircuitMetadata as a, type ChainMetadataFor as b, Chain as c, type IProvingSystem as d, type CircuitPaths as e, type ChainMetadata as f, type ICompiler as g, type IProver as h, type IVerifier as i };
|