@sip-protocol/sdk 0.2.8 → 0.2.10
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 +349 -0
- package/dist/browser.d.mts +100 -2
- package/dist/browser.d.ts +100 -2
- package/dist/browser.js +1362 -268
- package/dist/browser.mjs +502 -16
- package/dist/{chunk-UPTISVCY.mjs → chunk-AV37IZST.mjs} +731 -15
- package/dist/{chunk-VITVG25F.mjs → chunk-XLEPIR2P.mjs} +2 -100
- package/dist/index-BFOKTz2z.d.ts +6062 -0
- package/dist/index-CAhjA4kh.d.mts +6062 -0
- package/dist/index.d.mts +2 -5609
- package/dist/index.d.ts +2 -5609
- package/dist/index.js +588 -154
- package/dist/index.mjs +5 -1
- package/dist/{noir-BHQtFvRk.d.mts → noir-BTyLXLlZ.d.mts} +1 -1
- package/dist/{noir-BHQtFvRk.d.ts → noir-BTyLXLlZ.d.ts} +1 -1
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +11 -112
- package/dist/proofs/noir.mjs +10 -13
- package/package.json +16 -16
- package/src/browser.ts +23 -0
- package/src/index.ts +12 -0
- package/src/proofs/browser-utils.ts +389 -0
- package/src/proofs/browser.ts +246 -19
- package/src/proofs/circuits/funding_proof.json +1 -1
- package/src/proofs/noir.ts +14 -14
- package/src/proofs/worker.ts +426 -0
- package/src/zcash/bridge.ts +738 -0
- package/src/zcash/index.ts +36 -1
- package/src/zcash/swap-service.ts +793 -0
- package/dist/chunk-4VJHI66K.mjs +0 -12120
- package/dist/chunk-5BAS4D44.mjs +0 -10283
- package/dist/chunk-6WOV2YNG.mjs +0 -10179
- package/dist/chunk-DU7LQDD2.mjs +0 -10148
- package/dist/chunk-MR7HRCRS.mjs +0 -10165
- package/dist/chunk-NDGUWOOZ.mjs +0 -10157
- package/dist/chunk-O4Y2ZUDL.mjs +0 -12721
- package/dist/chunk-VXSHK7US.mjs +0 -10158
package/src/proofs/noir.ts
CHANGED
|
@@ -256,21 +256,15 @@ export class NoirProofProvider implements ProofProvider {
|
|
|
256
256
|
console.log('[NoirProofProvider] Generating funding proof...')
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
//
|
|
260
|
-
|
|
261
|
-
// We need to compute this to pass as a public input
|
|
262
|
-
const { commitmentHash, blindingField } = await this.computeCommitmentHash(
|
|
263
|
-
params.balance,
|
|
264
|
-
params.blindingFactor,
|
|
265
|
-
params.assetId
|
|
266
|
-
)
|
|
259
|
+
// Convert blinding factor to field element
|
|
260
|
+
const blindingField = this.bytesToField(params.blindingFactor)
|
|
267
261
|
|
|
268
262
|
// Prepare witness inputs for the circuit
|
|
263
|
+
// New circuit signature: (minimum_required: pub u64, asset_id: pub Field, balance: u64, blinding: Field) -> [u8; 32]
|
|
269
264
|
const witnessInputs = {
|
|
270
265
|
// Public inputs
|
|
271
|
-
commitment_hash: commitmentHash,
|
|
272
266
|
minimum_required: params.minimumRequired.toString(),
|
|
273
|
-
asset_id: this.assetIdToField(params.assetId)
|
|
267
|
+
asset_id: `0x${this.assetIdToField(params.assetId)}`,
|
|
274
268
|
// Private inputs
|
|
275
269
|
balance: params.balance.toString(),
|
|
276
270
|
blinding: blindingField,
|
|
@@ -278,16 +272,16 @@ export class NoirProofProvider implements ProofProvider {
|
|
|
278
272
|
|
|
279
273
|
if (this.config.verbose) {
|
|
280
274
|
console.log('[NoirProofProvider] Witness inputs:', {
|
|
281
|
-
commitment_hash: commitmentHash,
|
|
282
275
|
minimum_required: params.minimumRequired.toString(),
|
|
283
|
-
asset_id: this.assetIdToField(params.assetId)
|
|
276
|
+
asset_id: `0x${this.assetIdToField(params.assetId)}`,
|
|
284
277
|
balance: '[PRIVATE]',
|
|
285
278
|
blinding: '[PRIVATE]',
|
|
286
279
|
})
|
|
287
280
|
}
|
|
288
281
|
|
|
289
282
|
// Execute circuit to generate witness
|
|
290
|
-
|
|
283
|
+
// The circuit returns the commitment hash as [u8; 32]
|
|
284
|
+
const { witness, returnValue } = await this.fundingNoir.execute(witnessInputs)
|
|
291
285
|
|
|
292
286
|
if (this.config.verbose) {
|
|
293
287
|
console.log('[NoirProofProvider] Witness generated, creating proof...')
|
|
@@ -300,11 +294,17 @@ export class NoirProofProvider implements ProofProvider {
|
|
|
300
294
|
console.log('[NoirProofProvider] Proof generated successfully')
|
|
301
295
|
}
|
|
302
296
|
|
|
297
|
+
// Extract commitment hash from circuit return value
|
|
298
|
+
const { bytesToHex } = await import('@noble/hashes/utils')
|
|
299
|
+
const commitmentHashBytes = returnValue as number[]
|
|
300
|
+
const commitmentHashHex = bytesToHex(new Uint8Array(commitmentHashBytes))
|
|
301
|
+
|
|
303
302
|
// Extract public inputs from the proof
|
|
303
|
+
// Order: minimum_required, asset_id, commitment_hash (return value)
|
|
304
304
|
const publicInputs: `0x${string}`[] = [
|
|
305
|
-
`0x${commitmentHash}`,
|
|
306
305
|
`0x${params.minimumRequired.toString(16).padStart(16, '0')}`,
|
|
307
306
|
`0x${this.assetIdToField(params.assetId)}`,
|
|
307
|
+
`0x${commitmentHashHex}`,
|
|
308
308
|
]
|
|
309
309
|
|
|
310
310
|
// Create ZKProof object
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof Generation Web Worker
|
|
3
|
+
*
|
|
4
|
+
* Runs proof generation off the main thread to keep UI responsive.
|
|
5
|
+
* Communicates via postMessage with the main thread.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/sip-protocol/sip-protocol/issues/140
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ZKProof } from '@sip-protocol/types'
|
|
11
|
+
import type {
|
|
12
|
+
FundingProofParams,
|
|
13
|
+
ValidityProofParams,
|
|
14
|
+
FulfillmentProofParams,
|
|
15
|
+
ProofResult,
|
|
16
|
+
} from './interface'
|
|
17
|
+
|
|
18
|
+
// Worker message types
|
|
19
|
+
export type WorkerMessageType =
|
|
20
|
+
| 'init'
|
|
21
|
+
| 'generateFundingProof'
|
|
22
|
+
| 'generateValidityProof'
|
|
23
|
+
| 'generateFulfillmentProof'
|
|
24
|
+
| 'destroy'
|
|
25
|
+
|
|
26
|
+
export interface WorkerRequest {
|
|
27
|
+
id: string
|
|
28
|
+
type: WorkerMessageType
|
|
29
|
+
params?: FundingProofParams | ValidityProofParams | FulfillmentProofParams
|
|
30
|
+
config?: {
|
|
31
|
+
verbose?: boolean
|
|
32
|
+
oraclePublicKey?: { x: number[]; y: number[] }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WorkerResponse {
|
|
37
|
+
id: string
|
|
38
|
+
type: 'success' | 'error' | 'progress'
|
|
39
|
+
result?: ProofResult
|
|
40
|
+
error?: string
|
|
41
|
+
progress?: {
|
|
42
|
+
stage: string
|
|
43
|
+
percent: number
|
|
44
|
+
message: string
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create inline worker code as a blob URL
|
|
50
|
+
* This approach works with most bundlers without special configuration
|
|
51
|
+
*/
|
|
52
|
+
export function createWorkerBlobURL(): string {
|
|
53
|
+
const workerCode = `
|
|
54
|
+
// Proof Generation Worker
|
|
55
|
+
// This code runs in a separate thread
|
|
56
|
+
|
|
57
|
+
let fundingNoir = null;
|
|
58
|
+
let fundingBackend = null;
|
|
59
|
+
let validityNoir = null;
|
|
60
|
+
let validityBackend = null;
|
|
61
|
+
let fulfillmentNoir = null;
|
|
62
|
+
let fulfillmentBackend = null;
|
|
63
|
+
let isReady = false;
|
|
64
|
+
let config = { verbose: false };
|
|
65
|
+
|
|
66
|
+
// Helper to send progress updates
|
|
67
|
+
function sendProgress(id, stage, percent, message) {
|
|
68
|
+
self.postMessage({
|
|
69
|
+
id,
|
|
70
|
+
type: 'progress',
|
|
71
|
+
progress: { stage, percent, message }
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Helper to send error
|
|
76
|
+
function sendError(id, error) {
|
|
77
|
+
self.postMessage({
|
|
78
|
+
id,
|
|
79
|
+
type: 'error',
|
|
80
|
+
error: error.message || String(error)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Helper to send success
|
|
85
|
+
function sendSuccess(id, result) {
|
|
86
|
+
self.postMessage({
|
|
87
|
+
id,
|
|
88
|
+
type: 'success',
|
|
89
|
+
result
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Initialize circuits (called once)
|
|
94
|
+
async function initialize(id, initConfig) {
|
|
95
|
+
try {
|
|
96
|
+
sendProgress(id, 'initializing', 10, 'Loading Noir JS...');
|
|
97
|
+
|
|
98
|
+
// Dynamic imports for Noir
|
|
99
|
+
const { Noir } = await import('@noir-lang/noir_js');
|
|
100
|
+
const { UltraHonkBackend } = await import('@aztec/bb.js');
|
|
101
|
+
|
|
102
|
+
sendProgress(id, 'initializing', 30, 'Loading circuit artifacts...');
|
|
103
|
+
|
|
104
|
+
// Load circuit artifacts
|
|
105
|
+
const [fundingArtifact, validityArtifact, fulfillmentArtifact] = await Promise.all([
|
|
106
|
+
fetch(new URL('./circuits/funding_proof.json', import.meta.url)).then(r => r.json()),
|
|
107
|
+
fetch(new URL('./circuits/validity_proof.json', import.meta.url)).then(r => r.json()),
|
|
108
|
+
fetch(new URL('./circuits/fulfillment_proof.json', import.meta.url)).then(r => r.json()),
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
sendProgress(id, 'initializing', 50, 'Initializing backends...');
|
|
112
|
+
|
|
113
|
+
// Initialize Noir instances
|
|
114
|
+
fundingNoir = new Noir(fundingArtifact);
|
|
115
|
+
fundingBackend = new UltraHonkBackend(fundingArtifact.bytecode);
|
|
116
|
+
|
|
117
|
+
sendProgress(id, 'initializing', 70, 'Initializing validity circuit...');
|
|
118
|
+
validityNoir = new Noir(validityArtifact);
|
|
119
|
+
validityBackend = new UltraHonkBackend(validityArtifact.bytecode);
|
|
120
|
+
|
|
121
|
+
sendProgress(id, 'initializing', 90, 'Initializing fulfillment circuit...');
|
|
122
|
+
fulfillmentNoir = new Noir(fulfillmentArtifact);
|
|
123
|
+
fulfillmentBackend = new UltraHonkBackend(fulfillmentArtifact.bytecode);
|
|
124
|
+
|
|
125
|
+
config = initConfig || { verbose: false };
|
|
126
|
+
isReady = true;
|
|
127
|
+
|
|
128
|
+
sendProgress(id, 'complete', 100, 'Worker initialized');
|
|
129
|
+
sendSuccess(id, { initialized: true });
|
|
130
|
+
} catch (error) {
|
|
131
|
+
sendError(id, error);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Generate funding proof
|
|
136
|
+
async function generateFundingProof(id, params) {
|
|
137
|
+
if (!isReady) {
|
|
138
|
+
sendError(id, new Error('Worker not initialized'));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
sendProgress(id, 'witness', 20, 'Preparing witness...');
|
|
144
|
+
|
|
145
|
+
// Convert blinding factor to field
|
|
146
|
+
const blindingField = bytesToField(params.blindingFactor);
|
|
147
|
+
|
|
148
|
+
const witnessInputs = {
|
|
149
|
+
minimum_required: params.minimumRequired.toString(),
|
|
150
|
+
asset_id: '0x' + assetIdToField(params.assetId),
|
|
151
|
+
balance: params.balance.toString(),
|
|
152
|
+
blinding: blindingField,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
sendProgress(id, 'witness', 40, 'Executing circuit...');
|
|
156
|
+
const { witness, returnValue } = await fundingNoir.execute(witnessInputs);
|
|
157
|
+
|
|
158
|
+
sendProgress(id, 'proving', 60, 'Generating proof...');
|
|
159
|
+
const proofData = await fundingBackend.generateProof(witness);
|
|
160
|
+
|
|
161
|
+
sendProgress(id, 'complete', 100, 'Proof generated');
|
|
162
|
+
|
|
163
|
+
// Extract commitment hash from return value
|
|
164
|
+
const commitmentHashHex = bytesToHex(new Uint8Array(returnValue));
|
|
165
|
+
|
|
166
|
+
const publicInputs = [
|
|
167
|
+
'0x' + params.minimumRequired.toString(16).padStart(16, '0'),
|
|
168
|
+
'0x' + assetIdToField(params.assetId),
|
|
169
|
+
'0x' + commitmentHashHex,
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
const proof = {
|
|
173
|
+
type: 'funding',
|
|
174
|
+
proof: '0x' + bytesToHex(proofData.proof),
|
|
175
|
+
publicInputs,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
sendSuccess(id, { proof, publicInputs });
|
|
179
|
+
} catch (error) {
|
|
180
|
+
sendError(id, error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Helper functions
|
|
185
|
+
function bytesToField(bytes) {
|
|
186
|
+
let result = 0n;
|
|
187
|
+
const len = Math.min(bytes.length, 31);
|
|
188
|
+
for (let i = 0; i < len; i++) {
|
|
189
|
+
result = result * 256n + BigInt(bytes[i]);
|
|
190
|
+
}
|
|
191
|
+
return result.toString();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function assetIdToField(assetId) {
|
|
195
|
+
if (assetId.startsWith('0x')) {
|
|
196
|
+
return assetId.slice(2).padStart(64, '0');
|
|
197
|
+
}
|
|
198
|
+
const encoder = new TextEncoder();
|
|
199
|
+
const bytes = encoder.encode(assetId);
|
|
200
|
+
let result = 0n;
|
|
201
|
+
for (let i = 0; i < bytes.length && i < 31; i++) {
|
|
202
|
+
result = result * 256n + BigInt(bytes[i]);
|
|
203
|
+
}
|
|
204
|
+
return result.toString(16).padStart(64, '0');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function bytesToHex(bytes) {
|
|
208
|
+
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Message handler
|
|
212
|
+
self.onmessage = async function(event) {
|
|
213
|
+
const { id, type, params, config: initConfig } = event.data;
|
|
214
|
+
|
|
215
|
+
switch (type) {
|
|
216
|
+
case 'init':
|
|
217
|
+
await initialize(id, initConfig);
|
|
218
|
+
break;
|
|
219
|
+
case 'generateFundingProof':
|
|
220
|
+
await generateFundingProof(id, params);
|
|
221
|
+
break;
|
|
222
|
+
case 'generateValidityProof':
|
|
223
|
+
// TODO: Implement
|
|
224
|
+
sendError(id, new Error('Validity proof not yet implemented in worker'));
|
|
225
|
+
break;
|
|
226
|
+
case 'generateFulfillmentProof':
|
|
227
|
+
// TODO: Implement
|
|
228
|
+
sendError(id, new Error('Fulfillment proof not yet implemented in worker'));
|
|
229
|
+
break;
|
|
230
|
+
case 'destroy':
|
|
231
|
+
// Cleanup
|
|
232
|
+
fundingNoir = null;
|
|
233
|
+
fundingBackend = null;
|
|
234
|
+
validityNoir = null;
|
|
235
|
+
validityBackend = null;
|
|
236
|
+
fulfillmentNoir = null;
|
|
237
|
+
fulfillmentBackend = null;
|
|
238
|
+
isReady = false;
|
|
239
|
+
sendSuccess(id, { destroyed: true });
|
|
240
|
+
break;
|
|
241
|
+
default:
|
|
242
|
+
sendError(id, new Error('Unknown message type: ' + type));
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
`
|
|
246
|
+
|
|
247
|
+
const blob = new Blob([workerCode], { type: 'application/javascript' })
|
|
248
|
+
return URL.createObjectURL(blob)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* ProofWorker class for managing Web Worker proof generation
|
|
253
|
+
*
|
|
254
|
+
* Provides a clean API for generating proofs in a Web Worker,
|
|
255
|
+
* with progress callbacks and automatic fallback to main thread.
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```typescript
|
|
259
|
+
* const worker = new ProofWorker()
|
|
260
|
+
* await worker.initialize()
|
|
261
|
+
*
|
|
262
|
+
* const result = await worker.generateProof('funding', params, (progress) => {
|
|
263
|
+
* console.log(`${progress.stage}: ${progress.percent}%`)
|
|
264
|
+
* })
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
export class ProofWorker {
|
|
268
|
+
private worker: Worker | null = null
|
|
269
|
+
private pendingRequests: Map<
|
|
270
|
+
string,
|
|
271
|
+
{
|
|
272
|
+
resolve: (result: ProofResult) => void
|
|
273
|
+
reject: (error: Error) => void
|
|
274
|
+
onProgress?: (progress: NonNullable<WorkerResponse['progress']>) => void
|
|
275
|
+
}
|
|
276
|
+
> = new Map()
|
|
277
|
+
private _isReady = false
|
|
278
|
+
private requestCounter = 0
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Check if Web Workers are supported
|
|
282
|
+
*/
|
|
283
|
+
static isSupported(): boolean {
|
|
284
|
+
return typeof Worker !== 'undefined' && typeof Blob !== 'undefined'
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Check if worker is initialized and ready
|
|
289
|
+
*/
|
|
290
|
+
get isReady(): boolean {
|
|
291
|
+
return this._isReady
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Initialize the worker
|
|
296
|
+
*/
|
|
297
|
+
async initialize(config?: {
|
|
298
|
+
verbose?: boolean
|
|
299
|
+
oraclePublicKey?: { x: number[]; y: number[] }
|
|
300
|
+
}): Promise<void> {
|
|
301
|
+
if (this._isReady) {
|
|
302
|
+
return
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (!ProofWorker.isSupported()) {
|
|
306
|
+
throw new Error('Web Workers not supported in this environment')
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Create worker from blob URL
|
|
310
|
+
const workerURL = createWorkerBlobURL()
|
|
311
|
+
this.worker = new Worker(workerURL, { type: 'module' })
|
|
312
|
+
|
|
313
|
+
// Set up message handler
|
|
314
|
+
this.worker.onmessage = (event: MessageEvent<WorkerResponse>) => {
|
|
315
|
+
this.handleWorkerMessage(event.data)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
this.worker.onerror = (error) => {
|
|
319
|
+
console.error('[ProofWorker] Worker error:', error)
|
|
320
|
+
// Reject all pending requests
|
|
321
|
+
for (const [id, { reject }] of this.pendingRequests) {
|
|
322
|
+
reject(new Error(`Worker error: ${error.message}`))
|
|
323
|
+
this.pendingRequests.delete(id)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Initialize the worker
|
|
328
|
+
await this.sendRequest('init', undefined, config)
|
|
329
|
+
this._isReady = true
|
|
330
|
+
|
|
331
|
+
// Cleanup blob URL
|
|
332
|
+
URL.revokeObjectURL(workerURL)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Generate a proof using the worker
|
|
337
|
+
*/
|
|
338
|
+
async generateProof(
|
|
339
|
+
type: 'funding' | 'validity' | 'fulfillment',
|
|
340
|
+
params: FundingProofParams | ValidityProofParams | FulfillmentProofParams,
|
|
341
|
+
onProgress?: (progress: NonNullable<WorkerResponse['progress']>) => void
|
|
342
|
+
): Promise<ProofResult> {
|
|
343
|
+
if (!this._isReady || !this.worker) {
|
|
344
|
+
throw new Error('Worker not initialized. Call initialize() first.')
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const messageType =
|
|
348
|
+
type === 'funding'
|
|
349
|
+
? 'generateFundingProof'
|
|
350
|
+
: type === 'validity'
|
|
351
|
+
? 'generateValidityProof'
|
|
352
|
+
: 'generateFulfillmentProof'
|
|
353
|
+
|
|
354
|
+
return this.sendRequest(messageType, params, undefined, onProgress)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Destroy the worker and free resources
|
|
359
|
+
*/
|
|
360
|
+
async destroy(): Promise<void> {
|
|
361
|
+
if (this.worker) {
|
|
362
|
+
try {
|
|
363
|
+
await this.sendRequest('destroy')
|
|
364
|
+
} catch {
|
|
365
|
+
// Ignore errors during cleanup
|
|
366
|
+
}
|
|
367
|
+
this.worker.terminate()
|
|
368
|
+
this.worker = null
|
|
369
|
+
}
|
|
370
|
+
this._isReady = false
|
|
371
|
+
this.pendingRequests.clear()
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Send a request to the worker
|
|
376
|
+
*/
|
|
377
|
+
private sendRequest(
|
|
378
|
+
type: WorkerMessageType,
|
|
379
|
+
params?: FundingProofParams | ValidityProofParams | FulfillmentProofParams,
|
|
380
|
+
config?: { verbose?: boolean; oraclePublicKey?: { x: number[]; y: number[] } },
|
|
381
|
+
onProgress?: (progress: NonNullable<WorkerResponse['progress']>) => void
|
|
382
|
+
): Promise<ProofResult> {
|
|
383
|
+
return new Promise((resolve, reject) => {
|
|
384
|
+
if (!this.worker) {
|
|
385
|
+
reject(new Error('Worker not available'))
|
|
386
|
+
return
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const id = `req_${++this.requestCounter}_${Date.now()}`
|
|
390
|
+
this.pendingRequests.set(id, { resolve, reject, onProgress })
|
|
391
|
+
|
|
392
|
+
const request: WorkerRequest = { id, type, params, config }
|
|
393
|
+
this.worker.postMessage(request)
|
|
394
|
+
})
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Handle messages from the worker
|
|
399
|
+
*/
|
|
400
|
+
private handleWorkerMessage(response: WorkerResponse): void {
|
|
401
|
+
const pending = this.pendingRequests.get(response.id)
|
|
402
|
+
if (!pending) {
|
|
403
|
+
console.warn('[ProofWorker] Received response for unknown request:', response.id)
|
|
404
|
+
return
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
switch (response.type) {
|
|
408
|
+
case 'success':
|
|
409
|
+
this.pendingRequests.delete(response.id)
|
|
410
|
+
pending.resolve(response.result as ProofResult)
|
|
411
|
+
break
|
|
412
|
+
case 'error':
|
|
413
|
+
this.pendingRequests.delete(response.id)
|
|
414
|
+
pending.reject(new Error(response.error))
|
|
415
|
+
break
|
|
416
|
+
case 'progress':
|
|
417
|
+
if (pending.onProgress && response.progress) {
|
|
418
|
+
pending.onProgress(response.progress)
|
|
419
|
+
}
|
|
420
|
+
break
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Re-export types
|
|
426
|
+
export type { ProofResult }
|