@sip-protocol/sdk 0.6.5 → 0.6.8
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/dist/browser.d.mts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +277 -245
- package/dist/browser.mjs +274 -242
- package/dist/chunk-25QRORO4.mjs +17031 -0
- package/dist/chunk-3INS3PR5.mjs +884 -0
- package/dist/index-CLgrUxac.d.mts +11340 -0
- package/dist/index-Dm5Sdjkd.d.ts +11340 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/proofs/noir.js +6 -6
- package/dist/proofs/noir.mjs +5 -5
- package/package.json +1 -1
- package/src/proofs/browser.ts +324 -277
- package/src/proofs/circuits/funding_proof.json +1 -1
- package/src/proofs/mock.ts +2 -2
- package/src/proofs/noir.ts +7 -5
- package/src/proofs/worker.ts +5 -3
package/dist/browser.mjs
CHANGED
|
@@ -263,12 +263,12 @@ import {
|
|
|
263
263
|
walletRegistry,
|
|
264
264
|
withSecureBuffer,
|
|
265
265
|
withSecureBufferSync
|
|
266
|
-
} from "./chunk-
|
|
266
|
+
} from "./chunk-25QRORO4.mjs";
|
|
267
267
|
import {
|
|
268
268
|
fulfillment_proof_default,
|
|
269
269
|
funding_proof_default,
|
|
270
270
|
validity_proof_default
|
|
271
|
-
} from "./chunk-
|
|
271
|
+
} from "./chunk-3INS3PR5.mjs";
|
|
272
272
|
import {
|
|
273
273
|
CryptoError,
|
|
274
274
|
EncryptionNotImplementedError,
|
|
@@ -305,6 +305,8 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
|
|
|
305
305
|
validityBackend = null;
|
|
306
306
|
fulfillmentNoir = null;
|
|
307
307
|
fulfillmentBackend = null;
|
|
308
|
+
// Mutex for WASM operations (prevents BorrowMutError from concurrent access)
|
|
309
|
+
wasmMutex = Promise.resolve();
|
|
308
310
|
// Worker instance (optional)
|
|
309
311
|
worker = null;
|
|
310
312
|
workerPending = /* @__PURE__ */ new Map();
|
|
@@ -604,57 +606,59 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
|
|
|
604
606
|
if (!this.fundingNoir || !this.fundingBackend) {
|
|
605
607
|
throw new ProofGenerationError("funding", "Funding circuit not initialized");
|
|
606
608
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
609
|
+
return this.acquireWasmLock(async () => {
|
|
610
|
+
try {
|
|
611
|
+
onProgress?.({
|
|
612
|
+
stage: "witness",
|
|
613
|
+
percent: 10,
|
|
614
|
+
message: "Preparing witness inputs..."
|
|
615
|
+
});
|
|
616
|
+
const blindingField = this.bytesToField(params.blindingFactor);
|
|
617
|
+
const witnessInputs = {
|
|
618
|
+
minimum_required: `0x${params.minimumRequired.toString(16)}`,
|
|
619
|
+
asset_id: `0x${this.assetIdToField(params.assetId)}`,
|
|
620
|
+
balance: `0x${params.balance.toString(16)}`,
|
|
621
|
+
blinding: blindingField
|
|
622
|
+
};
|
|
623
|
+
onProgress?.({
|
|
624
|
+
stage: "witness",
|
|
625
|
+
percent: 30,
|
|
626
|
+
message: "Generating witness..."
|
|
627
|
+
});
|
|
628
|
+
const { witness, returnValue } = await this.fundingNoir.execute(witnessInputs);
|
|
629
|
+
onProgress?.({
|
|
630
|
+
stage: "proving",
|
|
631
|
+
percent: 50,
|
|
632
|
+
message: "Generating proof (this may take a moment)..."
|
|
633
|
+
});
|
|
634
|
+
const proofData = await this.fundingBackend.generateProof(witness);
|
|
635
|
+
onProgress?.({
|
|
636
|
+
stage: "complete",
|
|
637
|
+
percent: 100,
|
|
638
|
+
message: "Proof generated successfully"
|
|
639
|
+
});
|
|
640
|
+
const commitmentHashBytes = returnValue;
|
|
641
|
+
const commitmentHashHex = bytesToHex(new Uint8Array(commitmentHashBytes));
|
|
642
|
+
const publicInputs = [
|
|
643
|
+
`0x${params.minimumRequired.toString(16).padStart(64, "0")}`,
|
|
644
|
+
`0x${this.assetIdToField(params.assetId)}`,
|
|
645
|
+
`0x${commitmentHashHex}`
|
|
646
|
+
];
|
|
647
|
+
const proof = {
|
|
648
|
+
type: "funding",
|
|
649
|
+
proof: `0x${bytesToHex(proofData.proof)}`,
|
|
650
|
+
publicInputs
|
|
651
|
+
};
|
|
652
|
+
return { proof, publicInputs };
|
|
653
|
+
} catch (error) {
|
|
654
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
655
|
+
throw new ProofGenerationError(
|
|
656
|
+
"funding",
|
|
657
|
+
`Failed to generate funding proof: ${message}`,
|
|
658
|
+
error instanceof Error ? error : void 0
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
});
|
|
658
662
|
}
|
|
659
663
|
/**
|
|
660
664
|
* Generate a Validity Proof
|
|
@@ -666,89 +670,91 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
|
|
|
666
670
|
if (!this.validityNoir || !this.validityBackend) {
|
|
667
671
|
throw new ProofGenerationError("validity", "Validity circuit not initialized");
|
|
668
672
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
673
|
+
return this.acquireWasmLock(async () => {
|
|
674
|
+
try {
|
|
675
|
+
onProgress?.({
|
|
676
|
+
stage: "witness",
|
|
677
|
+
percent: 10,
|
|
678
|
+
message: "Preparing validity witness..."
|
|
679
|
+
});
|
|
680
|
+
const intentHashField = this.hexToField(params.intentHash);
|
|
681
|
+
const senderAddressField = this.hexToField(params.senderAddress);
|
|
682
|
+
const senderBlindingField = this.bytesToField(params.senderBlinding);
|
|
683
|
+
const senderSecretField = this.bytesToField(params.senderSecret);
|
|
684
|
+
const nonceField = this.bytesToField(params.nonce);
|
|
685
|
+
const { commitmentX, commitmentY } = await this.computeSenderCommitment(
|
|
686
|
+
senderAddressField,
|
|
687
|
+
senderBlindingField
|
|
688
|
+
);
|
|
689
|
+
const nullifier = await this.computeNullifier(senderSecretField, intentHashField, nonceField);
|
|
690
|
+
const signature = Array.from(params.authorizationSignature);
|
|
691
|
+
const messageHash = this.fieldToBytes32(intentHashField);
|
|
692
|
+
let pubKeyX;
|
|
693
|
+
let pubKeyY;
|
|
694
|
+
if (params.senderPublicKey) {
|
|
695
|
+
pubKeyX = Array.from(params.senderPublicKey.x);
|
|
696
|
+
pubKeyY = Array.from(params.senderPublicKey.y);
|
|
697
|
+
} else {
|
|
698
|
+
const coords = this.getPublicKeyCoordinates(params.senderSecret);
|
|
699
|
+
pubKeyX = coords.x;
|
|
700
|
+
pubKeyY = coords.y;
|
|
701
|
+
}
|
|
702
|
+
const witnessInputs = {
|
|
703
|
+
intent_hash: intentHashField,
|
|
704
|
+
sender_commitment_x: commitmentX,
|
|
705
|
+
sender_commitment_y: commitmentY,
|
|
706
|
+
nullifier,
|
|
707
|
+
timestamp: params.timestamp.toString(),
|
|
708
|
+
expiry: params.expiry.toString(),
|
|
709
|
+
sender_address: senderAddressField,
|
|
710
|
+
sender_blinding: senderBlindingField,
|
|
711
|
+
sender_secret: senderSecretField,
|
|
712
|
+
pub_key_x: pubKeyX,
|
|
713
|
+
pub_key_y: pubKeyY,
|
|
714
|
+
signature,
|
|
715
|
+
message_hash: messageHash,
|
|
716
|
+
nonce: nonceField
|
|
717
|
+
};
|
|
718
|
+
onProgress?.({
|
|
719
|
+
stage: "witness",
|
|
720
|
+
percent: 30,
|
|
721
|
+
message: "Generating witness..."
|
|
722
|
+
});
|
|
723
|
+
const { witness } = await this.validityNoir.execute(witnessInputs);
|
|
724
|
+
onProgress?.({
|
|
725
|
+
stage: "proving",
|
|
726
|
+
percent: 50,
|
|
727
|
+
message: "Generating validity proof..."
|
|
728
|
+
});
|
|
729
|
+
const proofData = await this.validityBackend.generateProof(witness);
|
|
730
|
+
onProgress?.({
|
|
731
|
+
stage: "complete",
|
|
732
|
+
percent: 100,
|
|
733
|
+
message: "Validity proof generated"
|
|
734
|
+
});
|
|
735
|
+
const publicInputs = [
|
|
736
|
+
`0x${intentHashField}`,
|
|
737
|
+
`0x${commitmentX}`,
|
|
738
|
+
`0x${commitmentY}`,
|
|
739
|
+
`0x${nullifier}`,
|
|
740
|
+
`0x${params.timestamp.toString(16).padStart(16, "0")}`,
|
|
741
|
+
`0x${params.expiry.toString(16).padStart(16, "0")}`
|
|
742
|
+
];
|
|
743
|
+
const proof = {
|
|
744
|
+
type: "validity",
|
|
745
|
+
proof: `0x${bytesToHex(proofData.proof)}`,
|
|
746
|
+
publicInputs
|
|
747
|
+
};
|
|
748
|
+
return { proof, publicInputs };
|
|
749
|
+
} catch (error) {
|
|
750
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
751
|
+
throw new ProofGenerationError(
|
|
752
|
+
"validity",
|
|
753
|
+
`Failed to generate validity proof: ${message}`,
|
|
754
|
+
error instanceof Error ? error : void 0
|
|
755
|
+
);
|
|
696
756
|
}
|
|
697
|
-
|
|
698
|
-
intent_hash: intentHashField,
|
|
699
|
-
sender_commitment_x: commitmentX,
|
|
700
|
-
sender_commitment_y: commitmentY,
|
|
701
|
-
nullifier,
|
|
702
|
-
timestamp: params.timestamp.toString(),
|
|
703
|
-
expiry: params.expiry.toString(),
|
|
704
|
-
sender_address: senderAddressField,
|
|
705
|
-
sender_blinding: senderBlindingField,
|
|
706
|
-
sender_secret: senderSecretField,
|
|
707
|
-
pub_key_x: pubKeyX,
|
|
708
|
-
pub_key_y: pubKeyY,
|
|
709
|
-
signature,
|
|
710
|
-
message_hash: messageHash,
|
|
711
|
-
nonce: nonceField
|
|
712
|
-
};
|
|
713
|
-
onProgress?.({
|
|
714
|
-
stage: "witness",
|
|
715
|
-
percent: 30,
|
|
716
|
-
message: "Generating witness..."
|
|
717
|
-
});
|
|
718
|
-
const { witness } = await this.validityNoir.execute(witnessInputs);
|
|
719
|
-
onProgress?.({
|
|
720
|
-
stage: "proving",
|
|
721
|
-
percent: 50,
|
|
722
|
-
message: "Generating validity proof..."
|
|
723
|
-
});
|
|
724
|
-
const proofData = await this.validityBackend.generateProof(witness);
|
|
725
|
-
onProgress?.({
|
|
726
|
-
stage: "complete",
|
|
727
|
-
percent: 100,
|
|
728
|
-
message: "Validity proof generated"
|
|
729
|
-
});
|
|
730
|
-
const publicInputs = [
|
|
731
|
-
`0x${intentHashField}`,
|
|
732
|
-
`0x${commitmentX}`,
|
|
733
|
-
`0x${commitmentY}`,
|
|
734
|
-
`0x${nullifier}`,
|
|
735
|
-
`0x${params.timestamp.toString(16).padStart(16, "0")}`,
|
|
736
|
-
`0x${params.expiry.toString(16).padStart(16, "0")}`
|
|
737
|
-
];
|
|
738
|
-
const proof = {
|
|
739
|
-
type: "validity",
|
|
740
|
-
proof: `0x${bytesToHex(proofData.proof)}`,
|
|
741
|
-
publicInputs
|
|
742
|
-
};
|
|
743
|
-
return { proof, publicInputs };
|
|
744
|
-
} catch (error) {
|
|
745
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
746
|
-
throw new ProofGenerationError(
|
|
747
|
-
"validity",
|
|
748
|
-
`Failed to generate validity proof: ${message}`,
|
|
749
|
-
error instanceof Error ? error : void 0
|
|
750
|
-
);
|
|
751
|
-
}
|
|
757
|
+
});
|
|
752
758
|
}
|
|
753
759
|
/**
|
|
754
760
|
* Generate a Fulfillment Proof
|
|
@@ -760,95 +766,97 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
|
|
|
760
766
|
if (!this.fulfillmentNoir || !this.fulfillmentBackend) {
|
|
761
767
|
throw new ProofGenerationError("fulfillment", "Fulfillment circuit not initialized");
|
|
762
768
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
769
|
+
return this.acquireWasmLock(async () => {
|
|
770
|
+
try {
|
|
771
|
+
onProgress?.({
|
|
772
|
+
stage: "witness",
|
|
773
|
+
percent: 10,
|
|
774
|
+
message: "Preparing fulfillment witness..."
|
|
775
|
+
});
|
|
776
|
+
const intentHashField = this.hexToField(params.intentHash);
|
|
777
|
+
const recipientStealthField = this.hexToField(params.recipientStealth);
|
|
778
|
+
const { commitmentX, commitmentY } = await this.computeOutputCommitment(
|
|
779
|
+
params.outputAmount,
|
|
780
|
+
params.outputBlinding
|
|
781
|
+
);
|
|
782
|
+
const solverSecretField = this.bytesToField(params.solverSecret);
|
|
783
|
+
const solverId = await this.computeSolverId(solverSecretField);
|
|
784
|
+
const outputBlindingField = this.bytesToField(params.outputBlinding);
|
|
785
|
+
const attestation = params.oracleAttestation;
|
|
786
|
+
const attestationRecipientField = this.hexToField(attestation.recipient);
|
|
787
|
+
const attestationTxHashField = this.hexToField(attestation.txHash);
|
|
788
|
+
const oracleSignature = Array.from(attestation.signature);
|
|
789
|
+
const oracleMessageHash = await this.computeOracleMessageHash(
|
|
790
|
+
attestation.recipient,
|
|
791
|
+
attestation.amount,
|
|
792
|
+
attestation.txHash,
|
|
793
|
+
attestation.blockNumber
|
|
794
|
+
);
|
|
795
|
+
const oraclePubKeyX = this.config.oraclePublicKey?.x ?? new Array(32).fill(0);
|
|
796
|
+
const oraclePubKeyY = this.config.oraclePublicKey?.y ?? new Array(32).fill(0);
|
|
797
|
+
const witnessInputs = {
|
|
798
|
+
intent_hash: intentHashField,
|
|
799
|
+
output_commitment_x: commitmentX,
|
|
800
|
+
output_commitment_y: commitmentY,
|
|
801
|
+
recipient_stealth: recipientStealthField,
|
|
802
|
+
min_output_amount: params.minOutputAmount.toString(),
|
|
803
|
+
solver_id: solverId,
|
|
804
|
+
fulfillment_time: params.fulfillmentTime.toString(),
|
|
805
|
+
expiry: params.expiry.toString(),
|
|
806
|
+
output_amount: params.outputAmount.toString(),
|
|
807
|
+
output_blinding: outputBlindingField,
|
|
808
|
+
solver_secret: solverSecretField,
|
|
809
|
+
attestation_recipient: attestationRecipientField,
|
|
810
|
+
attestation_amount: attestation.amount.toString(),
|
|
811
|
+
attestation_tx_hash: attestationTxHashField,
|
|
812
|
+
attestation_block: attestation.blockNumber.toString(),
|
|
813
|
+
oracle_signature: oracleSignature,
|
|
814
|
+
oracle_message_hash: oracleMessageHash,
|
|
815
|
+
oracle_pub_key_x: oraclePubKeyX,
|
|
816
|
+
oracle_pub_key_y: oraclePubKeyY
|
|
817
|
+
};
|
|
818
|
+
onProgress?.({
|
|
819
|
+
stage: "witness",
|
|
820
|
+
percent: 30,
|
|
821
|
+
message: "Generating witness..."
|
|
822
|
+
});
|
|
823
|
+
const { witness } = await this.fulfillmentNoir.execute(witnessInputs);
|
|
824
|
+
onProgress?.({
|
|
825
|
+
stage: "proving",
|
|
826
|
+
percent: 50,
|
|
827
|
+
message: "Generating fulfillment proof..."
|
|
828
|
+
});
|
|
829
|
+
const proofData = await this.fulfillmentBackend.generateProof(witness);
|
|
830
|
+
onProgress?.({
|
|
831
|
+
stage: "complete",
|
|
832
|
+
percent: 100,
|
|
833
|
+
message: "Fulfillment proof generated"
|
|
834
|
+
});
|
|
835
|
+
const publicInputs = [
|
|
836
|
+
`0x${intentHashField}`,
|
|
837
|
+
`0x${commitmentX}`,
|
|
838
|
+
`0x${commitmentY}`,
|
|
839
|
+
`0x${recipientStealthField}`,
|
|
840
|
+
`0x${params.minOutputAmount.toString(16).padStart(16, "0")}`,
|
|
841
|
+
`0x${solverId}`,
|
|
842
|
+
`0x${params.fulfillmentTime.toString(16).padStart(16, "0")}`,
|
|
843
|
+
`0x${params.expiry.toString(16).padStart(16, "0")}`
|
|
844
|
+
];
|
|
845
|
+
const proof = {
|
|
846
|
+
type: "fulfillment",
|
|
847
|
+
proof: `0x${bytesToHex(proofData.proof)}`,
|
|
848
|
+
publicInputs
|
|
849
|
+
};
|
|
850
|
+
return { proof, publicInputs };
|
|
851
|
+
} catch (error) {
|
|
852
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
853
|
+
throw new ProofGenerationError(
|
|
854
|
+
"fulfillment",
|
|
855
|
+
`Failed to generate fulfillment proof: ${message}`,
|
|
856
|
+
error instanceof Error ? error : void 0
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
});
|
|
852
860
|
}
|
|
853
861
|
/**
|
|
854
862
|
* Verify a proof
|
|
@@ -875,22 +883,25 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
|
|
|
875
883
|
"SIP_4004" /* PROOF_PROVIDER_NOT_READY */
|
|
876
884
|
);
|
|
877
885
|
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
886
|
+
const backendToUse = backend;
|
|
887
|
+
return this.acquireWasmLock(async () => {
|
|
888
|
+
try {
|
|
889
|
+
const proofHex = proof.proof.startsWith("0x") ? proof.proof.slice(2) : proof.proof;
|
|
890
|
+
const proofBytes = hexToBytes(proofHex);
|
|
891
|
+
const isValid = await backendToUse.verifyProof({
|
|
892
|
+
proof: proofBytes,
|
|
893
|
+
publicInputs: proof.publicInputs.map(
|
|
894
|
+
(input) => input.startsWith("0x") ? input.slice(2) : input
|
|
895
|
+
)
|
|
896
|
+
});
|
|
897
|
+
return isValid;
|
|
898
|
+
} catch (error) {
|
|
899
|
+
if (this.config.verbose) {
|
|
900
|
+
console.error("[BrowserNoirProvider] Verification error:", error);
|
|
901
|
+
}
|
|
902
|
+
return false;
|
|
891
903
|
}
|
|
892
|
-
|
|
893
|
-
}
|
|
904
|
+
});
|
|
894
905
|
}
|
|
895
906
|
/**
|
|
896
907
|
* Destroy the provider and free resources
|
|
@@ -918,6 +929,25 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
|
|
|
918
929
|
this._isReady = false;
|
|
919
930
|
}
|
|
920
931
|
// ─── Private Utility Methods ────────────────────────────────────────────────
|
|
932
|
+
/**
|
|
933
|
+
* Acquire WASM mutex lock for exclusive access
|
|
934
|
+
*
|
|
935
|
+
* The ACVM WASM module uses Rust RefCell internally which panics on
|
|
936
|
+
* concurrent mutable borrows. This mutex ensures serial execution.
|
|
937
|
+
*/
|
|
938
|
+
async acquireWasmLock(operation) {
|
|
939
|
+
const previousLock = this.wasmMutex;
|
|
940
|
+
let releaseLock;
|
|
941
|
+
this.wasmMutex = new Promise((resolve) => {
|
|
942
|
+
releaseLock = resolve;
|
|
943
|
+
});
|
|
944
|
+
try {
|
|
945
|
+
await previousLock;
|
|
946
|
+
return await operation();
|
|
947
|
+
} finally {
|
|
948
|
+
releaseLock();
|
|
949
|
+
}
|
|
950
|
+
}
|
|
921
951
|
ensureReady() {
|
|
922
952
|
if (!this._isReady) {
|
|
923
953
|
throw new ProofError(
|
|
@@ -1139,10 +1169,11 @@ function createWorkerBlobURL() {
|
|
|
1139
1169
|
// Convert blinding factor to field
|
|
1140
1170
|
const blindingField = bytesToField(params.blindingFactor);
|
|
1141
1171
|
|
|
1172
|
+
// Circuit uses Field type for unlimited precision
|
|
1142
1173
|
const witnessInputs = {
|
|
1143
|
-
minimum_required: params.minimumRequired.toString(),
|
|
1174
|
+
minimum_required: '0x' + params.minimumRequired.toString(16),
|
|
1144
1175
|
asset_id: '0x' + assetIdToField(params.assetId),
|
|
1145
|
-
balance: params.balance.toString(),
|
|
1176
|
+
balance: '0x' + params.balance.toString(16),
|
|
1146
1177
|
blinding: blindingField,
|
|
1147
1178
|
};
|
|
1148
1179
|
|
|
@@ -1157,8 +1188,9 @@ function createWorkerBlobURL() {
|
|
|
1157
1188
|
// Extract commitment hash from return value
|
|
1158
1189
|
const commitmentHashHex = bytesToHex(new Uint8Array(returnValue));
|
|
1159
1190
|
|
|
1191
|
+
// Field values padded to 64 hex chars (32 bytes)
|
|
1160
1192
|
const publicInputs = [
|
|
1161
|
-
'0x' + params.minimumRequired.toString(16).padStart(
|
|
1193
|
+
'0x' + params.minimumRequired.toString(16).padStart(64, '0'),
|
|
1162
1194
|
'0x' + assetIdToField(params.assetId),
|
|
1163
1195
|
'0x' + commitmentHashHex,
|
|
1164
1196
|
];
|