@sip-protocol/sdk 0.1.9 → 0.2.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.
@@ -0,0 +1,1037 @@
1
+ import {
2
+ ATTESTATION_VERSION,
3
+ BaseWalletAdapter,
4
+ CHAIN_NUMERIC_IDS,
5
+ ComplianceManager,
6
+ CryptoError,
7
+ DEFAULT_THRESHOLD,
8
+ DEFAULT_TOTAL_ORACLES,
9
+ DerivationPath,
10
+ EncryptionNotImplementedError,
11
+ ErrorCode,
12
+ EthereumChainId,
13
+ EthereumWalletAdapter,
14
+ HardwareErrorCode,
15
+ HardwareWalletError,
16
+ IntentBuilder,
17
+ IntentError,
18
+ IntentStatus,
19
+ LedgerWalletAdapter,
20
+ MockEthereumAdapter,
21
+ MockLedgerAdapter,
22
+ MockProofProvider,
23
+ MockSolanaAdapter,
24
+ MockSolver,
25
+ MockTrezorAdapter,
26
+ MockWalletAdapter,
27
+ NATIVE_TOKENS,
28
+ NEARIntentsAdapter,
29
+ NetworkError,
30
+ NoirProofProvider,
31
+ ORACLE_DOMAIN,
32
+ OneClickClient,
33
+ OneClickDepositMode,
34
+ OneClickErrorCode,
35
+ OneClickSwapStatus,
36
+ OneClickSwapType,
37
+ PaymentBuilder,
38
+ PaymentStatus,
39
+ PrivacyLevel,
40
+ ProofError,
41
+ ProofGenerationError,
42
+ ProofNotImplementedError,
43
+ ProposalStatus,
44
+ ReportStatus,
45
+ SIP,
46
+ SIPError,
47
+ SIP_VERSION,
48
+ STABLECOIN_ADDRESSES,
49
+ STABLECOIN_DECIMALS,
50
+ STABLECOIN_INFO,
51
+ SolanaWalletAdapter,
52
+ Treasury,
53
+ TrezorWalletAdapter,
54
+ ValidationError,
55
+ WalletError,
56
+ WalletErrorCode,
57
+ ZcashErrorCode,
58
+ ZcashRPCClient,
59
+ ZcashRPCError,
60
+ ZcashShieldedService,
61
+ addBlindings,
62
+ addCommitments,
63
+ addOracle,
64
+ attachProofs,
65
+ base58ToHex,
66
+ bytesToHex,
67
+ checkEd25519StealthAddress,
68
+ checkStealthAddress,
69
+ commit,
70
+ commitZero,
71
+ computeAttestationHash,
72
+ createCommitment,
73
+ createEthereumAdapter,
74
+ createLedgerAdapter,
75
+ createMockEthereumAdapter,
76
+ createMockEthereumProvider,
77
+ createMockLedgerAdapter,
78
+ createMockSolanaAdapter,
79
+ createMockSolanaConnection,
80
+ createMockSolanaProvider,
81
+ createMockSolver,
82
+ createMockTrezorAdapter,
83
+ createNEARIntentsAdapter,
84
+ createOracleRegistry,
85
+ createProductionSIP,
86
+ createSIP,
87
+ createShieldedIntent,
88
+ createShieldedPayment,
89
+ createSolanaAdapter,
90
+ createTrezorAdapter,
91
+ createWalletFactory,
92
+ createZcashClient,
93
+ createZcashShieldedService,
94
+ decodeStealthMetaAddress,
95
+ decryptMemo,
96
+ decryptWithViewing,
97
+ deriveEd25519StealthPrivateKey,
98
+ deriveOracleId,
99
+ deriveStealthPrivateKey,
100
+ deriveViewingKey,
101
+ deserializeAttestationMessage,
102
+ deserializeIntent,
103
+ deserializePayment,
104
+ detectEthereumWallets,
105
+ detectSolanaWallets,
106
+ ed25519PublicKeyToNearAddress,
107
+ ed25519PublicKeyToSolanaAddress,
108
+ encodeStealthMetaAddress,
109
+ encryptForViewing,
110
+ featureNotSupportedError,
111
+ formatStablecoinAmount,
112
+ fromHex,
113
+ fromStablecoinUnits,
114
+ fulfillment_proof_default,
115
+ funding_proof_default,
116
+ generateBlinding,
117
+ generateEd25519StealthAddress,
118
+ generateEd25519StealthMetaAddress,
119
+ generateIntentId,
120
+ generateRandomBytes,
121
+ generateStealthAddress,
122
+ generateStealthMetaAddress,
123
+ generateViewingKey,
124
+ getActiveOracles,
125
+ getAvailableTransports,
126
+ getBrowserInfo,
127
+ getChainNumericId,
128
+ getChainsForStablecoin,
129
+ getCurveForChain,
130
+ getDefaultRpcEndpoint,
131
+ getDerivationPath,
132
+ getErrorMessage,
133
+ getEthereumProvider,
134
+ getGenerators,
135
+ getIntentSummary,
136
+ getPaymentSummary,
137
+ getPaymentTimeRemaining,
138
+ getPrivacyConfig,
139
+ getPrivacyDescription,
140
+ getSolanaProvider,
141
+ getStablecoin,
142
+ getStablecoinInfo,
143
+ getStablecoinsForChain,
144
+ getSupportedStablecoins,
145
+ getTimeRemaining,
146
+ hasEnoughOracles,
147
+ hasErrorCode,
148
+ hasRequiredProofs,
149
+ hash,
150
+ hexToBytes,
151
+ hexToNumber,
152
+ isBrowser,
153
+ isEd25519Chain,
154
+ isExpired,
155
+ isNonNegativeAmount,
156
+ isPaymentExpired,
157
+ isPrivate,
158
+ isPrivateWalletAdapter,
159
+ isSIPError,
160
+ isStablecoin,
161
+ isStablecoinOnChain,
162
+ isValidAmount,
163
+ isValidChainId,
164
+ isValidCompressedPublicKey,
165
+ isValidEd25519PublicKey,
166
+ isValidHex,
167
+ isValidHexLength,
168
+ isValidNearAccountId,
169
+ isValidNearImplicitAddress,
170
+ isValidPrivacyLevel,
171
+ isValidPrivateKey,
172
+ isValidScalar,
173
+ isValidSlippage,
174
+ isValidSolanaAddress,
175
+ isValidStealthMetaAddress,
176
+ nearAddressToEd25519PublicKey,
177
+ normalizeAddress,
178
+ notConnectedError,
179
+ publicKeyToEthAddress,
180
+ registerWallet,
181
+ removeOracle,
182
+ secureWipe,
183
+ secureWipeAll,
184
+ serializeAttestationMessage,
185
+ serializeIntent,
186
+ serializePayment,
187
+ signAttestationMessage,
188
+ solanaAddressToEd25519PublicKey,
189
+ solanaPublicKeyToHex,
190
+ subtractBlindings,
191
+ subtractCommitments,
192
+ supportsSharedArrayBuffer,
193
+ supportsViewingKey,
194
+ supportsWebBluetooth,
195
+ supportsWebHID,
196
+ supportsWebUSB,
197
+ supportsWebWorkers,
198
+ toHex,
199
+ toStablecoinUnits,
200
+ trackIntent,
201
+ trackPayment,
202
+ updateOracleStatus,
203
+ validateAsset,
204
+ validateCreateIntentParams,
205
+ validateIntentInput,
206
+ validateIntentOutput,
207
+ validateScalar,
208
+ validateViewingKey,
209
+ validity_proof_default,
210
+ verifyAttestation,
211
+ verifyCommitment,
212
+ verifyOpening,
213
+ verifyOracleSignature,
214
+ walletRegistry,
215
+ withSecureBuffer,
216
+ withSecureBufferSync,
217
+ wrapError
218
+ } from "./chunk-4VJHI66K.mjs";
219
+
220
+ // src/proofs/browser.ts
221
+ import { Noir } from "@noir-lang/noir_js";
222
+ import { UltraHonkBackend } from "@aztec/bb.js";
223
+ import { secp256k1 } from "@noble/curves/secp256k1";
224
+ var BrowserNoirProvider = class _BrowserNoirProvider {
225
+ framework = "noir";
226
+ _isReady = false;
227
+ config;
228
+ // Circuit instances
229
+ fundingNoir = null;
230
+ fundingBackend = null;
231
+ validityNoir = null;
232
+ validityBackend = null;
233
+ fulfillmentNoir = null;
234
+ fulfillmentBackend = null;
235
+ // Worker instance (optional)
236
+ worker = null;
237
+ workerPending = /* @__PURE__ */ new Map();
238
+ constructor(config = {}) {
239
+ this.config = {
240
+ useWorker: config.useWorker ?? true,
241
+ verbose: config.verbose ?? false,
242
+ oraclePublicKey: config.oraclePublicKey ?? void 0,
243
+ timeout: config.timeout ?? 6e4
244
+ };
245
+ if (!isBrowser()) {
246
+ console.warn(
247
+ "[BrowserNoirProvider] Not running in browser environment. Consider using NoirProofProvider for Node.js."
248
+ );
249
+ }
250
+ }
251
+ get isReady() {
252
+ return this._isReady;
253
+ }
254
+ /**
255
+ * Get browser environment info
256
+ */
257
+ static getBrowserInfo() {
258
+ return getBrowserInfo();
259
+ }
260
+ /**
261
+ * Check if browser supports all required features
262
+ */
263
+ static checkBrowserSupport() {
264
+ const missing = [];
265
+ if (!isBrowser()) {
266
+ missing.push("browser environment");
267
+ }
268
+ if (typeof WebAssembly === "undefined") {
269
+ missing.push("WebAssembly");
270
+ }
271
+ if (!supportsSharedArrayBuffer()) {
272
+ missing.push("SharedArrayBuffer (requires COOP/COEP headers)");
273
+ }
274
+ return {
275
+ supported: missing.length === 0,
276
+ missing
277
+ };
278
+ }
279
+ /**
280
+ * Derive secp256k1 public key coordinates from a private key
281
+ */
282
+ static derivePublicKey(privateKey) {
283
+ const uncompressedPubKey = secp256k1.getPublicKey(privateKey, false);
284
+ const x = Array.from(uncompressedPubKey.slice(1, 33));
285
+ const y = Array.from(uncompressedPubKey.slice(33, 65));
286
+ return { x, y };
287
+ }
288
+ /**
289
+ * Initialize the browser provider
290
+ *
291
+ * Loads WASM and circuit artifacts. This should be called before any
292
+ * proof generation. Consider showing a loading indicator during init.
293
+ *
294
+ * @param onProgress - Optional progress callback
295
+ */
296
+ async initialize(onProgress) {
297
+ if (this._isReady) {
298
+ return;
299
+ }
300
+ const { supported, missing } = _BrowserNoirProvider.checkBrowserSupport();
301
+ if (!supported) {
302
+ throw new ProofError(
303
+ `Browser missing required features: ${missing.join(", ")}`,
304
+ "SIP_4004" /* PROOF_PROVIDER_NOT_READY */
305
+ );
306
+ }
307
+ try {
308
+ onProgress?.({
309
+ stage: "initializing",
310
+ percent: 0,
311
+ message: "Loading WASM runtime..."
312
+ });
313
+ if (this.config.verbose) {
314
+ console.log("[BrowserNoirProvider] Initializing...");
315
+ console.log("[BrowserNoirProvider] Browser info:", getBrowserInfo());
316
+ }
317
+ const fundingCircuit = funding_proof_default;
318
+ const validityCircuit = validity_proof_default;
319
+ const fulfillmentCircuit = fulfillment_proof_default;
320
+ onProgress?.({
321
+ stage: "initializing",
322
+ percent: 20,
323
+ message: "Creating proof backends..."
324
+ });
325
+ this.fundingBackend = new UltraHonkBackend(fundingCircuit.bytecode);
326
+ this.validityBackend = new UltraHonkBackend(validityCircuit.bytecode);
327
+ this.fulfillmentBackend = new UltraHonkBackend(fulfillmentCircuit.bytecode);
328
+ onProgress?.({
329
+ stage: "initializing",
330
+ percent: 60,
331
+ message: "Initializing Noir circuits..."
332
+ });
333
+ this.fundingNoir = new Noir(fundingCircuit);
334
+ this.validityNoir = new Noir(validityCircuit);
335
+ this.fulfillmentNoir = new Noir(fulfillmentCircuit);
336
+ onProgress?.({
337
+ stage: "initializing",
338
+ percent: 90,
339
+ message: "Setting up worker..."
340
+ });
341
+ if (this.config.useWorker && supportsWebWorkers()) {
342
+ await this.initializeWorker();
343
+ }
344
+ this._isReady = true;
345
+ onProgress?.({
346
+ stage: "complete",
347
+ percent: 100,
348
+ message: "Ready for proof generation"
349
+ });
350
+ if (this.config.verbose) {
351
+ console.log("[BrowserNoirProvider] Initialization complete");
352
+ }
353
+ } catch (error) {
354
+ throw new ProofError(
355
+ `Failed to initialize BrowserNoirProvider: ${error instanceof Error ? error.message : String(error)}`,
356
+ "SIP_4003" /* PROOF_NOT_IMPLEMENTED */,
357
+ { context: { error } }
358
+ );
359
+ }
360
+ }
361
+ /**
362
+ * Initialize Web Worker for off-main-thread proof generation
363
+ */
364
+ async initializeWorker() {
365
+ if (this.config.verbose) {
366
+ console.log("[BrowserNoirProvider] Worker support: using async main-thread");
367
+ }
368
+ }
369
+ /**
370
+ * Generate a Funding Proof
371
+ *
372
+ * Proves: balance >= minimumRequired without revealing balance
373
+ *
374
+ * @param params - Funding proof parameters
375
+ * @param onProgress - Optional progress callback
376
+ */
377
+ async generateFundingProof(params, onProgress) {
378
+ this.ensureReady();
379
+ if (!this.fundingNoir || !this.fundingBackend) {
380
+ throw new ProofGenerationError("funding", "Funding circuit not initialized");
381
+ }
382
+ try {
383
+ onProgress?.({
384
+ stage: "witness",
385
+ percent: 10,
386
+ message: "Preparing witness inputs..."
387
+ });
388
+ const { commitmentHash, blindingField } = await this.computeCommitmentHash(
389
+ params.balance,
390
+ params.blindingFactor,
391
+ params.assetId
392
+ );
393
+ const witnessInputs = {
394
+ commitment_hash: commitmentHash,
395
+ minimum_required: params.minimumRequired.toString(),
396
+ asset_id: this.assetIdToField(params.assetId),
397
+ balance: params.balance.toString(),
398
+ blinding: blindingField
399
+ };
400
+ onProgress?.({
401
+ stage: "witness",
402
+ percent: 30,
403
+ message: "Generating witness..."
404
+ });
405
+ const { witness } = await this.fundingNoir.execute(witnessInputs);
406
+ onProgress?.({
407
+ stage: "proving",
408
+ percent: 50,
409
+ message: "Generating proof (this may take a moment)..."
410
+ });
411
+ const proofData = await this.fundingBackend.generateProof(witness);
412
+ onProgress?.({
413
+ stage: "complete",
414
+ percent: 100,
415
+ message: "Proof generated successfully"
416
+ });
417
+ const publicInputs = [
418
+ `0x${commitmentHash}`,
419
+ `0x${params.minimumRequired.toString(16).padStart(16, "0")}`,
420
+ `0x${this.assetIdToField(params.assetId)}`
421
+ ];
422
+ const proof = {
423
+ type: "funding",
424
+ proof: `0x${bytesToHex(proofData.proof)}`,
425
+ publicInputs
426
+ };
427
+ return { proof, publicInputs };
428
+ } catch (error) {
429
+ const message = error instanceof Error ? error.message : String(error);
430
+ throw new ProofGenerationError(
431
+ "funding",
432
+ `Failed to generate funding proof: ${message}`,
433
+ error instanceof Error ? error : void 0
434
+ );
435
+ }
436
+ }
437
+ /**
438
+ * Generate a Validity Proof
439
+ *
440
+ * Proves: Intent is authorized by sender without revealing identity
441
+ */
442
+ async generateValidityProof(params, onProgress) {
443
+ this.ensureReady();
444
+ if (!this.validityNoir || !this.validityBackend) {
445
+ throw new ProofGenerationError("validity", "Validity circuit not initialized");
446
+ }
447
+ try {
448
+ onProgress?.({
449
+ stage: "witness",
450
+ percent: 10,
451
+ message: "Preparing validity witness..."
452
+ });
453
+ const intentHashField = this.hexToField(params.intentHash);
454
+ const senderAddressField = this.hexToField(params.senderAddress);
455
+ const senderBlindingField = this.bytesToField(params.senderBlinding);
456
+ const senderSecretField = this.bytesToField(params.senderSecret);
457
+ const nonceField = this.bytesToField(params.nonce);
458
+ const { commitmentX, commitmentY } = await this.computeSenderCommitment(
459
+ senderAddressField,
460
+ senderBlindingField
461
+ );
462
+ const nullifier = await this.computeNullifier(senderSecretField, intentHashField, nonceField);
463
+ const signature = Array.from(params.authorizationSignature);
464
+ const messageHash = this.fieldToBytes32(intentHashField);
465
+ let pubKeyX;
466
+ let pubKeyY;
467
+ if (params.senderPublicKey) {
468
+ pubKeyX = Array.from(params.senderPublicKey.x);
469
+ pubKeyY = Array.from(params.senderPublicKey.y);
470
+ } else {
471
+ const coords = this.getPublicKeyCoordinates(params.senderSecret);
472
+ pubKeyX = coords.x;
473
+ pubKeyY = coords.y;
474
+ }
475
+ const witnessInputs = {
476
+ intent_hash: intentHashField,
477
+ sender_commitment_x: commitmentX,
478
+ sender_commitment_y: commitmentY,
479
+ nullifier,
480
+ timestamp: params.timestamp.toString(),
481
+ expiry: params.expiry.toString(),
482
+ sender_address: senderAddressField,
483
+ sender_blinding: senderBlindingField,
484
+ sender_secret: senderSecretField,
485
+ pub_key_x: pubKeyX,
486
+ pub_key_y: pubKeyY,
487
+ signature,
488
+ message_hash: messageHash,
489
+ nonce: nonceField
490
+ };
491
+ onProgress?.({
492
+ stage: "witness",
493
+ percent: 30,
494
+ message: "Generating witness..."
495
+ });
496
+ const { witness } = await this.validityNoir.execute(witnessInputs);
497
+ onProgress?.({
498
+ stage: "proving",
499
+ percent: 50,
500
+ message: "Generating validity proof..."
501
+ });
502
+ const proofData = await this.validityBackend.generateProof(witness);
503
+ onProgress?.({
504
+ stage: "complete",
505
+ percent: 100,
506
+ message: "Validity proof generated"
507
+ });
508
+ const publicInputs = [
509
+ `0x${intentHashField}`,
510
+ `0x${commitmentX}`,
511
+ `0x${commitmentY}`,
512
+ `0x${nullifier}`,
513
+ `0x${params.timestamp.toString(16).padStart(16, "0")}`,
514
+ `0x${params.expiry.toString(16).padStart(16, "0")}`
515
+ ];
516
+ const proof = {
517
+ type: "validity",
518
+ proof: `0x${bytesToHex(proofData.proof)}`,
519
+ publicInputs
520
+ };
521
+ return { proof, publicInputs };
522
+ } catch (error) {
523
+ const message = error instanceof Error ? error.message : String(error);
524
+ throw new ProofGenerationError(
525
+ "validity",
526
+ `Failed to generate validity proof: ${message}`,
527
+ error instanceof Error ? error : void 0
528
+ );
529
+ }
530
+ }
531
+ /**
532
+ * Generate a Fulfillment Proof
533
+ *
534
+ * Proves: Solver correctly executed the intent
535
+ */
536
+ async generateFulfillmentProof(params, onProgress) {
537
+ this.ensureReady();
538
+ if (!this.fulfillmentNoir || !this.fulfillmentBackend) {
539
+ throw new ProofGenerationError("fulfillment", "Fulfillment circuit not initialized");
540
+ }
541
+ try {
542
+ onProgress?.({
543
+ stage: "witness",
544
+ percent: 10,
545
+ message: "Preparing fulfillment witness..."
546
+ });
547
+ const intentHashField = this.hexToField(params.intentHash);
548
+ const recipientStealthField = this.hexToField(params.recipientStealth);
549
+ const { commitmentX, commitmentY } = await this.computeOutputCommitment(
550
+ params.outputAmount,
551
+ params.outputBlinding
552
+ );
553
+ const solverSecretField = this.bytesToField(params.solverSecret);
554
+ const solverId = await this.computeSolverId(solverSecretField);
555
+ const outputBlindingField = this.bytesToField(params.outputBlinding);
556
+ const attestation = params.oracleAttestation;
557
+ const attestationRecipientField = this.hexToField(attestation.recipient);
558
+ const attestationTxHashField = this.hexToField(attestation.txHash);
559
+ const oracleSignature = Array.from(attestation.signature);
560
+ const oracleMessageHash = await this.computeOracleMessageHash(
561
+ attestation.recipient,
562
+ attestation.amount,
563
+ attestation.txHash,
564
+ attestation.blockNumber
565
+ );
566
+ const oraclePubKeyX = this.config.oraclePublicKey?.x ?? new Array(32).fill(0);
567
+ const oraclePubKeyY = this.config.oraclePublicKey?.y ?? new Array(32).fill(0);
568
+ const witnessInputs = {
569
+ intent_hash: intentHashField,
570
+ output_commitment_x: commitmentX,
571
+ output_commitment_y: commitmentY,
572
+ recipient_stealth: recipientStealthField,
573
+ min_output_amount: params.minOutputAmount.toString(),
574
+ solver_id: solverId,
575
+ fulfillment_time: params.fulfillmentTime.toString(),
576
+ expiry: params.expiry.toString(),
577
+ output_amount: params.outputAmount.toString(),
578
+ output_blinding: outputBlindingField,
579
+ solver_secret: solverSecretField,
580
+ attestation_recipient: attestationRecipientField,
581
+ attestation_amount: attestation.amount.toString(),
582
+ attestation_tx_hash: attestationTxHashField,
583
+ attestation_block: attestation.blockNumber.toString(),
584
+ oracle_signature: oracleSignature,
585
+ oracle_message_hash: oracleMessageHash,
586
+ oracle_pub_key_x: oraclePubKeyX,
587
+ oracle_pub_key_y: oraclePubKeyY
588
+ };
589
+ onProgress?.({
590
+ stage: "witness",
591
+ percent: 30,
592
+ message: "Generating witness..."
593
+ });
594
+ const { witness } = await this.fulfillmentNoir.execute(witnessInputs);
595
+ onProgress?.({
596
+ stage: "proving",
597
+ percent: 50,
598
+ message: "Generating fulfillment proof..."
599
+ });
600
+ const proofData = await this.fulfillmentBackend.generateProof(witness);
601
+ onProgress?.({
602
+ stage: "complete",
603
+ percent: 100,
604
+ message: "Fulfillment proof generated"
605
+ });
606
+ const publicInputs = [
607
+ `0x${intentHashField}`,
608
+ `0x${commitmentX}`,
609
+ `0x${commitmentY}`,
610
+ `0x${recipientStealthField}`,
611
+ `0x${params.minOutputAmount.toString(16).padStart(16, "0")}`,
612
+ `0x${solverId}`,
613
+ `0x${params.fulfillmentTime.toString(16).padStart(16, "0")}`,
614
+ `0x${params.expiry.toString(16).padStart(16, "0")}`
615
+ ];
616
+ const proof = {
617
+ type: "fulfillment",
618
+ proof: `0x${bytesToHex(proofData.proof)}`,
619
+ publicInputs
620
+ };
621
+ return { proof, publicInputs };
622
+ } catch (error) {
623
+ const message = error instanceof Error ? error.message : String(error);
624
+ throw new ProofGenerationError(
625
+ "fulfillment",
626
+ `Failed to generate fulfillment proof: ${message}`,
627
+ error instanceof Error ? error : void 0
628
+ );
629
+ }
630
+ }
631
+ /**
632
+ * Verify a proof
633
+ */
634
+ async verifyProof(proof) {
635
+ this.ensureReady();
636
+ let backend = null;
637
+ switch (proof.type) {
638
+ case "funding":
639
+ backend = this.fundingBackend;
640
+ break;
641
+ case "validity":
642
+ backend = this.validityBackend;
643
+ break;
644
+ case "fulfillment":
645
+ backend = this.fulfillmentBackend;
646
+ break;
647
+ default:
648
+ throw new ProofError(`Unknown proof type: ${proof.type}`, "SIP_4003" /* PROOF_NOT_IMPLEMENTED */);
649
+ }
650
+ if (!backend) {
651
+ throw new ProofError(
652
+ `${proof.type} backend not initialized`,
653
+ "SIP_4004" /* PROOF_PROVIDER_NOT_READY */
654
+ );
655
+ }
656
+ try {
657
+ const proofHex = proof.proof.startsWith("0x") ? proof.proof.slice(2) : proof.proof;
658
+ const proofBytes = hexToBytes(proofHex);
659
+ const isValid = await backend.verifyProof({
660
+ proof: proofBytes,
661
+ publicInputs: proof.publicInputs.map(
662
+ (input) => input.startsWith("0x") ? input.slice(2) : input
663
+ )
664
+ });
665
+ return isValid;
666
+ } catch (error) {
667
+ if (this.config.verbose) {
668
+ console.error("[BrowserNoirProvider] Verification error:", error);
669
+ }
670
+ return false;
671
+ }
672
+ }
673
+ /**
674
+ * Destroy the provider and free resources
675
+ */
676
+ async destroy() {
677
+ if (this.fundingBackend) {
678
+ await this.fundingBackend.destroy();
679
+ this.fundingBackend = null;
680
+ }
681
+ if (this.validityBackend) {
682
+ await this.validityBackend.destroy();
683
+ this.validityBackend = null;
684
+ }
685
+ if (this.fulfillmentBackend) {
686
+ await this.fulfillmentBackend.destroy();
687
+ this.fulfillmentBackend = null;
688
+ }
689
+ if (this.worker) {
690
+ this.worker.terminate();
691
+ this.worker = null;
692
+ }
693
+ this.fundingNoir = null;
694
+ this.validityNoir = null;
695
+ this.fulfillmentNoir = null;
696
+ this._isReady = false;
697
+ }
698
+ // ─── Private Utility Methods ────────────────────────────────────────────────
699
+ ensureReady() {
700
+ if (!this._isReady) {
701
+ throw new ProofError(
702
+ "BrowserNoirProvider not initialized. Call initialize() first.",
703
+ "SIP_4004" /* PROOF_PROVIDER_NOT_READY */
704
+ );
705
+ }
706
+ }
707
+ async computeCommitmentHash(balance, blindingFactor, assetId) {
708
+ const blindingField = this.bytesToField(blindingFactor);
709
+ const { sha256 } = await import("@noble/hashes/sha256");
710
+ const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
711
+ const preimage = new Uint8Array([
712
+ ...this.bigintToBytes(balance, 8),
713
+ ...blindingFactor.slice(0, 32),
714
+ ...hexToBytes(this.assetIdToField(assetId))
715
+ ]);
716
+ const hash2 = sha256(preimage);
717
+ const commitmentHash = nobleToHex(hash2);
718
+ return { commitmentHash, blindingField };
719
+ }
720
+ assetIdToField(assetId) {
721
+ if (assetId.startsWith("0x")) {
722
+ return assetId.slice(2).padStart(64, "0");
723
+ }
724
+ const encoder = new TextEncoder();
725
+ const bytes = encoder.encode(assetId);
726
+ let result = 0n;
727
+ for (let i = 0; i < bytes.length && i < 31; i++) {
728
+ result = result * 256n + BigInt(bytes[i]);
729
+ }
730
+ return result.toString(16).padStart(64, "0");
731
+ }
732
+ bytesToField(bytes) {
733
+ let result = 0n;
734
+ const len = Math.min(bytes.length, 31);
735
+ for (let i = 0; i < len; i++) {
736
+ result = result * 256n + BigInt(bytes[i]);
737
+ }
738
+ return result.toString();
739
+ }
740
+ bigintToBytes(value, length) {
741
+ const bytes = new Uint8Array(length);
742
+ let v = value;
743
+ for (let i = length - 1; i >= 0; i--) {
744
+ bytes[i] = Number(v & 0xffn);
745
+ v = v >> 8n;
746
+ }
747
+ return bytes;
748
+ }
749
+ hexToField(hex) {
750
+ const h = hex.startsWith("0x") ? hex.slice(2) : hex;
751
+ return h.padStart(64, "0");
752
+ }
753
+ fieldToBytes32(field) {
754
+ const hex = field.padStart(64, "0");
755
+ const bytes = [];
756
+ for (let i = 0; i < 32; i++) {
757
+ bytes.push(parseInt(hex.slice(i * 2, i * 2 + 2), 16));
758
+ }
759
+ return bytes;
760
+ }
761
+ async computeSenderCommitment(senderAddressField, senderBlindingField) {
762
+ const { sha256 } = await import("@noble/hashes/sha256");
763
+ const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
764
+ const addressBytes = hexToBytes(senderAddressField);
765
+ const blindingBytes = hexToBytes(senderBlindingField.padStart(64, "0"));
766
+ const preimage = new Uint8Array([...addressBytes, ...blindingBytes]);
767
+ const hash2 = sha256(preimage);
768
+ const commitmentX = nobleToHex(hash2.slice(0, 16)).padStart(64, "0");
769
+ const commitmentY = nobleToHex(hash2.slice(16, 32)).padStart(64, "0");
770
+ return { commitmentX, commitmentY };
771
+ }
772
+ async computeNullifier(senderSecretField, intentHashField, nonceField) {
773
+ const { sha256 } = await import("@noble/hashes/sha256");
774
+ const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
775
+ const secretBytes = hexToBytes(senderSecretField.padStart(64, "0"));
776
+ const intentBytes = hexToBytes(intentHashField);
777
+ const nonceBytes = hexToBytes(nonceField.padStart(64, "0"));
778
+ const preimage = new Uint8Array([...secretBytes, ...intentBytes, ...nonceBytes]);
779
+ const hash2 = sha256(preimage);
780
+ return nobleToHex(hash2);
781
+ }
782
+ async computeOutputCommitment(outputAmount, outputBlinding) {
783
+ const { sha256 } = await import("@noble/hashes/sha256");
784
+ const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
785
+ const amountBytes = this.bigintToBytes(outputAmount, 8);
786
+ const blindingBytes = outputBlinding.slice(0, 32);
787
+ const preimage = new Uint8Array([...amountBytes, ...blindingBytes]);
788
+ const hash2 = sha256(preimage);
789
+ const commitmentX = nobleToHex(hash2.slice(0, 16)).padStart(64, "0");
790
+ const commitmentY = nobleToHex(hash2.slice(16, 32)).padStart(64, "0");
791
+ return { commitmentX, commitmentY };
792
+ }
793
+ async computeSolverId(solverSecretField) {
794
+ const { sha256 } = await import("@noble/hashes/sha256");
795
+ const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
796
+ const secretBytes = hexToBytes(solverSecretField.padStart(64, "0"));
797
+ const hash2 = sha256(secretBytes);
798
+ return nobleToHex(hash2);
799
+ }
800
+ async computeOracleMessageHash(recipient, amount, txHash, blockNumber) {
801
+ const { sha256 } = await import("@noble/hashes/sha256");
802
+ const recipientBytes = hexToBytes(this.hexToField(recipient));
803
+ const amountBytes = this.bigintToBytes(amount, 8);
804
+ const txHashBytes = hexToBytes(this.hexToField(txHash));
805
+ const blockBytes = this.bigintToBytes(blockNumber, 8);
806
+ const preimage = new Uint8Array([
807
+ ...recipientBytes,
808
+ ...amountBytes,
809
+ ...txHashBytes,
810
+ ...blockBytes
811
+ ]);
812
+ const hash2 = sha256(preimage);
813
+ return Array.from(hash2);
814
+ }
815
+ getPublicKeyCoordinates(privateKey) {
816
+ const uncompressedPubKey = secp256k1.getPublicKey(privateKey, false);
817
+ const x = Array.from(uncompressedPubKey.slice(1, 33));
818
+ const y = Array.from(uncompressedPubKey.slice(33, 65));
819
+ return { x, y };
820
+ }
821
+ };
822
+ export {
823
+ ATTESTATION_VERSION,
824
+ BaseWalletAdapter,
825
+ BrowserNoirProvider,
826
+ CHAIN_NUMERIC_IDS,
827
+ ComplianceManager,
828
+ CryptoError,
829
+ DEFAULT_THRESHOLD,
830
+ DEFAULT_TOTAL_ORACLES,
831
+ DerivationPath,
832
+ EncryptionNotImplementedError,
833
+ ErrorCode,
834
+ EthereumChainId,
835
+ EthereumWalletAdapter,
836
+ HardwareErrorCode,
837
+ HardwareWalletError,
838
+ IntentBuilder,
839
+ IntentError,
840
+ IntentStatus,
841
+ LedgerWalletAdapter,
842
+ MockEthereumAdapter,
843
+ MockLedgerAdapter,
844
+ MockProofProvider,
845
+ MockSolanaAdapter,
846
+ MockSolver,
847
+ MockTrezorAdapter,
848
+ MockWalletAdapter,
849
+ NATIVE_TOKENS,
850
+ NEARIntentsAdapter,
851
+ NetworkError,
852
+ NoirProofProvider,
853
+ ORACLE_DOMAIN,
854
+ OneClickClient,
855
+ OneClickDepositMode,
856
+ OneClickErrorCode,
857
+ OneClickSwapStatus,
858
+ OneClickSwapType,
859
+ PaymentBuilder,
860
+ PaymentStatus,
861
+ PrivacyLevel,
862
+ ProofError,
863
+ ProofGenerationError,
864
+ ProofNotImplementedError,
865
+ ProposalStatus,
866
+ ReportStatus,
867
+ SIP,
868
+ SIPError,
869
+ SIP_VERSION,
870
+ STABLECOIN_ADDRESSES,
871
+ STABLECOIN_DECIMALS,
872
+ STABLECOIN_INFO,
873
+ SolanaWalletAdapter,
874
+ Treasury,
875
+ TrezorWalletAdapter,
876
+ ValidationError,
877
+ WalletError,
878
+ WalletErrorCode,
879
+ ZcashErrorCode,
880
+ ZcashRPCClient,
881
+ ZcashRPCError,
882
+ ZcashShieldedService,
883
+ addBlindings,
884
+ addCommitments,
885
+ addOracle,
886
+ attachProofs,
887
+ base58ToHex,
888
+ bytesToHex as browserBytesToHex,
889
+ hexToBytes as browserHexToBytes,
890
+ checkEd25519StealthAddress,
891
+ checkStealthAddress,
892
+ commit,
893
+ commitZero,
894
+ computeAttestationHash,
895
+ createCommitment,
896
+ createEthereumAdapter,
897
+ createLedgerAdapter,
898
+ createMockEthereumAdapter,
899
+ createMockEthereumProvider,
900
+ createMockLedgerAdapter,
901
+ createMockSolanaAdapter,
902
+ createMockSolanaConnection,
903
+ createMockSolanaProvider,
904
+ createMockSolver,
905
+ createMockTrezorAdapter,
906
+ createNEARIntentsAdapter,
907
+ createOracleRegistry,
908
+ createProductionSIP,
909
+ createSIP,
910
+ createShieldedIntent,
911
+ createShieldedPayment,
912
+ createSolanaAdapter,
913
+ createTrezorAdapter,
914
+ createWalletFactory,
915
+ createZcashClient,
916
+ createZcashShieldedService,
917
+ decodeStealthMetaAddress,
918
+ decryptMemo,
919
+ decryptWithViewing,
920
+ deriveEd25519StealthPrivateKey,
921
+ deriveOracleId,
922
+ deriveStealthPrivateKey,
923
+ deriveViewingKey,
924
+ deserializeAttestationMessage,
925
+ deserializeIntent,
926
+ deserializePayment,
927
+ detectEthereumWallets,
928
+ detectSolanaWallets,
929
+ ed25519PublicKeyToNearAddress,
930
+ ed25519PublicKeyToSolanaAddress,
931
+ encodeStealthMetaAddress,
932
+ encryptForViewing,
933
+ featureNotSupportedError,
934
+ formatStablecoinAmount,
935
+ fromHex,
936
+ fromStablecoinUnits,
937
+ generateBlinding,
938
+ generateEd25519StealthAddress,
939
+ generateEd25519StealthMetaAddress,
940
+ generateIntentId,
941
+ generateRandomBytes,
942
+ generateStealthAddress,
943
+ generateStealthMetaAddress,
944
+ generateViewingKey,
945
+ getActiveOracles,
946
+ getAvailableTransports,
947
+ getBrowserInfo,
948
+ getChainNumericId,
949
+ getChainsForStablecoin,
950
+ getCurveForChain,
951
+ getDefaultRpcEndpoint,
952
+ getDerivationPath,
953
+ getErrorMessage,
954
+ getEthereumProvider,
955
+ getGenerators,
956
+ getIntentSummary,
957
+ getPaymentSummary,
958
+ getPaymentTimeRemaining,
959
+ getPrivacyConfig,
960
+ getPrivacyDescription,
961
+ getSolanaProvider,
962
+ getStablecoin,
963
+ getStablecoinInfo,
964
+ getStablecoinsForChain,
965
+ getSupportedStablecoins,
966
+ getTimeRemaining,
967
+ hasEnoughOracles,
968
+ hasErrorCode,
969
+ hasRequiredProofs,
970
+ hash,
971
+ hexToNumber,
972
+ isBrowser,
973
+ isEd25519Chain,
974
+ isExpired,
975
+ isNonNegativeAmount,
976
+ isPaymentExpired,
977
+ isPrivate,
978
+ isPrivateWalletAdapter,
979
+ isSIPError,
980
+ isStablecoin,
981
+ isStablecoinOnChain,
982
+ isValidAmount,
983
+ isValidChainId,
984
+ isValidCompressedPublicKey,
985
+ isValidEd25519PublicKey,
986
+ isValidHex,
987
+ isValidHexLength,
988
+ isValidNearAccountId,
989
+ isValidNearImplicitAddress,
990
+ isValidPrivacyLevel,
991
+ isValidPrivateKey,
992
+ isValidScalar,
993
+ isValidSlippage,
994
+ isValidSolanaAddress,
995
+ isValidStealthMetaAddress,
996
+ nearAddressToEd25519PublicKey,
997
+ normalizeAddress,
998
+ notConnectedError,
999
+ publicKeyToEthAddress,
1000
+ registerWallet,
1001
+ removeOracle,
1002
+ secureWipe,
1003
+ secureWipeAll,
1004
+ serializeAttestationMessage,
1005
+ serializeIntent,
1006
+ serializePayment,
1007
+ signAttestationMessage,
1008
+ solanaAddressToEd25519PublicKey,
1009
+ solanaPublicKeyToHex,
1010
+ subtractBlindings,
1011
+ subtractCommitments,
1012
+ supportsSharedArrayBuffer,
1013
+ supportsViewingKey,
1014
+ supportsWebBluetooth,
1015
+ supportsWebHID,
1016
+ supportsWebUSB,
1017
+ supportsWebWorkers,
1018
+ toHex,
1019
+ toStablecoinUnits,
1020
+ trackIntent,
1021
+ trackPayment,
1022
+ updateOracleStatus,
1023
+ validateAsset,
1024
+ validateCreateIntentParams,
1025
+ validateIntentInput,
1026
+ validateIntentOutput,
1027
+ validateScalar,
1028
+ validateViewingKey,
1029
+ verifyAttestation,
1030
+ verifyCommitment,
1031
+ verifyOpening,
1032
+ verifyOracleSignature,
1033
+ walletRegistry,
1034
+ withSecureBuffer,
1035
+ withSecureBufferSync,
1036
+ wrapError
1037
+ };