@sip-protocol/sdk 0.2.9 → 0.3.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.
Files changed (42) hide show
  1. package/dist/browser.d.mts +100 -2
  2. package/dist/browser.d.ts +100 -2
  3. package/dist/browser.js +2116 -321
  4. package/dist/browser.mjs +516 -16
  5. package/dist/chunk-4IFOPYJF.mjs +11950 -0
  6. package/dist/chunk-7IMRM7LN.mjs +12149 -0
  7. package/dist/chunk-JNNXNTSS.mjs +11034 -0
  8. package/dist/chunk-W3YXIQ7L.mjs +11950 -0
  9. package/dist/chunk-XLEPIR2P.mjs +884 -0
  10. package/dist/index-Ba7njCU3.d.ts +6925 -0
  11. package/dist/index-Co26-vbG.d.mts +6925 -0
  12. package/dist/index-DqZoHYKI.d.mts +6418 -0
  13. package/dist/index-dTtK_DTl.d.ts +6762 -0
  14. package/dist/index-jnkYu-Z4.d.mts +6762 -0
  15. package/dist/index-vB1N1mHd.d.ts +6418 -0
  16. package/dist/index.d.mts +2 -5897
  17. package/dist/index.d.ts +2 -5897
  18. package/dist/index.js +1334 -199
  19. package/dist/index.mjs +19 -1
  20. package/dist/noir-BTyLXLlZ.d.mts +467 -0
  21. package/dist/noir-BTyLXLlZ.d.ts +467 -0
  22. package/dist/proofs/noir.d.mts +1 -1
  23. package/dist/proofs/noir.d.ts +1 -1
  24. package/dist/proofs/noir.js +11 -112
  25. package/dist/proofs/noir.mjs +10 -13
  26. package/package.json +3 -3
  27. package/src/browser.ts +23 -0
  28. package/src/index.ts +32 -0
  29. package/src/proofs/browser-utils.ts +389 -0
  30. package/src/proofs/browser.ts +246 -19
  31. package/src/proofs/circuits/funding_proof.json +1 -1
  32. package/src/proofs/noir.ts +14 -14
  33. package/src/proofs/worker.ts +426 -0
  34. package/src/settlement/README.md +439 -0
  35. package/src/settlement/backends/direct-chain.ts +569 -0
  36. package/src/settlement/backends/index.ts +22 -0
  37. package/src/settlement/backends/near-intents.ts +480 -0
  38. package/src/settlement/backends/zcash-native.ts +516 -0
  39. package/src/settlement/index.ts +47 -0
  40. package/src/settlement/interface.ts +397 -0
  41. package/src/settlement/registry.ts +269 -0
  42. package/src/settlement/router.ts +383 -0
package/dist/browser.js CHANGED
@@ -47,7 +47,7 @@ __export(browser_exports, {
47
47
  HardwareWalletError: () => HardwareWalletError,
48
48
  IntentBuilder: () => IntentBuilder,
49
49
  IntentError: () => IntentError,
50
- IntentStatus: () => import_types34.IntentStatus,
50
+ IntentStatus: () => import_types37.IntentStatus,
51
51
  LedgerWalletAdapter: () => LedgerWalletAdapter,
52
52
  MockEthereumAdapter: () => MockEthereumAdapter,
53
53
  MockLedgerAdapter: () => MockLedgerAdapter,
@@ -56,36 +56,43 @@ __export(browser_exports, {
56
56
  MockSolver: () => MockSolver,
57
57
  MockTrezorAdapter: () => MockTrezorAdapter,
58
58
  MockWalletAdapter: () => MockWalletAdapter,
59
- NATIVE_TOKENS: () => import_types34.NATIVE_TOKENS,
59
+ NATIVE_TOKENS: () => import_types37.NATIVE_TOKENS,
60
60
  NEARIntentsAdapter: () => NEARIntentsAdapter,
61
+ NEARIntentsBackend: () => NEARIntentsBackend,
61
62
  NetworkError: () => NetworkError,
62
63
  ORACLE_DOMAIN: () => ORACLE_DOMAIN,
63
64
  OneClickClient: () => OneClickClient,
64
- OneClickDepositMode: () => import_types38.OneClickDepositMode,
65
- OneClickErrorCode: () => import_types38.OneClickErrorCode,
66
- OneClickSwapStatus: () => import_types38.OneClickSwapStatus,
67
- OneClickSwapType: () => import_types38.OneClickSwapType,
65
+ OneClickDepositMode: () => import_types41.OneClickDepositMode,
66
+ OneClickErrorCode: () => import_types41.OneClickErrorCode,
67
+ OneClickSwapStatus: () => import_types41.OneClickSwapStatus,
68
+ OneClickSwapType: () => import_types41.OneClickSwapType,
68
69
  PaymentBuilder: () => PaymentBuilder,
69
- PaymentStatus: () => import_types35.PaymentStatus,
70
- PrivacyLevel: () => import_types34.PrivacyLevel,
70
+ PaymentStatus: () => import_types38.PaymentStatus,
71
+ PrivacyLevel: () => import_types37.PrivacyLevel,
71
72
  ProofError: () => ProofError,
72
73
  ProofGenerationError: () => ProofGenerationError,
73
74
  ProofNotImplementedError: () => ProofNotImplementedError,
74
- ProposalStatus: () => import_types36.ProposalStatus,
75
- ReportStatus: () => import_types37.ReportStatus,
75
+ ProofWorker: () => ProofWorker,
76
+ ProposalStatus: () => import_types39.ProposalStatus,
77
+ ReportStatus: () => import_types40.ReportStatus,
76
78
  SIP: () => SIP,
77
79
  SIPError: () => SIPError,
78
- SIP_VERSION: () => import_types34.SIP_VERSION,
80
+ SIP_VERSION: () => import_types37.SIP_VERSION,
79
81
  STABLECOIN_ADDRESSES: () => STABLECOIN_ADDRESSES,
80
82
  STABLECOIN_DECIMALS: () => STABLECOIN_DECIMALS,
81
83
  STABLECOIN_INFO: () => STABLECOIN_INFO,
84
+ SettlementRegistry: () => SettlementRegistry,
85
+ SettlementRegistryError: () => SettlementRegistryError,
86
+ SmartRouter: () => SmartRouter,
82
87
  SolanaWalletAdapter: () => SolanaWalletAdapter,
88
+ SwapStatus: () => SwapStatus,
83
89
  Treasury: () => Treasury,
84
90
  TrezorWalletAdapter: () => TrezorWalletAdapter,
85
91
  ValidationError: () => ValidationError,
86
92
  WalletError: () => WalletError,
87
- WalletErrorCode: () => import_types33.WalletErrorCode,
88
- ZcashErrorCode: () => import_types39.ZcashErrorCode,
93
+ WalletErrorCode: () => import_types36.WalletErrorCode,
94
+ ZcashErrorCode: () => import_types42.ZcashErrorCode,
95
+ ZcashNativeBackend: () => ZcashNativeBackend,
89
96
  ZcashRPCClient: () => ZcashRPCClient,
90
97
  ZcashRPCError: () => ZcashRPCError,
91
98
  ZcashShieldedService: () => ZcashShieldedService,
@@ -98,6 +105,7 @@ __export(browser_exports, {
98
105
  browserBytesToHex: () => bytesToHex7,
99
106
  browserHexToBytes: () => hexToBytes5,
100
107
  checkEd25519StealthAddress: () => checkEd25519StealthAddress,
108
+ checkMobileWASMCompatibility: () => checkMobileWASMCompatibility,
101
109
  checkStealthAddress: () => checkStealthAddress,
102
110
  commit: () => commit,
103
111
  commitZero: () => commitZero,
@@ -114,15 +122,19 @@ __export(browser_exports, {
114
122
  createMockSolver: () => createMockSolver,
115
123
  createMockTrezorAdapter: () => createMockTrezorAdapter,
116
124
  createNEARIntentsAdapter: () => createNEARIntentsAdapter,
125
+ createNEARIntentsBackend: () => createNEARIntentsBackend,
117
126
  createOracleRegistry: () => createOracleRegistry,
118
127
  createProductionSIP: () => createProductionSIP,
119
128
  createSIP: () => createSIP,
120
129
  createShieldedIntent: () => createShieldedIntent,
121
130
  createShieldedPayment: () => createShieldedPayment,
131
+ createSmartRouter: () => createSmartRouter,
122
132
  createSolanaAdapter: () => createSolanaAdapter,
123
133
  createTrezorAdapter: () => createTrezorAdapter,
124
134
  createWalletFactory: () => createWalletFactory,
135
+ createWorkerBlobURL: () => createWorkerBlobURL,
125
136
  createZcashClient: () => createZcashClient,
137
+ createZcashNativeBackend: () => createZcashNativeBackend,
126
138
  createZcashShieldedService: () => createZcashShieldedService,
127
139
  createZcashSwapService: () => createZcashSwapService,
128
140
  decodeStealthMetaAddress: () => decodeStealthMetaAddress,
@@ -136,6 +148,8 @@ __export(browser_exports, {
136
148
  deserializeIntent: () => deserializeIntent,
137
149
  deserializePayment: () => deserializePayment,
138
150
  detectEthereumWallets: () => detectEthereumWallets,
151
+ detectMobileBrowser: () => detectMobileBrowser,
152
+ detectMobilePlatform: () => detectMobilePlatform,
139
153
  detectSolanaWallets: () => detectSolanaWallets,
140
154
  ed25519PublicKeyToNearAddress: () => ed25519PublicKeyToNearAddress,
141
155
  ed25519PublicKeyToSolanaAddress: () => ed25519PublicKeyToSolanaAddress,
@@ -156,6 +170,7 @@ __export(browser_exports, {
156
170
  getActiveOracles: () => getActiveOracles,
157
171
  getAvailableTransports: () => getAvailableTransports,
158
172
  getBrowserInfo: () => getBrowserInfo,
173
+ getBrowserVersion: () => getBrowserVersion,
159
174
  getChainNumericId: () => getChainNumericId,
160
175
  getChainsForStablecoin: () => getChainsForStablecoin,
161
176
  getCurveForChain: () => getCurveForChain,
@@ -165,6 +180,8 @@ __export(browser_exports, {
165
180
  getEthereumProvider: () => getEthereumProvider,
166
181
  getGenerators: () => getGenerators,
167
182
  getIntentSummary: () => getIntentSummary,
183
+ getMobileDeviceInfo: () => getMobileDeviceInfo,
184
+ getOSVersion: () => getOSVersion,
168
185
  getPaymentSummary: () => getPaymentSummary,
169
186
  getPaymentTimeRemaining: () => getPaymentTimeRemaining,
170
187
  getPrivacyConfig: () => getPrivacyConfig,
@@ -185,11 +202,12 @@ __export(browser_exports, {
185
202
  isExpired: () => isExpired,
186
203
  isNonNegativeAmount: () => isNonNegativeAmount,
187
204
  isPaymentExpired: () => isPaymentExpired,
188
- isPrivate: () => import_types34.isPrivate,
205
+ isPrivate: () => import_types37.isPrivate,
189
206
  isPrivateWalletAdapter: () => isPrivateWalletAdapter,
190
207
  isSIPError: () => isSIPError,
191
208
  isStablecoin: () => isStablecoin,
192
209
  isStablecoinOnChain: () => isStablecoinOnChain,
210
+ isTablet: () => isTablet,
193
211
  isValidAmount: () => isValidAmount,
194
212
  isValidChainId: () => isValidChainId,
195
213
  isValidCompressedPublicKey: () => isValidCompressedPublicKey,
@@ -221,7 +239,10 @@ __export(browser_exports, {
221
239
  subtractBlindings: () => subtractBlindings,
222
240
  subtractCommitments: () => subtractCommitments,
223
241
  supportsSharedArrayBuffer: () => supportsSharedArrayBuffer,
224
- supportsViewingKey: () => import_types34.supportsViewingKey,
242
+ supportsTouch: () => supportsTouch,
243
+ supportsViewingKey: () => import_types37.supportsViewingKey,
244
+ supportsWASMBulkMemory: () => supportsWASMBulkMemory,
245
+ supportsWASMSimd: () => supportsWASMSimd,
225
246
  supportsWebBluetooth: () => supportsWebBluetooth,
226
247
  supportsWebHID: () => supportsWebHID,
227
248
  supportsWebUSB: () => supportsWebUSB,
@@ -3460,6 +3481,280 @@ var MockProofProvider = class {
3460
3481
  };
3461
3482
 
3462
3483
  // src/proofs/browser-utils.ts
3484
+ function detectMobilePlatform() {
3485
+ if (typeof navigator === "undefined") return "desktop";
3486
+ const ua = navigator.userAgent.toLowerCase();
3487
+ if (/iphone|ipad|ipod/.test(ua) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) {
3488
+ return "ios";
3489
+ }
3490
+ if (/android/.test(ua)) {
3491
+ return "android";
3492
+ }
3493
+ if (/mobile|webos|blackberry|opera mini|opera mobi|iemobile|wpdesktop/.test(ua)) {
3494
+ return "other";
3495
+ }
3496
+ return "desktop";
3497
+ }
3498
+ function detectMobileBrowser() {
3499
+ if (typeof navigator === "undefined") return "other";
3500
+ const ua = navigator.userAgent.toLowerCase();
3501
+ if (/safari/.test(ua) && /iphone|ipad|ipod/.test(ua) && !/crios|fxios/.test(ua)) {
3502
+ return "safari";
3503
+ }
3504
+ if (/chrome|crios/.test(ua) && !/edg|opr|samsung/.test(ua)) {
3505
+ return "chrome";
3506
+ }
3507
+ if (/firefox|fxios/.test(ua)) {
3508
+ return "firefox";
3509
+ }
3510
+ if (/samsung/.test(ua)) {
3511
+ return "samsung";
3512
+ }
3513
+ if (/opr|opera/.test(ua)) {
3514
+ return "opera";
3515
+ }
3516
+ if (/edg/.test(ua)) {
3517
+ return "edge";
3518
+ }
3519
+ return "other";
3520
+ }
3521
+ function getBrowserVersion() {
3522
+ if (typeof navigator === "undefined") return null;
3523
+ const ua = navigator.userAgent;
3524
+ const browser = detectMobileBrowser();
3525
+ const patterns = {
3526
+ safari: /version\/(\d+(\.\d+)*)/i,
3527
+ chrome: /chrome\/(\d+(\.\d+)*)|crios\/(\d+(\.\d+)*)/i,
3528
+ firefox: /firefox\/(\d+(\.\d+)*)|fxios\/(\d+(\.\d+)*)/i,
3529
+ samsung: /samsungbrowser\/(\d+(\.\d+)*)/i,
3530
+ opera: /opr\/(\d+(\.\d+)*)/i,
3531
+ edge: /edg\/(\d+(\.\d+)*)/i,
3532
+ other: /version\/(\d+(\.\d+)*)/i
3533
+ };
3534
+ const pattern = patterns[browser] || patterns.other;
3535
+ const match = ua.match(pattern);
3536
+ if (match) {
3537
+ for (let i = 1; i < match.length; i++) {
3538
+ if (match[i]) return match[i];
3539
+ }
3540
+ }
3541
+ return null;
3542
+ }
3543
+ function getOSVersion() {
3544
+ if (typeof navigator === "undefined") return null;
3545
+ const ua = navigator.userAgent;
3546
+ const platform = detectMobilePlatform();
3547
+ if (platform === "ios") {
3548
+ const match = ua.match(/os (\d+[_\d]*)/i);
3549
+ return match ? match[1].replace(/_/g, ".") : null;
3550
+ }
3551
+ if (platform === "android") {
3552
+ const match = ua.match(/android (\d+(\.\d+)*)/i);
3553
+ return match ? match[1] : null;
3554
+ }
3555
+ return null;
3556
+ }
3557
+ function isTablet() {
3558
+ if (typeof navigator === "undefined") return false;
3559
+ const ua = navigator.userAgent.toLowerCase();
3560
+ if (/ipad/.test(ua) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) {
3561
+ return true;
3562
+ }
3563
+ if (/android/.test(ua) && !/mobile/.test(ua)) {
3564
+ return true;
3565
+ }
3566
+ return false;
3567
+ }
3568
+ function supportsTouch() {
3569
+ if (typeof window === "undefined") return false;
3570
+ return "ontouchstart" in window || navigator.maxTouchPoints > 0;
3571
+ }
3572
+ function getMobileDeviceInfo() {
3573
+ const platform = detectMobilePlatform();
3574
+ return {
3575
+ isMobile: platform !== "desktop",
3576
+ platform,
3577
+ browser: detectMobileBrowser(),
3578
+ browserVersion: getBrowserVersion(),
3579
+ osVersion: getOSVersion(),
3580
+ isTablet: isTablet(),
3581
+ supportsTouch: supportsTouch(),
3582
+ deviceMemoryGB: (
3583
+ // @ts-expect-error - deviceMemory is non-standard
3584
+ typeof navigator !== "undefined" && navigator.deviceMemory ? (
3585
+ // @ts-expect-error - deviceMemory is non-standard
3586
+ navigator.deviceMemory
3587
+ ) : null
3588
+ ),
3589
+ hardwareConcurrency: typeof navigator !== "undefined" && navigator.hardwareConcurrency ? navigator.hardwareConcurrency : null
3590
+ };
3591
+ }
3592
+ function supportsWASMSimd() {
3593
+ try {
3594
+ return WebAssembly.validate(
3595
+ new Uint8Array([
3596
+ 0,
3597
+ 97,
3598
+ 115,
3599
+ 109,
3600
+ 1,
3601
+ 0,
3602
+ 0,
3603
+ 0,
3604
+ 1,
3605
+ 5,
3606
+ 1,
3607
+ 96,
3608
+ 0,
3609
+ 1,
3610
+ 123,
3611
+ 3,
3612
+ 2,
3613
+ 1,
3614
+ 0,
3615
+ 10,
3616
+ 10,
3617
+ 1,
3618
+ 8,
3619
+ 0,
3620
+ 65,
3621
+ 0,
3622
+ 253,
3623
+ 15,
3624
+ 253,
3625
+ 98,
3626
+ 11
3627
+ ])
3628
+ );
3629
+ } catch {
3630
+ return false;
3631
+ }
3632
+ }
3633
+ function supportsWASMBulkMemory() {
3634
+ try {
3635
+ return WebAssembly.validate(
3636
+ new Uint8Array([
3637
+ 0,
3638
+ 97,
3639
+ 115,
3640
+ 109,
3641
+ 1,
3642
+ 0,
3643
+ 0,
3644
+ 0,
3645
+ 1,
3646
+ 4,
3647
+ 1,
3648
+ 96,
3649
+ 0,
3650
+ 0,
3651
+ 3,
3652
+ 2,
3653
+ 1,
3654
+ 0,
3655
+ 5,
3656
+ 3,
3657
+ 1,
3658
+ 0,
3659
+ 1,
3660
+ 10,
3661
+ 13,
3662
+ 1,
3663
+ 11,
3664
+ 0,
3665
+ 65,
3666
+ 0,
3667
+ 65,
3668
+ 0,
3669
+ 65,
3670
+ 0,
3671
+ 252,
3672
+ 11,
3673
+ 0,
3674
+ 11
3675
+ ])
3676
+ );
3677
+ } catch {
3678
+ return false;
3679
+ }
3680
+ }
3681
+ function checkMobileWASMCompatibility() {
3682
+ const issues = [];
3683
+ const recommendations = [];
3684
+ let score = 100;
3685
+ const webAssembly = typeof WebAssembly !== "undefined";
3686
+ if (!webAssembly) {
3687
+ issues.push("WebAssembly not supported");
3688
+ score -= 50;
3689
+ }
3690
+ const sharedArrayBuffer = supportsSharedArrayBuffer();
3691
+ if (!sharedArrayBuffer) {
3692
+ issues.push("SharedArrayBuffer not available (requires COOP/COEP headers)");
3693
+ recommendations.push("Server must send Cross-Origin-Opener-Policy: same-origin");
3694
+ recommendations.push("Server must send Cross-Origin-Embedder-Policy: require-corp");
3695
+ score -= 20;
3696
+ }
3697
+ const webWorkers = supportsWebWorkers();
3698
+ if (!webWorkers) {
3699
+ issues.push("Web Workers not supported");
3700
+ recommendations.push("Consider using a polyfill or fallback to main-thread execution");
3701
+ score -= 15;
3702
+ }
3703
+ const simd = supportsWASMSimd();
3704
+ if (!simd) {
3705
+ recommendations.push("WASM SIMD not supported - proofs will be slower");
3706
+ score -= 5;
3707
+ }
3708
+ const bulkMemory = supportsWASMBulkMemory();
3709
+ if (!bulkMemory) {
3710
+ recommendations.push("WASM bulk memory not supported - may affect performance");
3711
+ score -= 5;
3712
+ }
3713
+ const bigInt = typeof BigInt !== "undefined";
3714
+ if (!bigInt) {
3715
+ issues.push("BigInt not supported (required for 64-bit operations)");
3716
+ score -= 10;
3717
+ }
3718
+ const deviceInfo = getMobileDeviceInfo();
3719
+ if (deviceInfo.isMobile) {
3720
+ if (deviceInfo.deviceMemoryGB !== null && deviceInfo.deviceMemoryGB < 2) {
3721
+ recommendations.push(`Low device memory (${deviceInfo.deviceMemoryGB}GB) - may experience issues with large proofs`);
3722
+ score -= 5;
3723
+ }
3724
+ if (deviceInfo.platform === "ios" && deviceInfo.browser === "safari") {
3725
+ if (!sharedArrayBuffer) {
3726
+ recommendations.push("iOS Safari requires iOS 15.2+ for SharedArrayBuffer support");
3727
+ }
3728
+ }
3729
+ if (deviceInfo.platform === "android" && deviceInfo.browser === "chrome") {
3730
+ if (!sharedArrayBuffer) {
3731
+ recommendations.push("Ensure COOP/COEP headers are set - Chrome Android requires them");
3732
+ }
3733
+ }
3734
+ }
3735
+ let summary;
3736
+ if (score >= 90) {
3737
+ summary = "Excellent - Full WASM proof support";
3738
+ } else if (score >= 70) {
3739
+ summary = "Good - WASM proofs supported with minor limitations";
3740
+ } else if (score >= 50) {
3741
+ summary = "Limited - WASM proofs may work with reduced performance";
3742
+ } else {
3743
+ summary = "Poor - WASM proofs not recommended on this device";
3744
+ }
3745
+ return {
3746
+ webAssembly,
3747
+ sharedArrayBuffer,
3748
+ webWorkers,
3749
+ simd,
3750
+ bulkMemory,
3751
+ bigInt,
3752
+ score: Math.max(0, score),
3753
+ summary,
3754
+ issues,
3755
+ recommendations
3756
+ };
3757
+ }
3463
3758
  function hexToBytes5(hex) {
3464
3759
  const h = hex.startsWith("0x") ? hex.slice(2) : hex;
3465
3760
  if (h.length === 0) return new Uint8Array(0);
@@ -3775,10 +4070,10 @@ function hasEnoughOracles(registry) {
3775
4070
  }
3776
4071
 
3777
4072
  // src/index.ts
3778
- var import_types34 = require("@sip-protocol/types");
3779
- var import_types35 = require("@sip-protocol/types");
3780
- var import_types36 = require("@sip-protocol/types");
3781
4073
  var import_types37 = require("@sip-protocol/types");
4074
+ var import_types38 = require("@sip-protocol/types");
4075
+ var import_types39 = require("@sip-protocol/types");
4076
+ var import_types40 = require("@sip-protocol/types");
3782
4077
 
3783
4078
  // src/solver/mock-solver.ts
3784
4079
  var import_types7 = require("@sip-protocol/types");
@@ -3948,25 +4243,1142 @@ var MockSolver = class {
3948
4243
  async getStatus(intentId) {
3949
4244
  return this.pendingFulfillments.get(intentId) ?? null;
3950
4245
  }
3951
- /**
3952
- * Reset solver state (for testing)
3953
- */
3954
- reset() {
3955
- this.pendingFulfillments.clear();
4246
+ /**
4247
+ * Reset solver state (for testing)
4248
+ */
4249
+ reset() {
4250
+ this.pendingFulfillments.clear();
4251
+ }
4252
+ delay(ms) {
4253
+ return new Promise((resolve) => setTimeout(resolve, ms));
4254
+ }
4255
+ };
4256
+ function createMockSolver(config) {
4257
+ return new MockSolver(config);
4258
+ }
4259
+
4260
+ // src/index.ts
4261
+ var import_types41 = require("@sip-protocol/types");
4262
+
4263
+ // src/settlement/interface.ts
4264
+ var SwapStatus = /* @__PURE__ */ ((SwapStatus2) => {
4265
+ SwapStatus2["PENDING_DEPOSIT"] = "pending_deposit";
4266
+ SwapStatus2["DEPOSIT_CONFIRMED"] = "deposit_confirmed";
4267
+ SwapStatus2["IN_PROGRESS"] = "in_progress";
4268
+ SwapStatus2["SUCCESS"] = "success";
4269
+ SwapStatus2["FAILED"] = "failed";
4270
+ SwapStatus2["CANCELLED"] = "cancelled";
4271
+ SwapStatus2["REFUNDING"] = "refunding";
4272
+ SwapStatus2["REFUNDED"] = "refunded";
4273
+ return SwapStatus2;
4274
+ })(SwapStatus || {});
4275
+
4276
+ // src/settlement/registry.ts
4277
+ var SettlementRegistryError = class extends Error {
4278
+ constructor(message) {
4279
+ super(message);
4280
+ this.name = "SettlementRegistryError";
4281
+ }
4282
+ };
4283
+ var SettlementRegistry = class {
4284
+ backends = /* @__PURE__ */ new Map();
4285
+ /**
4286
+ * Register a settlement backend
4287
+ *
4288
+ * @param backend - Settlement backend to register
4289
+ * @throws {SettlementRegistryError} If backend with same name already exists
4290
+ *
4291
+ * @example
4292
+ * ```typescript
4293
+ * registry.register(nearIntentsBackend)
4294
+ * ```
4295
+ */
4296
+ register(backend) {
4297
+ if (this.backends.has(backend.name)) {
4298
+ throw new SettlementRegistryError(
4299
+ `Backend '${backend.name}' is already registered`
4300
+ );
4301
+ }
4302
+ this.backends.set(backend.name, backend);
4303
+ }
4304
+ /**
4305
+ * Get a settlement backend by name
4306
+ *
4307
+ * @param name - Backend name
4308
+ * @returns Settlement backend
4309
+ * @throws {SettlementRegistryError} If backend is not found
4310
+ *
4311
+ * @example
4312
+ * ```typescript
4313
+ * const backend = registry.get('near-intents')
4314
+ * ```
4315
+ */
4316
+ get(name) {
4317
+ const backend = this.backends.get(name);
4318
+ if (!backend) {
4319
+ throw new SettlementRegistryError(`Backend '${name}' not found`);
4320
+ }
4321
+ return backend;
4322
+ }
4323
+ /**
4324
+ * List all registered backend names
4325
+ *
4326
+ * @returns Array of backend names
4327
+ *
4328
+ * @example
4329
+ * ```typescript
4330
+ * const names = registry.list()
4331
+ * // ['near-intents', 'zcash', 'thorchain']
4332
+ * ```
4333
+ */
4334
+ list() {
4335
+ return Array.from(this.backends.keys());
4336
+ }
4337
+ /**
4338
+ * Get the best backend for a specific route
4339
+ *
4340
+ * Selection criteria (in order of priority):
4341
+ * 1. Backends that support both source and destination chains
4342
+ * 2. Backends with faster average execution time
4343
+ * 3. First registered backend (if no execution time info)
4344
+ *
4345
+ * @param fromChain - Source chain
4346
+ * @param toChain - Destination chain
4347
+ * @returns Best settlement backend for the route
4348
+ * @throws {SettlementRegistryError} If no backend supports the route
4349
+ *
4350
+ * @example
4351
+ * ```typescript
4352
+ * const backend = registry.getBestForRoute('ethereum', 'solana')
4353
+ * const quote = await backend.getQuote({ ... })
4354
+ * ```
4355
+ */
4356
+ getBestForRoute(fromChain, toChain) {
4357
+ const supportedBackends = [];
4358
+ for (const backend of Array.from(this.backends.values())) {
4359
+ const { supportedSourceChains, supportedDestinationChains } = backend.capabilities;
4360
+ const supportsSource = supportedSourceChains.includes(fromChain);
4361
+ const supportsDestination = supportedDestinationChains.includes(toChain);
4362
+ if (supportsSource && supportsDestination) {
4363
+ supportedBackends.push(backend);
4364
+ }
4365
+ }
4366
+ if (supportedBackends.length === 0) {
4367
+ throw new SettlementRegistryError(
4368
+ `No backend supports route from '${fromChain}' to '${toChain}'`
4369
+ );
4370
+ }
4371
+ if (supportedBackends.length === 1) {
4372
+ return supportedBackends[0];
4373
+ }
4374
+ supportedBackends.sort((a, b) => {
4375
+ const timeA = a.capabilities.averageExecutionTime ?? Infinity;
4376
+ const timeB = b.capabilities.averageExecutionTime ?? Infinity;
4377
+ return timeA - timeB;
4378
+ });
4379
+ return supportedBackends[0];
4380
+ }
4381
+ /**
4382
+ * Get all supported routes across all registered backends
4383
+ *
4384
+ * @returns Array of supported routes
4385
+ *
4386
+ * @example
4387
+ * ```typescript
4388
+ * const routes = registry.getSupportedRoutes()
4389
+ * // [
4390
+ * // { fromChain: 'ethereum', toChain: 'solana', backend: 'near-intents' },
4391
+ * // { fromChain: 'solana', toChain: 'ethereum', backend: 'near-intents' },
4392
+ * // { fromChain: 'ethereum', toChain: 'zcash', backend: 'zcash' },
4393
+ * // ...
4394
+ * // ]
4395
+ * ```
4396
+ */
4397
+ getSupportedRoutes() {
4398
+ const routes = [];
4399
+ for (const backend of Array.from(this.backends.values())) {
4400
+ const { supportedSourceChains, supportedDestinationChains } = backend.capabilities;
4401
+ for (const fromChain of supportedSourceChains) {
4402
+ for (const toChain of supportedDestinationChains) {
4403
+ routes.push({
4404
+ fromChain,
4405
+ toChain,
4406
+ backend: backend.name
4407
+ });
4408
+ }
4409
+ }
4410
+ }
4411
+ return routes;
4412
+ }
4413
+ /**
4414
+ * Check if a backend is registered
4415
+ *
4416
+ * @param name - Backend name
4417
+ * @returns True if backend is registered
4418
+ *
4419
+ * @example
4420
+ * ```typescript
4421
+ * if (registry.has('near-intents')) {
4422
+ * const backend = registry.get('near-intents')
4423
+ * }
4424
+ * ```
4425
+ */
4426
+ has(name) {
4427
+ return this.backends.has(name);
4428
+ }
4429
+ /**
4430
+ * Unregister a settlement backend
4431
+ *
4432
+ * @param name - Backend name to unregister
4433
+ * @returns True if backend was unregistered, false if not found
4434
+ *
4435
+ * @example
4436
+ * ```typescript
4437
+ * registry.unregister('near-intents')
4438
+ * ```
4439
+ */
4440
+ unregister(name) {
4441
+ return this.backends.delete(name);
4442
+ }
4443
+ /**
4444
+ * Clear all registered backends
4445
+ *
4446
+ * @example
4447
+ * ```typescript
4448
+ * registry.clear()
4449
+ * ```
4450
+ */
4451
+ clear() {
4452
+ this.backends.clear();
4453
+ }
4454
+ /**
4455
+ * Get number of registered backends
4456
+ *
4457
+ * @returns Number of registered backends
4458
+ *
4459
+ * @example
4460
+ * ```typescript
4461
+ * const count = registry.size()
4462
+ * ```
4463
+ */
4464
+ size() {
4465
+ return this.backends.size;
4466
+ }
4467
+ };
4468
+
4469
+ // src/settlement/router.ts
4470
+ var SmartRouter = class {
4471
+ constructor(registry) {
4472
+ this.registry = registry;
4473
+ }
4474
+ /**
4475
+ * Find best routes for a swap
4476
+ *
4477
+ * Queries all compatible backends in parallel and returns sorted routes.
4478
+ *
4479
+ * @param params - Route finding parameters
4480
+ * @returns Sorted routes (best first)
4481
+ * @throws {ValidationError} If no backends support the route
4482
+ */
4483
+ async findBestRoute(params) {
4484
+ const {
4485
+ from,
4486
+ to,
4487
+ amount,
4488
+ privacyLevel,
4489
+ preferSpeed = false,
4490
+ preferLowFees = true,
4491
+ recipientMetaAddress,
4492
+ senderAddress,
4493
+ slippageTolerance,
4494
+ deadline
4495
+ } = params;
4496
+ if (amount <= 0n) {
4497
+ throw new ValidationError("Amount must be greater than zero");
4498
+ }
4499
+ const allBackends = this.registry.list().map((name) => this.registry.get(name));
4500
+ const compatibleBackends = allBackends.filter((backend) => {
4501
+ const { supportedSourceChains, supportedDestinationChains, supportedPrivacyLevels } = backend.capabilities;
4502
+ const supportsRoute = supportedSourceChains.includes(from.chain) && supportedDestinationChains.includes(to.chain);
4503
+ const supportsPrivacy = supportedPrivacyLevels.includes(privacyLevel);
4504
+ return supportsRoute && supportsPrivacy;
4505
+ });
4506
+ if (compatibleBackends.length === 0) {
4507
+ throw new ValidationError(
4508
+ `No backend supports route from ${from.chain} to ${to.chain} with privacy level ${privacyLevel}`
4509
+ );
4510
+ }
4511
+ const quoteParams = {
4512
+ fromChain: from.chain,
4513
+ toChain: to.chain,
4514
+ fromToken: from.token,
4515
+ toToken: to.token,
4516
+ amount,
4517
+ privacyLevel,
4518
+ recipientMetaAddress,
4519
+ senderAddress,
4520
+ slippageTolerance,
4521
+ deadline
4522
+ };
4523
+ const quotePromises = compatibleBackends.map(async (backend) => {
4524
+ try {
4525
+ const quote = await backend.getQuote(quoteParams);
4526
+ return {
4527
+ backend: backend.name,
4528
+ quote,
4529
+ backendInstance: backend,
4530
+ success: true
4531
+ };
4532
+ } catch (error) {
4533
+ return {
4534
+ backend: backend.name,
4535
+ error: error instanceof Error ? error.message : "Unknown error",
4536
+ success: false
4537
+ };
4538
+ }
4539
+ });
4540
+ const results = await Promise.all(quotePromises);
4541
+ const successfulRoutes = results.filter((r) => r.success).map((r) => ({
4542
+ backend: r.backend,
4543
+ quote: r.quote,
4544
+ backendInstance: r.backendInstance,
4545
+ score: 0
4546
+ // Will be calculated below
4547
+ }));
4548
+ if (successfulRoutes.length === 0) {
4549
+ const errors = results.filter((r) => !r.success).map((r) => `${r.backend}: ${r.error}`).join(", ");
4550
+ throw new NetworkError(
4551
+ `All backends failed to provide quotes: ${errors}`
4552
+ );
4553
+ }
4554
+ this.rankRoutes(successfulRoutes, { preferSpeed, preferLowFees });
4555
+ successfulRoutes.sort((a, b) => b.score - a.score);
4556
+ return successfulRoutes;
4557
+ }
4558
+ /**
4559
+ * Compare quotes from multiple routes side-by-side
4560
+ *
4561
+ * @param routes - Routes to compare (from findBestRoute)
4562
+ * @returns Comparison with best routes by different criteria
4563
+ */
4564
+ compareQuotes(routes) {
4565
+ if (routes.length === 0) {
4566
+ return {
4567
+ routes: [],
4568
+ bestByCost: null,
4569
+ bestBySpeed: null,
4570
+ bestByPrivacy: null,
4571
+ metadata: {
4572
+ totalQueried: 0,
4573
+ failures: [],
4574
+ queriedAt: Date.now()
4575
+ }
4576
+ };
4577
+ }
4578
+ const bestByCost = [...routes].sort((a, b) => {
4579
+ const costA = this.calculateTotalCost(a.quote);
4580
+ const costB = this.calculateTotalCost(b.quote);
4581
+ return costA - costB;
4582
+ })[0];
4583
+ const bestBySpeed = [...routes].sort((a, b) => {
4584
+ const timeA = a.quote.estimatedTime ?? Infinity;
4585
+ const timeB = b.quote.estimatedTime ?? Infinity;
4586
+ return timeA - timeB;
4587
+ })[0];
4588
+ const bestByPrivacy = [...routes].find((route) => {
4589
+ const { supportedPrivacyLevels } = route.backendInstance.capabilities;
4590
+ return supportedPrivacyLevels.includes("shielded") || supportedPrivacyLevels.includes("compliant");
4591
+ }) || routes[0];
4592
+ return {
4593
+ routes,
4594
+ bestByCost,
4595
+ bestBySpeed,
4596
+ bestByPrivacy,
4597
+ metadata: {
4598
+ totalQueried: routes.length,
4599
+ failures: [],
4600
+ // Could track from findBestRoute
4601
+ queriedAt: Date.now()
4602
+ }
4603
+ };
4604
+ }
4605
+ /**
4606
+ * Rank routes by score
4607
+ *
4608
+ * Scoring algorithm:
4609
+ * - Base score: 100
4610
+ * - Cost: Lower fees = higher score (up to +50)
4611
+ * - Speed: Faster execution = higher score (up to +30)
4612
+ * - Privacy: Better privacy support = higher score (up to +20)
4613
+ *
4614
+ * @private
4615
+ */
4616
+ rankRoutes(routes, preferences) {
4617
+ const { preferSpeed, preferLowFees } = preferences;
4618
+ const costs = routes.map((r) => this.calculateTotalCost(r.quote));
4619
+ const times = routes.map((r) => r.quote.estimatedTime ?? Infinity);
4620
+ const minCost = Math.min(...costs);
4621
+ const maxCost = Math.max(...costs);
4622
+ const minTime = Math.min(...times.filter((t) => t !== Infinity));
4623
+ const maxTime = Math.max(...times.filter((t) => t !== Infinity));
4624
+ routes.forEach((route, index) => {
4625
+ let score = 100;
4626
+ if (maxCost > minCost) {
4627
+ const costNormalized = 1 - (costs[index] - minCost) / (maxCost - minCost);
4628
+ const costWeight = preferLowFees ? 50 : 30;
4629
+ score += costNormalized * costWeight;
4630
+ }
4631
+ const time = times[index];
4632
+ if (time !== Infinity && maxTime > minTime) {
4633
+ const speedNormalized = 1 - (time - minTime) / (maxTime - minTime);
4634
+ const speedWeight = preferSpeed ? 50 : 30;
4635
+ score += speedNormalized * speedWeight;
4636
+ }
4637
+ const { supportedPrivacyLevels } = route.backendInstance.capabilities;
4638
+ if (supportedPrivacyLevels.includes("shielded")) {
4639
+ score += 20;
4640
+ } else if (supportedPrivacyLevels.includes("compliant")) {
4641
+ score += 10;
4642
+ }
4643
+ route.score = score;
4644
+ });
4645
+ }
4646
+ /**
4647
+ * Calculate total cost from quote
4648
+ *
4649
+ * Returns total fee in USD if available, otherwise estimates from fees
4650
+ *
4651
+ * @private
4652
+ */
4653
+ calculateTotalCost(quote) {
4654
+ if (quote.fees.totalFeeUSD) {
4655
+ return parseFloat(quote.fees.totalFeeUSD);
4656
+ }
4657
+ const networkFee = parseFloat(quote.fees.networkFee) || 0;
4658
+ const protocolFee = parseFloat(quote.fees.protocolFee) || 0;
4659
+ return networkFee + protocolFee;
4660
+ }
4661
+ };
4662
+ function createSmartRouter(registry) {
4663
+ return new SmartRouter(registry);
4664
+ }
4665
+
4666
+ // src/settlement/backends/near-intents.ts
4667
+ var import_types8 = require("@sip-protocol/types");
4668
+ function mapOneClickStatus(status) {
4669
+ switch (status) {
4670
+ case import_types8.OneClickSwapStatus.PENDING_DEPOSIT:
4671
+ return "pending_deposit" /* PENDING_DEPOSIT */;
4672
+ case import_types8.OneClickSwapStatus.PROCESSING:
4673
+ return "in_progress" /* IN_PROGRESS */;
4674
+ case import_types8.OneClickSwapStatus.SUCCESS:
4675
+ return "success" /* SUCCESS */;
4676
+ case import_types8.OneClickSwapStatus.FAILED:
4677
+ return "failed" /* FAILED */;
4678
+ case import_types8.OneClickSwapStatus.INCOMPLETE_DEPOSIT:
4679
+ return "failed" /* FAILED */;
4680
+ case import_types8.OneClickSwapStatus.REFUNDED:
4681
+ return "refunded" /* REFUNDED */;
4682
+ default:
4683
+ return "pending_deposit" /* PENDING_DEPOSIT */;
4684
+ }
4685
+ }
4686
+ var NEARIntentsBackend = class {
4687
+ name = "near-intents";
4688
+ capabilities;
4689
+ adapter;
4690
+ quoteCache;
4691
+ constructor(config = {}) {
4692
+ this.adapter = new NEARIntentsAdapter(config);
4693
+ this.quoteCache = /* @__PURE__ */ new Map();
4694
+ this.capabilities = {
4695
+ supportedSourceChains: [
4696
+ "near",
4697
+ "ethereum",
4698
+ "solana",
4699
+ "polygon",
4700
+ "arbitrum",
4701
+ "optimism",
4702
+ "base",
4703
+ "bitcoin",
4704
+ "zcash"
4705
+ ],
4706
+ supportedDestinationChains: [
4707
+ "near",
4708
+ "ethereum",
4709
+ "solana",
4710
+ "polygon",
4711
+ "arbitrum",
4712
+ "optimism",
4713
+ "base",
4714
+ "bitcoin",
4715
+ "zcash"
4716
+ ],
4717
+ supportedPrivacyLevels: [
4718
+ import_types8.PrivacyLevel.TRANSPARENT,
4719
+ import_types8.PrivacyLevel.SHIELDED,
4720
+ import_types8.PrivacyLevel.COMPLIANT
4721
+ ],
4722
+ supportsCancellation: false,
4723
+ supportsRefunds: true,
4724
+ averageExecutionTime: 300,
4725
+ // 5 minutes
4726
+ features: ["stealth-addresses", "cross-chain", "near-intents"]
4727
+ };
4728
+ }
4729
+ /**
4730
+ * Get quote for a cross-chain swap
4731
+ */
4732
+ async getQuote(params) {
4733
+ this.validateQuoteParams(params);
4734
+ const swapRequest = {
4735
+ requestId: this.generateRequestId(),
4736
+ privacyLevel: params.privacyLevel,
4737
+ inputAsset: {
4738
+ chain: params.fromChain,
4739
+ symbol: params.fromToken,
4740
+ decimals: 0
4741
+ // Will be inferred by adapter
4742
+ },
4743
+ outputAsset: {
4744
+ chain: params.toChain,
4745
+ symbol: params.toToken,
4746
+ decimals: 0
4747
+ // Will be inferred by adapter
4748
+ },
4749
+ inputAmount: params.amount,
4750
+ minOutputAmount: params.slippageTolerance ? params.amount - params.amount * BigInt(params.slippageTolerance) / BigInt(1e4) : void 0
4751
+ };
4752
+ const prepared = await this.adapter.prepareSwap(
4753
+ swapRequest,
4754
+ params.recipientMetaAddress,
4755
+ params.senderAddress
4756
+ );
4757
+ const oneClickQuote = await this.adapter.getQuote(prepared);
4758
+ this.quoteCache.set(oneClickQuote.quoteId, params);
4759
+ const quote = {
4760
+ quoteId: oneClickQuote.quoteId,
4761
+ amountIn: oneClickQuote.amountIn,
4762
+ amountOut: oneClickQuote.amountOut,
4763
+ minAmountOut: oneClickQuote.amountOut,
4764
+ // 1Click doesn't provide separate minAmount
4765
+ fees: {
4766
+ networkFee: "0",
4767
+ // 1Click doesn't provide separate fee breakdown
4768
+ protocolFee: "0",
4769
+ totalFeeUSD: oneClickQuote.amountOutUsd
4770
+ },
4771
+ depositAddress: oneClickQuote.depositAddress,
4772
+ recipientAddress: prepared.stealthAddress?.address ?? params.senderAddress ?? "",
4773
+ refundAddress: params.senderAddress,
4774
+ expiresAt: new Date(oneClickQuote.deadline).getTime() / 1e3,
4775
+ estimatedTime: oneClickQuote.timeEstimate,
4776
+ metadata: {
4777
+ prepared,
4778
+ oneClickQuote,
4779
+ stealthAddress: prepared.stealthAddress,
4780
+ ephemeralPublicKey: prepared.stealthAddress?.ephemeralPublicKey,
4781
+ curve: prepared.curve
4782
+ }
4783
+ };
4784
+ return quote;
4785
+ }
4786
+ /**
4787
+ * Execute swap using a quote
4788
+ */
4789
+ async executeSwap(params) {
4790
+ if (!params.quoteId) {
4791
+ throw new ValidationError("quoteId is required", "quoteId");
4792
+ }
4793
+ const quoteParams = this.quoteCache.get(params.quoteId);
4794
+ if (!quoteParams) {
4795
+ throw new ValidationError(
4796
+ "Quote not found. Please call getQuote() before executeSwap()",
4797
+ "quoteId"
4798
+ );
4799
+ }
4800
+ const swapRequest = {
4801
+ requestId: this.generateRequestId(),
4802
+ privacyLevel: quoteParams.privacyLevel,
4803
+ inputAsset: {
4804
+ chain: quoteParams.fromChain,
4805
+ symbol: quoteParams.fromToken,
4806
+ decimals: 0
4807
+ },
4808
+ outputAsset: {
4809
+ chain: quoteParams.toChain,
4810
+ symbol: quoteParams.toToken,
4811
+ decimals: 0
4812
+ },
4813
+ inputAmount: quoteParams.amount
4814
+ };
4815
+ const adapterResult = await this.adapter.initiateSwap(
4816
+ swapRequest,
4817
+ quoteParams.recipientMetaAddress,
4818
+ quoteParams.senderAddress
4819
+ );
4820
+ if (params.depositTxHash) {
4821
+ await this.adapter.notifyDeposit(
4822
+ adapterResult.depositAddress,
4823
+ params.depositTxHash,
4824
+ params.nearAccount
4825
+ );
4826
+ }
4827
+ const result = {
4828
+ swapId: adapterResult.depositAddress,
4829
+ // Use deposit address as swap ID
4830
+ status: mapOneClickStatus(adapterResult.status),
4831
+ quoteId: params.quoteId,
4832
+ depositAddress: adapterResult.depositAddress,
4833
+ depositTxHash: params.depositTxHash,
4834
+ settlementTxHash: adapterResult.settlementTxHash,
4835
+ actualAmountOut: adapterResult.amountOut,
4836
+ metadata: {
4837
+ adapterResult,
4838
+ stealthRecipient: adapterResult.stealthRecipient,
4839
+ ephemeralPublicKey: adapterResult.ephemeralPublicKey
4840
+ }
4841
+ };
4842
+ return result;
4843
+ }
4844
+ /**
4845
+ * Get current swap status
4846
+ */
4847
+ async getStatus(swapId) {
4848
+ const oneClickStatus = await this.adapter.getStatus(swapId);
4849
+ const status = {
4850
+ swapId,
4851
+ status: mapOneClickStatus(oneClickStatus.status),
4852
+ quoteId: "",
4853
+ // 1Click status doesn't include quoteId
4854
+ depositAddress: swapId,
4855
+ amountIn: oneClickStatus.amountIn ?? "0",
4856
+ amountOut: oneClickStatus.amountOut ?? "0",
4857
+ depositTxHash: oneClickStatus.depositTxHash,
4858
+ settlementTxHash: oneClickStatus.settlementTxHash,
4859
+ errorMessage: oneClickStatus.error,
4860
+ updatedAt: Date.now() / 1e3,
4861
+ // 1Click doesn't provide updatedAt
4862
+ metadata: {
4863
+ oneClickStatus
4864
+ }
4865
+ };
4866
+ return status;
4867
+ }
4868
+ /**
4869
+ * Wait for swap completion (optional)
4870
+ */
4871
+ async waitForCompletion(swapId, options) {
4872
+ await this.adapter.waitForCompletion(swapId, {
4873
+ interval: options?.interval,
4874
+ timeout: options?.timeout,
4875
+ onStatus: options?.onStatusChange ? (oneClickStatus) => {
4876
+ const status = {
4877
+ swapId,
4878
+ status: mapOneClickStatus(oneClickStatus.status),
4879
+ quoteId: "",
4880
+ depositAddress: swapId,
4881
+ amountIn: oneClickStatus.amountIn ?? "0",
4882
+ amountOut: oneClickStatus.amountOut ?? "0",
4883
+ depositTxHash: oneClickStatus.depositTxHash,
4884
+ settlementTxHash: oneClickStatus.settlementTxHash,
4885
+ errorMessage: oneClickStatus.error,
4886
+ updatedAt: Date.now() / 1e3,
4887
+ metadata: { oneClickStatus }
4888
+ };
4889
+ options.onStatusChange?.(status);
4890
+ } : void 0
4891
+ });
4892
+ return this.getStatus(swapId);
4893
+ }
4894
+ /**
4895
+ * Get dry quote (preview without creating deposit address)
4896
+ */
4897
+ async getDryQuote(params) {
4898
+ this.validateQuoteParams(params);
4899
+ const swapRequest = {
4900
+ requestId: this.generateRequestId(),
4901
+ privacyLevel: params.privacyLevel,
4902
+ inputAsset: {
4903
+ chain: params.fromChain,
4904
+ symbol: params.fromToken,
4905
+ decimals: 0
4906
+ },
4907
+ outputAsset: {
4908
+ chain: params.toChain,
4909
+ symbol: params.toToken,
4910
+ decimals: 0
4911
+ },
4912
+ inputAmount: params.amount
4913
+ };
4914
+ const prepared = await this.adapter.prepareSwap(
4915
+ swapRequest,
4916
+ params.recipientMetaAddress,
4917
+ params.senderAddress
4918
+ );
4919
+ const oneClickQuote = await this.adapter.getDryQuote(prepared);
4920
+ const quote = {
4921
+ quoteId: oneClickQuote.quoteId,
4922
+ amountIn: oneClickQuote.amountIn,
4923
+ amountOut: oneClickQuote.amountOut,
4924
+ minAmountOut: oneClickQuote.amountOut,
4925
+ fees: {
4926
+ networkFee: "0",
4927
+ protocolFee: "0",
4928
+ totalFeeUSD: oneClickQuote.amountOutUsd
4929
+ },
4930
+ depositAddress: oneClickQuote.depositAddress,
4931
+ recipientAddress: prepared.stealthAddress?.address ?? params.senderAddress ?? "",
4932
+ refundAddress: params.senderAddress,
4933
+ expiresAt: new Date(oneClickQuote.deadline).getTime() / 1e3,
4934
+ estimatedTime: oneClickQuote.timeEstimate,
4935
+ metadata: {
4936
+ prepared,
4937
+ oneClickQuote,
4938
+ stealthAddress: prepared.stealthAddress,
4939
+ ephemeralPublicKey: prepared.stealthAddress?.ephemeralPublicKey,
4940
+ curve: prepared.curve,
4941
+ isDryQuote: true
4942
+ }
4943
+ };
4944
+ return quote;
4945
+ }
4946
+ /**
4947
+ * Notify backend of deposit transaction
4948
+ */
4949
+ async notifyDeposit(swapId, txHash, metadata) {
4950
+ await this.adapter.notifyDeposit(
4951
+ swapId,
4952
+ // swapId is deposit address
4953
+ txHash,
4954
+ metadata?.nearAccount
4955
+ );
4956
+ }
4957
+ // ─── Private Methods ──────────────────────────────────────────────────────────
4958
+ validateQuoteParams(params) {
4959
+ if (!params.fromChain) {
4960
+ throw new ValidationError("fromChain is required", "fromChain");
4961
+ }
4962
+ if (!params.toChain) {
4963
+ throw new ValidationError("toChain is required", "toChain");
4964
+ }
4965
+ if (!params.fromToken) {
4966
+ throw new ValidationError("fromToken is required", "fromToken");
4967
+ }
4968
+ if (!params.toToken) {
4969
+ throw new ValidationError("toToken is required", "toToken");
4970
+ }
4971
+ if (!params.amount || params.amount <= BigInt(0)) {
4972
+ throw new ValidationError("amount must be greater than 0", "amount");
4973
+ }
4974
+ if (!params.privacyLevel) {
4975
+ throw new ValidationError("privacyLevel is required", "privacyLevel");
4976
+ }
4977
+ if (params.privacyLevel !== import_types8.PrivacyLevel.TRANSPARENT && !params.recipientMetaAddress) {
4978
+ throw new ValidationError(
4979
+ "recipientMetaAddress is required for shielded/compliant privacy modes",
4980
+ "recipientMetaAddress"
4981
+ );
4982
+ }
4983
+ if (params.privacyLevel === import_types8.PrivacyLevel.TRANSPARENT && !params.senderAddress) {
4984
+ throw new ValidationError(
4985
+ "senderAddress is required for transparent mode",
4986
+ "senderAddress"
4987
+ );
4988
+ }
4989
+ if (!this.capabilities.supportedSourceChains.includes(params.fromChain)) {
4990
+ throw new ValidationError(
4991
+ `Source chain ${params.fromChain} is not supported`,
4992
+ "fromChain",
4993
+ { supportedChains: this.capabilities.supportedSourceChains }
4994
+ );
4995
+ }
4996
+ if (!this.capabilities.supportedDestinationChains.includes(params.toChain)) {
4997
+ throw new ValidationError(
4998
+ `Destination chain ${params.toChain} is not supported`,
4999
+ "toChain",
5000
+ { supportedChains: this.capabilities.supportedDestinationChains }
5001
+ );
5002
+ }
5003
+ }
5004
+ generateRequestId() {
5005
+ return `req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
5006
+ }
5007
+ };
5008
+ function createNEARIntentsBackend(config) {
5009
+ return new NEARIntentsBackend(config);
5010
+ }
5011
+
5012
+ // src/settlement/backends/zcash-native.ts
5013
+ var import_types9 = require("@sip-protocol/types");
5014
+ var ZcashNativeBackend = class {
5015
+ name = "zcash-native";
5016
+ capabilities;
5017
+ swapService;
5018
+ config;
5019
+ quotes = /* @__PURE__ */ new Map();
5020
+ swaps = /* @__PURE__ */ new Map();
5021
+ constructor(config) {
5022
+ this.swapService = config.swapService;
5023
+ this.config = {
5024
+ quoteValiditySeconds: config.quoteValiditySeconds ?? 300,
5025
+ networkFeeZatoshis: config.networkFeeZatoshis ?? 1e4
5026
+ };
5027
+ this.capabilities = {
5028
+ supportedSourceChains: ["zcash"],
5029
+ supportedDestinationChains: ["zcash"],
5030
+ supportedPrivacyLevels: [
5031
+ import_types9.PrivacyLevel.TRANSPARENT,
5032
+ import_types9.PrivacyLevel.SHIELDED,
5033
+ import_types9.PrivacyLevel.COMPLIANT
5034
+ ],
5035
+ supportsCancellation: false,
5036
+ supportsRefunds: false,
5037
+ averageExecutionTime: 75,
5038
+ // ~75 seconds for Zcash block confirmation
5039
+ features: [
5040
+ "native-zcash",
5041
+ "shielded-addresses",
5042
+ "transparent-addresses",
5043
+ "instant-quotes"
5044
+ ]
5045
+ };
5046
+ }
5047
+ // ─── Quote Methods ─────────────────────────────────────────────────────────
5048
+ /**
5049
+ * Get a quote for ZEC → ZEC transfer
5050
+ */
5051
+ async getQuote(params) {
5052
+ this.validateQuoteParams(params);
5053
+ const { amount, recipientMetaAddress, senderAddress, privacyLevel } = params;
5054
+ const quoteId = this.generateQuoteId();
5055
+ const now = Math.floor(Date.now() / 1e3);
5056
+ const expiresAt = now + this.config.quoteValiditySeconds;
5057
+ const networkFee = BigInt(this.config.networkFeeZatoshis);
5058
+ const protocolFee = BigInt(0);
5059
+ const totalFee = networkFee;
5060
+ const amountOut = amount - totalFee;
5061
+ if (amountOut <= BigInt(0)) {
5062
+ throw new ValidationError(
5063
+ "Amount too small to cover network fees",
5064
+ "amount",
5065
+ { amount: amount.toString(), networkFee: networkFee.toString() },
5066
+ "SIP_2004" /* INVALID_AMOUNT */
5067
+ );
5068
+ }
5069
+ const minAmountOut = amountOut * BigInt(99) / BigInt(100);
5070
+ let depositAddress;
5071
+ let recipientAddress;
5072
+ if (privacyLevel === import_types9.PrivacyLevel.SHIELDED || privacyLevel === import_types9.PrivacyLevel.COMPLIANT) {
5073
+ if (typeof recipientMetaAddress === "string") {
5074
+ recipientAddress = recipientMetaAddress;
5075
+ } else if (recipientMetaAddress) {
5076
+ recipientAddress = `zs1${this.randomHex(72)}`;
5077
+ } else {
5078
+ throw new ValidationError(
5079
+ "Recipient address required for shielded transfers",
5080
+ "recipientMetaAddress",
5081
+ void 0,
5082
+ "SIP_2000" /* VALIDATION_FAILED */
5083
+ );
5084
+ }
5085
+ depositAddress = `zs1${this.randomHex(72)}`;
5086
+ } else {
5087
+ if (senderAddress) {
5088
+ depositAddress = senderAddress;
5089
+ } else {
5090
+ depositAddress = `t1${this.randomBase58(33)}`;
5091
+ }
5092
+ if (typeof recipientMetaAddress === "string") {
5093
+ recipientAddress = recipientMetaAddress;
5094
+ } else {
5095
+ throw new ValidationError(
5096
+ "Recipient address required",
5097
+ "recipientMetaAddress",
5098
+ void 0,
5099
+ "SIP_2000" /* VALIDATION_FAILED */
5100
+ );
5101
+ }
5102
+ }
5103
+ const quote = {
5104
+ quoteId,
5105
+ amountIn: amount.toString(),
5106
+ amountOut: amountOut.toString(),
5107
+ minAmountOut: minAmountOut.toString(),
5108
+ fees: {
5109
+ networkFee: networkFee.toString(),
5110
+ protocolFee: protocolFee.toString()
5111
+ },
5112
+ depositAddress,
5113
+ recipientAddress,
5114
+ expiresAt,
5115
+ estimatedTime: this.capabilities.averageExecutionTime,
5116
+ metadata: {
5117
+ backend: this.name,
5118
+ privacyLevel,
5119
+ zcashNetwork: "mainnet"
5120
+ }
5121
+ };
5122
+ this.quotes.set(quoteId, quote);
5123
+ return quote;
5124
+ }
5125
+ /**
5126
+ * Get a dry quote (preview without creating deposit address)
5127
+ */
5128
+ async getDryQuote(params) {
5129
+ return this.getQuote(params);
5130
+ }
5131
+ // ─── Swap Execution ────────────────────────────────────────────────────────
5132
+ /**
5133
+ * Execute a ZEC → ZEC swap/transfer
5134
+ */
5135
+ async executeSwap(params) {
5136
+ const { quoteId, depositTxHash } = params;
5137
+ const quote = this.quotes.get(quoteId);
5138
+ if (!quote) {
5139
+ throw new ValidationError(
5140
+ "Quote not found or expired",
5141
+ "quoteId",
5142
+ { quoteId },
5143
+ "SIP_2000" /* VALIDATION_FAILED */
5144
+ );
5145
+ }
5146
+ const now = Math.floor(Date.now() / 1e3);
5147
+ if (now > quote.expiresAt) {
5148
+ throw new ValidationError(
5149
+ "Quote has expired",
5150
+ "quoteId",
5151
+ { quoteId, expiresAt: quote.expiresAt, now },
5152
+ "SIP_2000" /* VALIDATION_FAILED */
5153
+ );
5154
+ }
5155
+ const swapId = this.generateSwapId();
5156
+ const result = {
5157
+ swapId,
5158
+ status: depositTxHash ? "deposit_confirmed" /* DEPOSIT_CONFIRMED */ : "pending_deposit" /* PENDING_DEPOSIT */,
5159
+ quoteId,
5160
+ depositAddress: quote.depositAddress,
5161
+ depositTxHash,
5162
+ metadata: {
5163
+ backend: this.name,
5164
+ recipientAddress: quote.recipientAddress
5165
+ }
5166
+ };
5167
+ this.swaps.set(swapId, result);
5168
+ if (depositTxHash) {
5169
+ this.simulateSwapExecution(swapId, quote);
5170
+ }
5171
+ return result;
5172
+ }
5173
+ // ─── Status Methods ────────────────────────────────────────────────────────
5174
+ /**
5175
+ * Get swap status
5176
+ */
5177
+ async getStatus(swapId) {
5178
+ const swap = this.swaps.get(swapId);
5179
+ if (!swap) {
5180
+ throw new ValidationError(
5181
+ "Swap not found",
5182
+ "swapId",
5183
+ { swapId },
5184
+ "SIP_2000" /* VALIDATION_FAILED */
5185
+ );
5186
+ }
5187
+ const quote = this.quotes.get(swap.quoteId);
5188
+ if (!quote) {
5189
+ throw new ValidationError(
5190
+ "Quote not found for swap",
5191
+ "quoteId",
5192
+ { quoteId: swap.quoteId },
5193
+ "SIP_2000" /* VALIDATION_FAILED */
5194
+ );
5195
+ }
5196
+ const status = {
5197
+ swapId: swap.swapId,
5198
+ status: swap.status,
5199
+ quoteId: swap.quoteId,
5200
+ depositAddress: swap.depositAddress,
5201
+ amountIn: quote.amountIn,
5202
+ amountOut: quote.amountOut,
5203
+ depositTxHash: swap.depositTxHash,
5204
+ settlementTxHash: swap.settlementTxHash,
5205
+ actualAmountOut: swap.actualAmountOut,
5206
+ errorMessage: swap.errorMessage,
5207
+ updatedAt: Math.floor(Date.now() / 1e3),
5208
+ metadata: swap.metadata
5209
+ };
5210
+ return status;
5211
+ }
5212
+ /**
5213
+ * Wait for swap completion
5214
+ */
5215
+ async waitForCompletion(swapId, options) {
5216
+ const interval = options?.interval ?? 5e3;
5217
+ const timeout = options?.timeout ?? 6e5;
5218
+ const startTime = Date.now();
5219
+ while (Date.now() - startTime < timeout) {
5220
+ const status2 = await this.getStatus(swapId);
5221
+ if (options?.onStatusChange) {
5222
+ options.onStatusChange(status2);
5223
+ }
5224
+ if (status2.status === "success" /* SUCCESS */) {
5225
+ return status2;
5226
+ }
5227
+ if (status2.status === "failed" /* FAILED */ || status2.status === "cancelled" /* CANCELLED */ || status2.status === "refunded" /* REFUNDED */) {
5228
+ return status2;
5229
+ }
5230
+ await this.delay(interval);
5231
+ }
5232
+ const status = await this.getStatus(swapId);
5233
+ return status;
5234
+ }
5235
+ /**
5236
+ * Notify backend of deposit
5237
+ */
5238
+ async notifyDeposit(swapId, txHash, metadata) {
5239
+ const swap = this.swaps.get(swapId);
5240
+ if (!swap) {
5241
+ throw new ValidationError(
5242
+ "Swap not found",
5243
+ "swapId",
5244
+ { swapId },
5245
+ "SIP_2000" /* VALIDATION_FAILED */
5246
+ );
5247
+ }
5248
+ swap.depositTxHash = txHash;
5249
+ swap.status = "deposit_confirmed" /* DEPOSIT_CONFIRMED */;
5250
+ if (metadata) {
5251
+ swap.metadata = { ...swap.metadata, ...metadata };
5252
+ }
5253
+ this.swaps.set(swapId, swap);
5254
+ const quote = this.quotes.get(swap.quoteId);
5255
+ if (quote) {
5256
+ this.simulateSwapExecution(swapId, quote);
5257
+ }
5258
+ }
5259
+ // ─── Private Helpers ───────────────────────────────────────────────────────
5260
+ validateQuoteParams(params) {
5261
+ if (params.fromChain !== "zcash") {
5262
+ throw new ValidationError(
5263
+ "Source chain must be zcash",
5264
+ "fromChain",
5265
+ { received: params.fromChain, expected: "zcash" },
5266
+ "SIP_2000" /* VALIDATION_FAILED */
5267
+ );
5268
+ }
5269
+ if (params.toChain !== "zcash") {
5270
+ throw new ValidationError(
5271
+ "Destination chain must be zcash",
5272
+ "toChain",
5273
+ { received: params.toChain, expected: "zcash" },
5274
+ "SIP_2000" /* VALIDATION_FAILED */
5275
+ );
5276
+ }
5277
+ if (params.fromToken !== "ZEC") {
5278
+ throw new ValidationError(
5279
+ "Source token must be ZEC",
5280
+ "fromToken",
5281
+ { received: params.fromToken, expected: "ZEC" },
5282
+ "SIP_2000" /* VALIDATION_FAILED */
5283
+ );
5284
+ }
5285
+ if (params.toToken !== "ZEC") {
5286
+ throw new ValidationError(
5287
+ "Destination token must be ZEC",
5288
+ "toToken",
5289
+ { received: params.toToken, expected: "ZEC" },
5290
+ "SIP_2000" /* VALIDATION_FAILED */
5291
+ );
5292
+ }
5293
+ if (!params.amount || params.amount <= BigInt(0)) {
5294
+ throw new ValidationError(
5295
+ "Amount must be positive",
5296
+ "amount",
5297
+ { received: params.amount },
5298
+ "SIP_2004" /* INVALID_AMOUNT */
5299
+ );
5300
+ }
5301
+ if (!this.capabilities.supportedPrivacyLevels.includes(params.privacyLevel)) {
5302
+ throw new ValidationError(
5303
+ "Unsupported privacy level",
5304
+ "privacyLevel",
5305
+ { received: params.privacyLevel, supported: this.capabilities.supportedPrivacyLevels },
5306
+ "SIP_2000" /* VALIDATION_FAILED */
5307
+ );
5308
+ }
5309
+ }
5310
+ simulateSwapExecution(swapId, quote) {
5311
+ setTimeout(() => {
5312
+ const swap = this.swaps.get(swapId);
5313
+ if (!swap) return;
5314
+ swap.status = "in_progress" /* IN_PROGRESS */;
5315
+ this.swaps.set(swapId, swap);
5316
+ setTimeout(() => {
5317
+ const finalSwap = this.swaps.get(swapId);
5318
+ if (!finalSwap) return;
5319
+ finalSwap.status = "success" /* SUCCESS */;
5320
+ finalSwap.settlementTxHash = this.randomHex(64);
5321
+ finalSwap.actualAmountOut = quote.amountOut;
5322
+ this.swaps.set(swapId, finalSwap);
5323
+ }, 2e3);
5324
+ }, 1e3);
5325
+ }
5326
+ generateQuoteId() {
5327
+ return `zec_native_quote_${Date.now()}_${this.randomHex(8)}`;
5328
+ }
5329
+ generateSwapId() {
5330
+ return `zec_native_swap_${Date.now()}_${this.randomHex(8)}`;
5331
+ }
5332
+ randomHex(length) {
5333
+ const chars = "0123456789abcdef";
5334
+ let result = "";
5335
+ for (let i = 0; i < length; i++) {
5336
+ result += chars[Math.floor(Math.random() * chars.length)];
5337
+ }
5338
+ return result;
5339
+ }
5340
+ randomBase58(length) {
5341
+ const chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
5342
+ let result = "";
5343
+ for (let i = 0; i < length; i++) {
5344
+ result += chars[Math.floor(Math.random() * chars.length)];
5345
+ }
5346
+ return result;
3956
5347
  }
3957
5348
  delay(ms) {
3958
5349
  return new Promise((resolve) => setTimeout(resolve, ms));
3959
5350
  }
3960
5351
  };
3961
- function createMockSolver(config) {
3962
- return new MockSolver(config);
5352
+ function createZcashNativeBackend(config) {
5353
+ return new ZcashNativeBackend(config);
3963
5354
  }
3964
5355
 
3965
- // src/index.ts
3966
- var import_types38 = require("@sip-protocol/types");
5356
+ // src/settlement/backends/direct-chain.ts
5357
+ var import_types10 = require("@sip-protocol/types");
5358
+ var import_utils11 = require("@noble/hashes/utils");
5359
+ var DEFAULT_GAS_FEES = {
5360
+ ethereum: 21000n * 50n * 1000000000n,
5361
+ // 21k gas * 50 gwei = 0.00105 ETH
5362
+ solana: 5000n,
5363
+ // 5000 lamports = 0.000005 SOL
5364
+ near: 300000000000000000000n,
5365
+ // 0.3 NEAR in yoctoNEAR
5366
+ zcash: 10000n,
5367
+ // 0.0001 ZEC in zatoshi
5368
+ polygon: 21000n * 30n * 1000000000n,
5369
+ // 21k gas * 30 gwei POL
5370
+ arbitrum: 2100000000n,
5371
+ // 21k gas * 0.1 gwei ETH = 2100 gwei = 2.1e9 wei
5372
+ optimism: 21000000n,
5373
+ // 21k gas * 0.001 gwei ETH = 21 gwei = 21e6 wei
5374
+ base: 2100000000n,
5375
+ // 21k gas * 0.1 gwei ETH = 2100 gwei = 2.1e9 wei
5376
+ bitcoin: 10000n
5377
+ // 10000 sats = 0.0001 BTC (estimate for 1 input, 2 outputs)
5378
+ };
3967
5379
 
3968
5380
  // src/zcash/rpc-client.ts
3969
- var import_types8 = require("@sip-protocol/types");
5381
+ var import_types11 = require("@sip-protocol/types");
3970
5382
  var DEFAULT_CONFIG = {
3971
5383
  host: "127.0.0.1",
3972
5384
  port: 8232,
@@ -3986,19 +5398,19 @@ var ZcashRPCError = class extends Error {
3986
5398
  * Check if error is due to insufficient funds
3987
5399
  */
3988
5400
  isInsufficientFunds() {
3989
- return this.code === import_types8.ZcashErrorCode.WALLET_INSUFFICIENT_FUNDS;
5401
+ return this.code === import_types11.ZcashErrorCode.WALLET_INSUFFICIENT_FUNDS;
3990
5402
  }
3991
5403
  /**
3992
5404
  * Check if error is due to invalid address
3993
5405
  */
3994
5406
  isInvalidAddress() {
3995
- return this.code === import_types8.ZcashErrorCode.INVALID_ADDRESS_OR_KEY;
5407
+ return this.code === import_types11.ZcashErrorCode.INVALID_ADDRESS_OR_KEY;
3996
5408
  }
3997
5409
  /**
3998
5410
  * Check if error is due to wallet being locked
3999
5411
  */
4000
5412
  isWalletLocked() {
4001
- return this.code === import_types8.ZcashErrorCode.WALLET_UNLOCK_NEEDED;
5413
+ return this.code === import_types11.ZcashErrorCode.WALLET_UNLOCK_NEEDED;
4002
5414
  }
4003
5415
  };
4004
5416
  var ZcashRPCClient = class {
@@ -4385,7 +5797,7 @@ function createZcashClient(config) {
4385
5797
  }
4386
5798
 
4387
5799
  // src/zcash/shielded-service.ts
4388
- var import_types9 = require("@sip-protocol/types");
5800
+ var import_types12 = require("@sip-protocol/types");
4389
5801
  var ZcashShieldedService = class _ZcashShieldedService {
4390
5802
  client;
4391
5803
  config;
@@ -4571,7 +5983,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
4571
5983
  * Higher-level method that handles privacy level mapping.
4572
5984
  */
4573
5985
  async sendWithPrivacy(to, amount, privacyLevel, memo) {
4574
- if (privacyLevel === import_types9.PrivacyLevel.TRANSPARENT) {
5986
+ if (privacyLevel === import_types12.PrivacyLevel.TRANSPARENT) {
4575
5987
  throw new ValidationError(
4576
5988
  "Transparent mode not supported for Zcash shielded service. Use standard RPC client.",
4577
5989
  "privacyLevel",
@@ -4665,7 +6077,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
4665
6077
  const viewingKey = await this.exportViewingKey();
4666
6078
  return {
4667
6079
  viewingKey,
4668
- privacyLevel: import_types9.PrivacyLevel.COMPLIANT,
6080
+ privacyLevel: import_types12.PrivacyLevel.COMPLIANT,
4669
6081
  disclaimer: "This viewing key provides read-only access to transaction history. It cannot be used to spend funds. Share only with authorized auditors."
4670
6082
  };
4671
6083
  }
@@ -4751,11 +6163,11 @@ var ZcashShieldedService = class _ZcashShieldedService {
4751
6163
  */
4752
6164
  mapPrivacyLevelToPolicy(level) {
4753
6165
  switch (level) {
4754
- case import_types9.PrivacyLevel.TRANSPARENT:
6166
+ case import_types12.PrivacyLevel.TRANSPARENT:
4755
6167
  return "NoPrivacy";
4756
- case import_types9.PrivacyLevel.SHIELDED:
6168
+ case import_types12.PrivacyLevel.SHIELDED:
4757
6169
  return "FullPrivacy";
4758
- case import_types9.PrivacyLevel.COMPLIANT:
6170
+ case import_types12.PrivacyLevel.COMPLIANT:
4759
6171
  return "FullPrivacy";
4760
6172
  default:
4761
6173
  return "FullPrivacy";
@@ -4808,7 +6220,7 @@ function createZcashShieldedService(config) {
4808
6220
  }
4809
6221
 
4810
6222
  // src/zcash/swap-service.ts
4811
- var import_types10 = require("@sip-protocol/types");
6223
+ var import_types13 = require("@sip-protocol/types");
4812
6224
  var MOCK_PRICES = {
4813
6225
  ETH: 2500,
4814
6226
  SOL: 120,
@@ -4915,7 +6327,7 @@ var ZcashSwapService = class {
4915
6327
  validUntil,
4916
6328
  depositAddress: this.generateMockDepositAddress(sourceChain),
4917
6329
  estimatedTime: this.getEstimatedTime(sourceChain),
4918
- privacyLevel: import_types10.PrivacyLevel.SHIELDED
6330
+ privacyLevel: import_types13.PrivacyLevel.SHIELDED
4919
6331
  };
4920
6332
  this.quotes.set(quoteId, quote);
4921
6333
  return quote;
@@ -4958,7 +6370,7 @@ var ZcashSwapService = class {
4958
6370
  depositAddress: "",
4959
6371
  // Will be set by bridge
4960
6372
  estimatedTime: this.getEstimatedTime(params.sourceChain),
4961
- privacyLevel: import_types10.PrivacyLevel.SHIELDED
6373
+ privacyLevel: import_types13.PrivacyLevel.SHIELDED
4962
6374
  };
4963
6375
  this.quotes.set(quote.quoteId, quote);
4964
6376
  return quote;
@@ -5238,15 +6650,15 @@ function createZcashSwapService(config) {
5238
6650
  }
5239
6651
 
5240
6652
  // src/zcash/index.ts
5241
- var import_types11 = require("@sip-protocol/types");
6653
+ var import_types14 = require("@sip-protocol/types");
5242
6654
 
5243
6655
  // src/index.ts
5244
- var import_types39 = require("@sip-protocol/types");
6656
+ var import_types42 = require("@sip-protocol/types");
5245
6657
 
5246
6658
  // src/payment/payment.ts
5247
- var import_types12 = require("@sip-protocol/types");
6659
+ var import_types15 = require("@sip-protocol/types");
5248
6660
  var import_sha2569 = require("@noble/hashes/sha256");
5249
- var import_utils11 = require("@noble/hashes/utils");
6661
+ var import_utils12 = require("@noble/hashes/utils");
5250
6662
  var import_chacha2 = require("@noble/ciphers/chacha.js");
5251
6663
  var import_hkdf2 = require("@noble/hashes/hkdf");
5252
6664
 
@@ -5431,7 +6843,7 @@ var PaymentBuilder = class {
5431
6843
  _amount;
5432
6844
  _recipientMetaAddress;
5433
6845
  _recipientAddress;
5434
- _privacy = import_types12.PrivacyLevel.SHIELDED;
6846
+ _privacy = import_types15.PrivacyLevel.SHIELDED;
5435
6847
  _viewingKey;
5436
6848
  _sourceChain;
5437
6849
  _destinationChain;
@@ -5714,7 +7126,7 @@ async function createShieldedPayment(params, options) {
5714
7126
  } else {
5715
7127
  resolvedToken = token;
5716
7128
  }
5717
- if (privacy !== import_types12.PrivacyLevel.TRANSPARENT && !recipientMetaAddress) {
7129
+ if (privacy !== import_types15.PrivacyLevel.TRANSPARENT && !recipientMetaAddress) {
5718
7130
  throw new ValidationError(
5719
7131
  "recipientMetaAddress is required for shielded/compliant privacy modes",
5720
7132
  "recipientMetaAddress",
@@ -5722,7 +7134,7 @@ async function createShieldedPayment(params, options) {
5722
7134
  "SIP_2008" /* MISSING_REQUIRED */
5723
7135
  );
5724
7136
  }
5725
- if (privacy === import_types12.PrivacyLevel.TRANSPARENT && !recipientAddress) {
7137
+ if (privacy === import_types15.PrivacyLevel.TRANSPARENT && !recipientAddress) {
5726
7138
  throw new ValidationError(
5727
7139
  "recipientAddress is required for transparent mode",
5728
7140
  "recipientAddress",
@@ -5730,7 +7142,7 @@ async function createShieldedPayment(params, options) {
5730
7142
  "SIP_2008" /* MISSING_REQUIRED */
5731
7143
  );
5732
7144
  }
5733
- if (privacy === import_types12.PrivacyLevel.COMPLIANT && !viewingKey) {
7145
+ if (privacy === import_types15.PrivacyLevel.COMPLIANT && !viewingKey) {
5734
7146
  throw new ValidationError(
5735
7147
  "viewingKey is required for compliant mode",
5736
7148
  "viewingKey",
@@ -5742,8 +7154,8 @@ async function createShieldedPayment(params, options) {
5742
7154
  let viewingKeyHash;
5743
7155
  if (viewingKey) {
5744
7156
  const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
5745
- const keyBytes = (0, import_utils11.hexToBytes)(keyHex);
5746
- viewingKeyHash = `0x${(0, import_utils11.bytesToHex)((0, import_sha2569.sha256)(keyBytes))}`;
7157
+ const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
7158
+ viewingKeyHash = `0x${(0, import_utils12.bytesToHex)((0, import_sha2569.sha256)(keyBytes))}`;
5747
7159
  }
5748
7160
  const privacyConfig = getPrivacyConfig(
5749
7161
  privacy,
@@ -5752,7 +7164,7 @@ async function createShieldedPayment(params, options) {
5752
7164
  const now = Math.floor(Date.now() / 1e3);
5753
7165
  const payment = {
5754
7166
  paymentId,
5755
- version: import_types12.SIP_VERSION,
7167
+ version: import_types15.SIP_VERSION,
5756
7168
  privacyLevel: privacy,
5757
7169
  createdAt: now,
5758
7170
  expiry: now + ttl,
@@ -5763,7 +7175,7 @@ async function createShieldedPayment(params, options) {
5763
7175
  purpose,
5764
7176
  viewingKeyHash
5765
7177
  };
5766
- if (privacy !== import_types12.PrivacyLevel.TRANSPARENT && recipientMetaAddress) {
7178
+ if (privacy !== import_types15.PrivacyLevel.TRANSPARENT && recipientMetaAddress) {
5767
7179
  const metaAddress = decodeStealthMetaAddress(recipientMetaAddress);
5768
7180
  const { stealthAddress } = generateStealthAddress(metaAddress);
5769
7181
  payment.recipientStealth = stealthAddress;
@@ -5780,10 +7192,10 @@ async function createShieldedPayment(params, options) {
5780
7192
  payment.recipientAddress = recipientAddress;
5781
7193
  payment.memo = memo;
5782
7194
  }
5783
- if (privacy !== import_types12.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
7195
+ if (privacy !== import_types15.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
5784
7196
  const hexToUint8 = (hex) => {
5785
7197
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
5786
- return (0, import_utils11.hexToBytes)(cleanHex);
7198
+ return (0, import_utils12.hexToBytes)(cleanHex);
5787
7199
  };
5788
7200
  const fundingResult = await proofProvider.generateFundingProof({
5789
7201
  balance: amount,
@@ -5810,17 +7222,17 @@ async function createShieldedPayment(params, options) {
5810
7222
  }
5811
7223
  function encryptMemo(memo, viewingKey) {
5812
7224
  const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
5813
- const keyBytes = (0, import_utils11.hexToBytes)(keyHex);
7225
+ const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
5814
7226
  const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
5815
7227
  try {
5816
- const nonce = (0, import_utils11.randomBytes)(24);
7228
+ const nonce = (0, import_utils12.randomBytes)(24);
5817
7229
  const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
5818
7230
  const plaintext = new TextEncoder().encode(memo);
5819
7231
  const ciphertext = cipher.encrypt(plaintext);
5820
7232
  const result = new Uint8Array(nonce.length + ciphertext.length);
5821
7233
  result.set(nonce);
5822
7234
  result.set(ciphertext, nonce.length);
5823
- return `0x${(0, import_utils11.bytesToHex)(result)}`;
7235
+ return `0x${(0, import_utils12.bytesToHex)(result)}`;
5824
7236
  } finally {
5825
7237
  secureWipe(keyBytes);
5826
7238
  secureWipe(encKey);
@@ -5828,11 +7240,11 @@ function encryptMemo(memo, viewingKey) {
5828
7240
  }
5829
7241
  function decryptMemo(encryptedMemo, viewingKey) {
5830
7242
  const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
5831
- const keyBytes = (0, import_utils11.hexToBytes)(keyHex);
7243
+ const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
5832
7244
  const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
5833
7245
  try {
5834
7246
  const dataHex = encryptedMemo.startsWith("0x") ? encryptedMemo.slice(2) : encryptedMemo;
5835
- const data = (0, import_utils11.hexToBytes)(dataHex);
7247
+ const data = (0, import_utils12.hexToBytes)(dataHex);
5836
7248
  const nonce = data.slice(0, 24);
5837
7249
  const ciphertext = data.slice(24);
5838
7250
  const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
@@ -5846,7 +7258,7 @@ function decryptMemo(encryptedMemo, viewingKey) {
5846
7258
  function trackPayment(payment) {
5847
7259
  return {
5848
7260
  ...payment,
5849
- status: import_types12.PaymentStatus.DRAFT
7261
+ status: import_types15.PaymentStatus.DRAFT
5850
7262
  };
5851
7263
  }
5852
7264
  function isPaymentExpired(payment) {
@@ -5879,10 +7291,10 @@ function getPaymentSummary(payment) {
5879
7291
  }
5880
7292
 
5881
7293
  // src/treasury/treasury.ts
5882
- var import_types13 = require("@sip-protocol/types");
7294
+ var import_types16 = require("@sip-protocol/types");
5883
7295
  var import_secp256k13 = require("@noble/curves/secp256k1");
5884
7296
  var import_sha25610 = require("@noble/hashes/sha256");
5885
- var import_utils12 = require("@noble/hashes/utils");
7297
+ var import_utils13 = require("@noble/hashes/utils");
5886
7298
  var DEFAULT_PROPOSAL_TTL = 7 * 24 * 60 * 60;
5887
7299
  var Treasury = class _Treasury {
5888
7300
  config;
@@ -5912,7 +7324,7 @@ var Treasury = class _Treasury {
5912
7324
  ...m,
5913
7325
  addedAt: now
5914
7326
  })),
5915
- defaultPrivacy: params.defaultPrivacy ?? import_types13.PrivacyLevel.SHIELDED,
7327
+ defaultPrivacy: params.defaultPrivacy ?? import_types16.PrivacyLevel.SHIELDED,
5916
7328
  masterViewingKey,
5917
7329
  dailyLimit: params.dailyLimit,
5918
7330
  transactionLimit: params.transactionLimit,
@@ -5991,7 +7403,7 @@ var Treasury = class _Treasury {
5991
7403
  proposalId,
5992
7404
  treasuryId: this.config.treasuryId,
5993
7405
  type: "payment",
5994
- status: import_types13.ProposalStatus.PENDING,
7406
+ status: import_types16.ProposalStatus.PENDING,
5995
7407
  proposer: "",
5996
7408
  // Should be set by caller
5997
7409
  title: params.title,
@@ -6024,7 +7436,7 @@ var Treasury = class _Treasury {
6024
7436
  proposalId,
6025
7437
  treasuryId: this.config.treasuryId,
6026
7438
  type: "batch_payment",
6027
- status: import_types13.ProposalStatus.PENDING,
7439
+ status: import_types16.ProposalStatus.PENDING,
6028
7440
  proposer: "",
6029
7441
  title: params.title,
6030
7442
  description: params.description,
@@ -6058,7 +7470,7 @@ var Treasury = class _Treasury {
6058
7470
  * Get pending proposals
6059
7471
  */
6060
7472
  getPendingProposals() {
6061
- return this.getAllProposals().filter((p) => p.status === import_types13.ProposalStatus.PENDING);
7473
+ return this.getAllProposals().filter((p) => p.status === import_types16.ProposalStatus.PENDING);
6062
7474
  }
6063
7475
  /**
6064
7476
  * Sign a proposal
@@ -6089,7 +7501,7 @@ var Treasury = class _Treasury {
6089
7501
  "SIP_2001" /* INVALID_INPUT */
6090
7502
  );
6091
7503
  }
6092
- if (proposal.status !== import_types13.ProposalStatus.PENDING) {
7504
+ if (proposal.status !== import_types16.ProposalStatus.PENDING) {
6093
7505
  throw new ValidationError(
6094
7506
  `proposal is not pending: ${proposal.status}`,
6095
7507
  "proposalId",
@@ -6099,7 +7511,7 @@ var Treasury = class _Treasury {
6099
7511
  }
6100
7512
  const now = Math.floor(Date.now() / 1e3);
6101
7513
  if (now > proposal.expiresAt) {
6102
- proposal.status = import_types13.ProposalStatus.EXPIRED;
7514
+ proposal.status = import_types16.ProposalStatus.EXPIRED;
6103
7515
  throw new ValidationError(
6104
7516
  "proposal has expired",
6105
7517
  "proposalId",
@@ -6131,9 +7543,9 @@ var Treasury = class _Treasury {
6131
7543
  const approvals = proposal.signatures.filter((s) => s.approved).length;
6132
7544
  const rejections = proposal.signatures.filter((s) => !s.approved).length;
6133
7545
  if (approvals >= proposal.requiredSignatures) {
6134
- proposal.status = import_types13.ProposalStatus.APPROVED;
7546
+ proposal.status = import_types16.ProposalStatus.APPROVED;
6135
7547
  } else if (rejections > this.config.totalSigners - proposal.requiredSignatures) {
6136
- proposal.status = import_types13.ProposalStatus.REJECTED;
7548
+ proposal.status = import_types16.ProposalStatus.REJECTED;
6137
7549
  }
6138
7550
  return proposal;
6139
7551
  }
@@ -6150,7 +7562,7 @@ var Treasury = class _Treasury {
6150
7562
  "SIP_2001" /* INVALID_INPUT */
6151
7563
  );
6152
7564
  }
6153
- if (proposal.status !== import_types13.ProposalStatus.APPROVED) {
7565
+ if (proposal.status !== import_types16.ProposalStatus.APPROVED) {
6154
7566
  throw new ValidationError(
6155
7567
  `proposal is not approved: ${proposal.status}`,
6156
7568
  "proposalId",
@@ -6163,8 +7575,8 @@ var Treasury = class _Treasury {
6163
7575
  const payment = await createShieldedPayment({
6164
7576
  token: proposal.payment.token,
6165
7577
  amount: proposal.payment.amount,
6166
- recipientMetaAddress: proposal.payment.privacy !== import_types13.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
6167
- recipientAddress: proposal.payment.privacy === import_types13.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
7578
+ recipientMetaAddress: proposal.payment.privacy !== import_types16.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
7579
+ recipientAddress: proposal.payment.privacy === import_types16.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
6168
7580
  privacy: proposal.payment.privacy,
6169
7581
  viewingKey: this.config.masterViewingKey?.key,
6170
7582
  sourceChain: this.config.chain,
@@ -6177,8 +7589,8 @@ var Treasury = class _Treasury {
6177
7589
  const payment = await createShieldedPayment({
6178
7590
  token: proposal.batchPayment.token,
6179
7591
  amount: recipient.amount,
6180
- recipientMetaAddress: proposal.batchPayment.privacy !== import_types13.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
6181
- recipientAddress: proposal.batchPayment.privacy === import_types13.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
7592
+ recipientMetaAddress: proposal.batchPayment.privacy !== import_types16.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
7593
+ recipientAddress: proposal.batchPayment.privacy === import_types16.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
6182
7594
  privacy: proposal.batchPayment.privacy,
6183
7595
  viewingKey: this.config.masterViewingKey?.key,
6184
7596
  sourceChain: this.config.chain,
@@ -6188,7 +7600,7 @@ var Treasury = class _Treasury {
6188
7600
  payments.push(payment);
6189
7601
  }
6190
7602
  }
6191
- proposal.status = import_types13.ProposalStatus.EXECUTED;
7603
+ proposal.status = import_types16.ProposalStatus.EXECUTED;
6192
7604
  proposal.executedAt = Math.floor(Date.now() / 1e3);
6193
7605
  proposal.resultPayments = payments;
6194
7606
  return payments;
@@ -6217,7 +7629,7 @@ var Treasury = class _Treasury {
6217
7629
  "SIP_2001" /* INVALID_INPUT */
6218
7630
  );
6219
7631
  }
6220
- if (proposal.status !== import_types13.ProposalStatus.PENDING) {
7632
+ if (proposal.status !== import_types16.ProposalStatus.PENDING) {
6221
7633
  throw new ValidationError(
6222
7634
  `proposal is not pending: ${proposal.status}`,
6223
7635
  "proposalId",
@@ -6225,7 +7637,7 @@ var Treasury = class _Treasury {
6225
7637
  "SIP_2001" /* INVALID_INPUT */
6226
7638
  );
6227
7639
  }
6228
- proposal.status = import_types13.ProposalStatus.CANCELLED;
7640
+ proposal.status = import_types16.ProposalStatus.CANCELLED;
6229
7641
  return proposal;
6230
7642
  }
6231
7643
  // ─── Auditor Access ──────────────────────────────────────────────────────────
@@ -6322,7 +7734,7 @@ var Treasury = class _Treasury {
6322
7734
  getCommittedAmount(token) {
6323
7735
  let committed = 0n;
6324
7736
  for (const proposal of this.proposals.values()) {
6325
- if (proposal.status !== import_types13.ProposalStatus.PENDING) continue;
7737
+ if (proposal.status !== import_types16.ProposalStatus.PENDING) continue;
6326
7738
  if (proposal.type === "payment" && proposal.payment) {
6327
7739
  if (proposal.payment.token.symbol === token.symbol && proposal.payment.token.chain === token.chain) {
6328
7740
  committed += proposal.payment.amount;
@@ -6373,12 +7785,12 @@ var Treasury = class _Treasury {
6373
7785
  }
6374
7786
  };
6375
7787
  function generateTreasuryId() {
6376
- const bytes = (0, import_utils12.randomBytes)(16);
6377
- return `treasury_${(0, import_utils12.bytesToHex)(bytes)}`;
7788
+ const bytes = (0, import_utils13.randomBytes)(16);
7789
+ return `treasury_${(0, import_utils13.bytesToHex)(bytes)}`;
6378
7790
  }
6379
7791
  function generateProposalId() {
6380
- const bytes = (0, import_utils12.randomBytes)(16);
6381
- return `prop_${(0, import_utils12.bytesToHex)(bytes)}`;
7792
+ const bytes = (0, import_utils13.randomBytes)(16);
7793
+ return `prop_${(0, import_utils13.bytesToHex)(bytes)}`;
6382
7794
  }
6383
7795
  function computeProposalHash(proposal) {
6384
7796
  const data = JSON.stringify({
@@ -6394,7 +7806,7 @@ function computeProposalHash(proposal) {
6394
7806
  }
6395
7807
  function signMessage(messageHash, privateKey) {
6396
7808
  const keyHex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
6397
- const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
7809
+ const keyBytes = (0, import_utils13.hexToBytes)(keyHex);
6398
7810
  try {
6399
7811
  const signature = import_secp256k13.secp256k1.sign(messageHash, keyBytes);
6400
7812
  return `0x${signature.toCompactHex()}`;
@@ -6406,8 +7818,8 @@ function verifySignature(messageHash, signature, publicKey) {
6406
7818
  const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
6407
7819
  const pubKeyHex = publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
6408
7820
  try {
6409
- const sigBytes = (0, import_utils12.hexToBytes)(sigHex);
6410
- const pubKeyBytes = (0, import_utils12.hexToBytes)(pubKeyHex);
7821
+ const sigBytes = (0, import_utils13.hexToBytes)(sigHex);
7822
+ const pubKeyBytes = (0, import_utils13.hexToBytes)(pubKeyHex);
6411
7823
  return import_secp256k13.secp256k1.verify(sigBytes, messageHash, pubKeyBytes);
6412
7824
  } catch {
6413
7825
  return false;
@@ -6565,8 +7977,8 @@ function validateBatchProposalParams(params, config) {
6565
7977
  }
6566
7978
 
6567
7979
  // src/compliance/compliance-manager.ts
6568
- var import_types14 = require("@sip-protocol/types");
6569
- var import_utils13 = require("@noble/hashes/utils");
7980
+ var import_types17 = require("@sip-protocol/types");
7981
+ var import_utils14 = require("@noble/hashes/utils");
6570
7982
  var DEFAULTS2 = {
6571
7983
  riskThreshold: 70,
6572
7984
  highValueThreshold: 10000000000n,
@@ -6933,7 +8345,7 @@ var ComplianceManager = class _ComplianceManager {
6933
8345
  title: params.title,
6934
8346
  description: params.description,
6935
8347
  format: params.format,
6936
- status: import_types14.ReportStatus.GENERATING,
8348
+ status: import_types17.ReportStatus.GENERATING,
6937
8349
  requestedBy,
6938
8350
  requestedAt: now,
6939
8351
  startDate: params.startDate,
@@ -6962,10 +8374,10 @@ var ComplianceManager = class _ComplianceManager {
6962
8374
  } else if (params.format === "csv") {
6963
8375
  report.content = this.generateCSV(transactions);
6964
8376
  }
6965
- report.status = import_types14.ReportStatus.COMPLETED;
8377
+ report.status = import_types17.ReportStatus.COMPLETED;
6966
8378
  report.generatedAt = Math.floor(Date.now() / 1e3);
6967
8379
  } catch (error) {
6968
- report.status = import_types14.ReportStatus.FAILED;
8380
+ report.status = import_types17.ReportStatus.FAILED;
6969
8381
  report.error = error instanceof Error ? error.message : "Unknown error";
6970
8382
  }
6971
8383
  this.addAuditLog(requestedBy, "report_generated", {
@@ -7240,7 +8652,7 @@ var ComplianceManager = class _ComplianceManager {
7240
8652
  }
7241
8653
  };
7242
8654
  function generateId(prefix) {
7243
- return `${prefix}_${(0, import_utils13.bytesToHex)((0, import_utils13.randomBytes)(12))}`;
8655
+ return `${prefix}_${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(12))}`;
7244
8656
  }
7245
8657
  function validateRegisterAuditorParams(params) {
7246
8658
  if (!params.organization?.trim()) {
@@ -7328,10 +8740,10 @@ function validateReportParams(params) {
7328
8740
  }
7329
8741
 
7330
8742
  // src/wallet/errors.ts
7331
- var import_types15 = require("@sip-protocol/types");
8743
+ var import_types18 = require("@sip-protocol/types");
7332
8744
  var WalletError = class extends SIPError {
7333
8745
  walletCode;
7334
- constructor(message, walletCode = import_types15.WalletErrorCode.UNKNOWN, options) {
8746
+ constructor(message, walletCode = import_types18.WalletErrorCode.UNKNOWN, options) {
7335
8747
  super(message, "SIP_7000" /* WALLET_ERROR */, options);
7336
8748
  this.walletCode = walletCode;
7337
8749
  this.name = "WalletError";
@@ -7341,10 +8753,10 @@ var WalletError = class extends SIPError {
7341
8753
  */
7342
8754
  isConnectionError() {
7343
8755
  const codes = [
7344
- import_types15.WalletErrorCode.NOT_INSTALLED,
7345
- import_types15.WalletErrorCode.CONNECTION_REJECTED,
7346
- import_types15.WalletErrorCode.CONNECTION_FAILED,
7347
- import_types15.WalletErrorCode.NOT_CONNECTED
8756
+ import_types18.WalletErrorCode.NOT_INSTALLED,
8757
+ import_types18.WalletErrorCode.CONNECTION_REJECTED,
8758
+ import_types18.WalletErrorCode.CONNECTION_FAILED,
8759
+ import_types18.WalletErrorCode.NOT_CONNECTED
7348
8760
  ];
7349
8761
  return codes.includes(this.walletCode);
7350
8762
  }
@@ -7353,9 +8765,9 @@ var WalletError = class extends SIPError {
7353
8765
  */
7354
8766
  isSigningError() {
7355
8767
  const codes = [
7356
- import_types15.WalletErrorCode.SIGNING_REJECTED,
7357
- import_types15.WalletErrorCode.SIGNING_FAILED,
7358
- import_types15.WalletErrorCode.INVALID_MESSAGE
8768
+ import_types18.WalletErrorCode.SIGNING_REJECTED,
8769
+ import_types18.WalletErrorCode.SIGNING_FAILED,
8770
+ import_types18.WalletErrorCode.INVALID_MESSAGE
7359
8771
  ];
7360
8772
  return codes.includes(this.walletCode);
7361
8773
  }
@@ -7364,10 +8776,10 @@ var WalletError = class extends SIPError {
7364
8776
  */
7365
8777
  isTransactionError() {
7366
8778
  const codes = [
7367
- import_types15.WalletErrorCode.INSUFFICIENT_FUNDS,
7368
- import_types15.WalletErrorCode.TRANSACTION_REJECTED,
7369
- import_types15.WalletErrorCode.TRANSACTION_FAILED,
7370
- import_types15.WalletErrorCode.INVALID_TRANSACTION
8779
+ import_types18.WalletErrorCode.INSUFFICIENT_FUNDS,
8780
+ import_types18.WalletErrorCode.TRANSACTION_REJECTED,
8781
+ import_types18.WalletErrorCode.TRANSACTION_FAILED,
8782
+ import_types18.WalletErrorCode.INVALID_TRANSACTION
7371
8783
  ];
7372
8784
  return codes.includes(this.walletCode);
7373
8785
  }
@@ -7376,9 +8788,9 @@ var WalletError = class extends SIPError {
7376
8788
  */
7377
8789
  isPrivacyError() {
7378
8790
  const codes = [
7379
- import_types15.WalletErrorCode.STEALTH_NOT_SUPPORTED,
7380
- import_types15.WalletErrorCode.VIEWING_KEY_NOT_SUPPORTED,
7381
- import_types15.WalletErrorCode.SHIELDED_NOT_SUPPORTED
8791
+ import_types18.WalletErrorCode.STEALTH_NOT_SUPPORTED,
8792
+ import_types18.WalletErrorCode.VIEWING_KEY_NOT_SUPPORTED,
8793
+ import_types18.WalletErrorCode.SHIELDED_NOT_SUPPORTED
7382
8794
  ];
7383
8795
  return codes.includes(this.walletCode);
7384
8796
  }
@@ -7387,10 +8799,10 @@ var WalletError = class extends SIPError {
7387
8799
  */
7388
8800
  isUserRejection() {
7389
8801
  const codes = [
7390
- import_types15.WalletErrorCode.CONNECTION_REJECTED,
7391
- import_types15.WalletErrorCode.SIGNING_REJECTED,
7392
- import_types15.WalletErrorCode.TRANSACTION_REJECTED,
7393
- import_types15.WalletErrorCode.CHAIN_SWITCH_REJECTED
8802
+ import_types18.WalletErrorCode.CONNECTION_REJECTED,
8803
+ import_types18.WalletErrorCode.SIGNING_REJECTED,
8804
+ import_types18.WalletErrorCode.TRANSACTION_REJECTED,
8805
+ import_types18.WalletErrorCode.CHAIN_SWITCH_REJECTED
7394
8806
  ];
7395
8807
  return codes.includes(this.walletCode);
7396
8808
  }
@@ -7398,15 +8810,15 @@ var WalletError = class extends SIPError {
7398
8810
  function notConnectedError() {
7399
8811
  return new WalletError(
7400
8812
  "Wallet not connected. Call connect() first.",
7401
- import_types15.WalletErrorCode.NOT_CONNECTED
8813
+ import_types18.WalletErrorCode.NOT_CONNECTED
7402
8814
  );
7403
8815
  }
7404
- function featureNotSupportedError(feature, code = import_types15.WalletErrorCode.UNKNOWN) {
8816
+ function featureNotSupportedError(feature, code = import_types18.WalletErrorCode.UNKNOWN) {
7405
8817
  return new WalletError(`${feature} is not supported by this wallet`, code);
7406
8818
  }
7407
8819
 
7408
8820
  // src/wallet/base-adapter.ts
7409
- var import_types16 = require("@sip-protocol/types");
8821
+ var import_types19 = require("@sip-protocol/types");
7410
8822
  var BaseWalletAdapter = class {
7411
8823
  _address = "";
7412
8824
  _publicKey = "";
@@ -7569,12 +8981,12 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
7569
8981
  this._connectionState = "connecting";
7570
8982
  if (this.shouldFailConnect) {
7571
8983
  this.setError(
7572
- import_types16.WalletErrorCode.CONNECTION_FAILED,
8984
+ import_types19.WalletErrorCode.CONNECTION_FAILED,
7573
8985
  "Mock connection failure"
7574
8986
  );
7575
8987
  throw new WalletError(
7576
8988
  "Mock connection failure",
7577
- import_types16.WalletErrorCode.CONNECTION_FAILED
8989
+ import_types19.WalletErrorCode.CONNECTION_FAILED
7578
8990
  );
7579
8991
  }
7580
8992
  await new Promise((resolve) => setTimeout(resolve, 10));
@@ -7586,7 +8998,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
7586
8998
  async signMessage(message) {
7587
8999
  this.requireConnected();
7588
9000
  if (this.shouldFailSign) {
7589
- throw new WalletError("Mock signing failure", import_types16.WalletErrorCode.SIGNING_FAILED);
9001
+ throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_FAILED);
7590
9002
  }
7591
9003
  const mockSig = new Uint8Array(64);
7592
9004
  for (let i = 0; i < 64; i++) {
@@ -7601,7 +9013,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
7601
9013
  async signTransaction(tx) {
7602
9014
  this.requireConnected();
7603
9015
  if (this.shouldFailSign) {
7604
- throw new WalletError("Mock signing failure", import_types16.WalletErrorCode.SIGNING_FAILED);
9016
+ throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_FAILED);
7605
9017
  }
7606
9018
  const signature = await this.signMessage(
7607
9019
  new TextEncoder().encode(JSON.stringify(tx.data))
@@ -7783,7 +9195,7 @@ function isPrivateWalletAdapter(adapter) {
7783
9195
  }
7784
9196
 
7785
9197
  // src/wallet/solana/adapter.ts
7786
- var import_types17 = require("@sip-protocol/types");
9198
+ var import_types20 = require("@sip-protocol/types");
7787
9199
 
7788
9200
  // src/wallet/solana/types.ts
7789
9201
  function getSolanaProvider(wallet = "phantom") {
@@ -7904,19 +9316,19 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
7904
9316
  }
7905
9317
  if (!this.provider) {
7906
9318
  this.setError(
7907
- import_types17.WalletErrorCode.NOT_INSTALLED,
9319
+ import_types20.WalletErrorCode.NOT_INSTALLED,
7908
9320
  `${this.walletName} wallet is not installed`
7909
9321
  );
7910
9322
  throw new WalletError(
7911
9323
  `${this.walletName} wallet is not installed`,
7912
- import_types17.WalletErrorCode.NOT_INSTALLED
9324
+ import_types20.WalletErrorCode.NOT_INSTALLED
7913
9325
  );
7914
9326
  }
7915
9327
  const { publicKey } = await this.provider.connect();
7916
9328
  if (!publicKey) {
7917
9329
  throw new WalletError(
7918
9330
  "No public key returned from wallet",
7919
- import_types17.WalletErrorCode.CONNECTION_FAILED
9331
+ import_types20.WalletErrorCode.CONNECTION_FAILED
7920
9332
  );
7921
9333
  }
7922
9334
  this.setupEventHandlers();
@@ -7926,11 +9338,11 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
7926
9338
  } catch (error) {
7927
9339
  const message = error instanceof Error ? error.message : "Connection failed";
7928
9340
  if (message.includes("User rejected") || message.includes("rejected")) {
7929
- this.setError(import_types17.WalletErrorCode.CONNECTION_REJECTED, message);
7930
- throw new WalletError(message, import_types17.WalletErrorCode.CONNECTION_REJECTED);
9341
+ this.setError(import_types20.WalletErrorCode.CONNECTION_REJECTED, message);
9342
+ throw new WalletError(message, import_types20.WalletErrorCode.CONNECTION_REJECTED);
7931
9343
  }
7932
- this.setError(import_types17.WalletErrorCode.CONNECTION_FAILED, message);
7933
- throw error instanceof WalletError ? error : new WalletError(message, import_types17.WalletErrorCode.CONNECTION_FAILED, { cause: error });
9344
+ this.setError(import_types20.WalletErrorCode.CONNECTION_FAILED, message);
9345
+ throw error instanceof WalletError ? error : new WalletError(message, import_types20.WalletErrorCode.CONNECTION_FAILED, { cause: error });
7934
9346
  }
7935
9347
  }
7936
9348
  /**
@@ -7953,7 +9365,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
7953
9365
  async signMessage(message) {
7954
9366
  this.requireConnected();
7955
9367
  if (!this.provider) {
7956
- throw new WalletError("Provider not available", import_types17.WalletErrorCode.NOT_CONNECTED);
9368
+ throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
7957
9369
  }
7958
9370
  try {
7959
9371
  const { signature } = await this.provider.signMessage(message);
@@ -7964,9 +9376,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
7964
9376
  } catch (error) {
7965
9377
  const message2 = error instanceof Error ? error.message : "Signing failed";
7966
9378
  if (message2.includes("User rejected") || message2.includes("rejected")) {
7967
- throw new WalletError(message2, import_types17.WalletErrorCode.SIGNING_REJECTED);
9379
+ throw new WalletError(message2, import_types20.WalletErrorCode.SIGNING_REJECTED);
7968
9380
  }
7969
- throw new WalletError(message2, import_types17.WalletErrorCode.SIGNING_FAILED, {
9381
+ throw new WalletError(message2, import_types20.WalletErrorCode.SIGNING_FAILED, {
7970
9382
  cause: error
7971
9383
  });
7972
9384
  }
@@ -7979,7 +9391,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
7979
9391
  async signTransaction(tx) {
7980
9392
  this.requireConnected();
7981
9393
  if (!this.provider) {
7982
- throw new WalletError("Provider not available", import_types17.WalletErrorCode.NOT_CONNECTED);
9394
+ throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
7983
9395
  }
7984
9396
  try {
7985
9397
  const solTx = tx.data;
@@ -7998,9 +9410,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
7998
9410
  } catch (error) {
7999
9411
  const message = error instanceof Error ? error.message : "Signing failed";
8000
9412
  if (message.includes("User rejected") || message.includes("rejected")) {
8001
- throw new WalletError(message, import_types17.WalletErrorCode.SIGNING_REJECTED);
9413
+ throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_REJECTED);
8002
9414
  }
8003
- throw new WalletError(message, import_types17.WalletErrorCode.SIGNING_FAILED, {
9415
+ throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_FAILED, {
8004
9416
  cause: error
8005
9417
  });
8006
9418
  }
@@ -8011,7 +9423,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
8011
9423
  async signAndSendTransaction(tx) {
8012
9424
  this.requireConnected();
8013
9425
  if (!this.provider) {
8014
- throw new WalletError("Provider not available", import_types17.WalletErrorCode.NOT_CONNECTED);
9426
+ throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
8015
9427
  }
8016
9428
  try {
8017
9429
  const solTx = tx.data;
@@ -8026,12 +9438,12 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
8026
9438
  } catch (error) {
8027
9439
  const message = error instanceof Error ? error.message : "Transaction failed";
8028
9440
  if (message.includes("User rejected") || message.includes("rejected")) {
8029
- throw new WalletError(message, import_types17.WalletErrorCode.TRANSACTION_REJECTED);
9441
+ throw new WalletError(message, import_types20.WalletErrorCode.TRANSACTION_REJECTED);
8030
9442
  }
8031
9443
  if (message.includes("insufficient") || message.includes("Insufficient")) {
8032
- throw new WalletError(message, import_types17.WalletErrorCode.INSUFFICIENT_FUNDS);
9444
+ throw new WalletError(message, import_types20.WalletErrorCode.INSUFFICIENT_FUNDS);
8033
9445
  }
8034
- throw new WalletError(message, import_types17.WalletErrorCode.TRANSACTION_FAILED, {
9446
+ throw new WalletError(message, import_types20.WalletErrorCode.TRANSACTION_FAILED, {
8035
9447
  cause: error
8036
9448
  });
8037
9449
  }
@@ -8044,16 +9456,16 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
8044
9456
  async signAllTransactions(transactions) {
8045
9457
  this.requireConnected();
8046
9458
  if (!this.provider) {
8047
- throw new WalletError("Provider not available", import_types17.WalletErrorCode.NOT_CONNECTED);
9459
+ throw new WalletError("Provider not available", import_types20.WalletErrorCode.NOT_CONNECTED);
8048
9460
  }
8049
9461
  try {
8050
9462
  return await this.provider.signAllTransactions(transactions);
8051
9463
  } catch (error) {
8052
9464
  const message = error instanceof Error ? error.message : "Signing failed";
8053
9465
  if (message.includes("User rejected") || message.includes("rejected")) {
8054
- throw new WalletError(message, import_types17.WalletErrorCode.SIGNING_REJECTED);
9466
+ throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_REJECTED);
8055
9467
  }
8056
- throw new WalletError(message, import_types17.WalletErrorCode.SIGNING_FAILED, {
9468
+ throw new WalletError(message, import_types20.WalletErrorCode.SIGNING_FAILED, {
8057
9469
  cause: error
8058
9470
  });
8059
9471
  }
@@ -8074,7 +9486,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
8074
9486
  } catch (error) {
8075
9487
  throw new WalletError(
8076
9488
  "Failed to get balance",
8077
- import_types17.WalletErrorCode.UNKNOWN,
9489
+ import_types20.WalletErrorCode.UNKNOWN,
8078
9490
  { cause: error }
8079
9491
  );
8080
9492
  }
@@ -8087,7 +9499,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
8087
9499
  if (asset.chain !== "solana") {
8088
9500
  throw new WalletError(
8089
9501
  `Asset chain ${asset.chain} not supported by Solana adapter`,
8090
- import_types17.WalletErrorCode.UNSUPPORTED_CHAIN
9502
+ import_types20.WalletErrorCode.UNSUPPORTED_CHAIN
8091
9503
  );
8092
9504
  }
8093
9505
  if (!asset.address) {
@@ -8205,7 +9617,7 @@ function createSolanaAdapter(config = {}) {
8205
9617
  }
8206
9618
 
8207
9619
  // src/wallet/solana/mock.ts
8208
- var import_types19 = require("@sip-protocol/types");
9620
+ var import_types22 = require("@sip-protocol/types");
8209
9621
  var MockPublicKey = class {
8210
9622
  base58;
8211
9623
  bytes;
@@ -8271,8 +9683,8 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
8271
9683
  this._connectionState = "connecting";
8272
9684
  await this.simulateLatency();
8273
9685
  if (this.shouldFailConnect) {
8274
- this.setError(import_types19.WalletErrorCode.CONNECTION_FAILED, "Mock connection failure");
8275
- throw new WalletError("Mock connection failure", import_types19.WalletErrorCode.CONNECTION_FAILED);
9686
+ this.setError(import_types22.WalletErrorCode.CONNECTION_FAILED, "Mock connection failure");
9687
+ throw new WalletError("Mock connection failure", import_types22.WalletErrorCode.CONNECTION_FAILED);
8276
9688
  }
8277
9689
  const hexPubKey = "0x" + Buffer.from(this.mockPublicKey.toBytes()).toString("hex");
8278
9690
  this.setConnected(this.mockAddress, hexPubKey);
@@ -8291,7 +9703,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
8291
9703
  this.requireConnected();
8292
9704
  await this.simulateLatency();
8293
9705
  if (this.shouldFailSign) {
8294
- throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_REJECTED);
9706
+ throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
8295
9707
  }
8296
9708
  const mockSig = new Uint8Array(64);
8297
9709
  for (let i = 0; i < 64; i++) {
@@ -8309,7 +9721,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
8309
9721
  this.requireConnected();
8310
9722
  await this.simulateLatency();
8311
9723
  if (this.shouldFailSign) {
8312
- throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_REJECTED);
9724
+ throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
8313
9725
  }
8314
9726
  const solTx = tx.data;
8315
9727
  this.signedTransactions.push(solTx);
@@ -8329,10 +9741,10 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
8329
9741
  this.requireConnected();
8330
9742
  await this.simulateLatency();
8331
9743
  if (this.shouldFailSign) {
8332
- throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_REJECTED);
9744
+ throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
8333
9745
  }
8334
9746
  if (this.shouldFailTransaction) {
8335
- throw new WalletError("Mock transaction failure", import_types19.WalletErrorCode.TRANSACTION_FAILED);
9747
+ throw new WalletError("Mock transaction failure", import_types22.WalletErrorCode.TRANSACTION_FAILED);
8336
9748
  }
8337
9749
  const txSig = `mock_tx_${Date.now()}_${Math.random().toString(36).slice(2)}`;
8338
9750
  this.sentTransactions.push(txSig);
@@ -8352,7 +9764,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
8352
9764
  this.requireConnected();
8353
9765
  await this.simulateLatency();
8354
9766
  if (this.shouldFailSign) {
8355
- throw new WalletError("Mock signing failure", import_types19.WalletErrorCode.SIGNING_REJECTED);
9767
+ throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_REJECTED);
8356
9768
  }
8357
9769
  this.signedTransactions.push(...transactions);
8358
9770
  return transactions.map((tx) => {
@@ -8379,7 +9791,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
8379
9791
  if (asset.chain !== "solana") {
8380
9792
  throw new WalletError(
8381
9793
  `Asset chain ${asset.chain} not supported by Solana adapter`,
8382
- import_types19.WalletErrorCode.UNSUPPORTED_CHAIN
9794
+ import_types22.WalletErrorCode.UNSUPPORTED_CHAIN
8383
9795
  );
8384
9796
  }
8385
9797
  if (!asset.address) {
@@ -8548,7 +9960,7 @@ function createMockSolanaAdapter(config = {}) {
8548
9960
  }
8549
9961
 
8550
9962
  // src/wallet/ethereum/adapter.ts
8551
- var import_types21 = require("@sip-protocol/types");
9963
+ var import_types24 = require("@sip-protocol/types");
8552
9964
 
8553
9965
  // src/wallet/ethereum/types.ts
8554
9966
  var EthereumChainId = {
@@ -8690,7 +10102,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8690
10102
  this._connectionState = "error";
8691
10103
  throw new WalletError(
8692
10104
  `${this.walletType} wallet not found. Please install the extension.`,
8693
- import_types21.WalletErrorCode.NOT_INSTALLED
10105
+ import_types24.WalletErrorCode.NOT_INSTALLED
8694
10106
  );
8695
10107
  }
8696
10108
  const accounts = await this.provider.request({
@@ -8700,7 +10112,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8700
10112
  this._connectionState = "error";
8701
10113
  throw new WalletError(
8702
10114
  "No accounts returned from wallet",
8703
- import_types21.WalletErrorCode.CONNECTION_REJECTED
10115
+ import_types24.WalletErrorCode.CONNECTION_REJECTED
8704
10116
  );
8705
10117
  }
8706
10118
  const address = normalizeAddress(accounts[0]);
@@ -8720,12 +10132,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8720
10132
  if (rpcError.code === 4001) {
8721
10133
  throw new WalletError(
8722
10134
  "User rejected connection request",
8723
- import_types21.WalletErrorCode.CONNECTION_REJECTED
10135
+ import_types24.WalletErrorCode.CONNECTION_REJECTED
8724
10136
  );
8725
10137
  }
8726
10138
  throw new WalletError(
8727
10139
  `Failed to connect: ${rpcError.message || String(error)}`,
8728
- import_types21.WalletErrorCode.CONNECTION_FAILED
10140
+ import_types24.WalletErrorCode.CONNECTION_FAILED
8729
10141
  );
8730
10142
  }
8731
10143
  }
@@ -8745,7 +10157,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8745
10157
  if (!this.provider) {
8746
10158
  throw new WalletError(
8747
10159
  "Provider not available",
8748
- import_types21.WalletErrorCode.NOT_CONNECTED
10160
+ import_types24.WalletErrorCode.NOT_CONNECTED
8749
10161
  );
8750
10162
  }
8751
10163
  try {
@@ -8763,12 +10175,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8763
10175
  if (rpcError.code === 4001) {
8764
10176
  throw new WalletError(
8765
10177
  "User rejected signing request",
8766
- import_types21.WalletErrorCode.SIGNING_REJECTED
10178
+ import_types24.WalletErrorCode.SIGNING_REJECTED
8767
10179
  );
8768
10180
  }
8769
10181
  throw new WalletError(
8770
10182
  `Failed to sign message: ${rpcError.message || String(error)}`,
8771
- import_types21.WalletErrorCode.SIGNING_FAILED
10183
+ import_types24.WalletErrorCode.SIGNING_FAILED
8772
10184
  );
8773
10185
  }
8774
10186
  }
@@ -8780,7 +10192,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8780
10192
  if (!this.provider) {
8781
10193
  throw new WalletError(
8782
10194
  "Provider not available",
8783
- import_types21.WalletErrorCode.NOT_CONNECTED
10195
+ import_types24.WalletErrorCode.NOT_CONNECTED
8784
10196
  );
8785
10197
  }
8786
10198
  try {
@@ -8797,12 +10209,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8797
10209
  if (rpcError.code === 4001) {
8798
10210
  throw new WalletError(
8799
10211
  "User rejected signing request",
8800
- import_types21.WalletErrorCode.SIGNING_REJECTED
10212
+ import_types24.WalletErrorCode.SIGNING_REJECTED
8801
10213
  );
8802
10214
  }
8803
10215
  throw new WalletError(
8804
10216
  `Failed to sign typed data: ${rpcError.message || String(error)}`,
8805
- import_types21.WalletErrorCode.SIGNING_FAILED
10217
+ import_types24.WalletErrorCode.SIGNING_FAILED
8806
10218
  );
8807
10219
  }
8808
10220
  }
@@ -8814,7 +10226,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8814
10226
  if (!this.provider) {
8815
10227
  throw new WalletError(
8816
10228
  "Provider not available",
8817
- import_types21.WalletErrorCode.NOT_CONNECTED
10229
+ import_types24.WalletErrorCode.NOT_CONNECTED
8818
10230
  );
8819
10231
  }
8820
10232
  try {
@@ -8842,7 +10254,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8842
10254
  if (rpcError.code === 4001) {
8843
10255
  throw new WalletError(
8844
10256
  "User rejected transaction signing",
8845
- import_types21.WalletErrorCode.SIGNING_REJECTED
10257
+ import_types24.WalletErrorCode.SIGNING_REJECTED
8846
10258
  );
8847
10259
  }
8848
10260
  if (rpcError.code === -32601 || rpcError.message?.includes("not supported")) {
@@ -8860,7 +10272,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8860
10272
  }
8861
10273
  throw new WalletError(
8862
10274
  `Failed to sign transaction: ${rpcError.message || String(error)}`,
8863
- import_types21.WalletErrorCode.TRANSACTION_FAILED
10275
+ import_types24.WalletErrorCode.TRANSACTION_FAILED
8864
10276
  );
8865
10277
  }
8866
10278
  }
@@ -8872,7 +10284,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8872
10284
  if (!this.provider) {
8873
10285
  throw new WalletError(
8874
10286
  "Provider not available",
8875
- import_types21.WalletErrorCode.NOT_CONNECTED
10287
+ import_types24.WalletErrorCode.NOT_CONNECTED
8876
10288
  );
8877
10289
  }
8878
10290
  try {
@@ -8894,12 +10306,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8894
10306
  if (rpcError.code === 4001) {
8895
10307
  throw new WalletError(
8896
10308
  "User rejected transaction",
8897
- import_types21.WalletErrorCode.TRANSACTION_REJECTED
10309
+ import_types24.WalletErrorCode.TRANSACTION_REJECTED
8898
10310
  );
8899
10311
  }
8900
10312
  throw new WalletError(
8901
10313
  `Failed to send transaction: ${rpcError.message || String(error)}`,
8902
- import_types21.WalletErrorCode.TRANSACTION_FAILED
10314
+ import_types24.WalletErrorCode.TRANSACTION_FAILED
8903
10315
  );
8904
10316
  }
8905
10317
  }
@@ -8934,7 +10346,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8934
10346
  } catch (error) {
8935
10347
  throw new WalletError(
8936
10348
  `Failed to fetch balance: ${String(error)}`,
8937
- import_types21.WalletErrorCode.UNKNOWN
10349
+ import_types24.WalletErrorCode.UNKNOWN
8938
10350
  );
8939
10351
  }
8940
10352
  }
@@ -8946,7 +10358,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8946
10358
  if (asset.chain !== "ethereum") {
8947
10359
  throw new WalletError(
8948
10360
  `Asset chain ${asset.chain} not supported by Ethereum adapter`,
8949
- import_types21.WalletErrorCode.UNSUPPORTED_CHAIN
10361
+ import_types24.WalletErrorCode.UNSUPPORTED_CHAIN
8950
10362
  );
8951
10363
  }
8952
10364
  if (!asset.address) {
@@ -8971,7 +10383,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8971
10383
  } catch (error) {
8972
10384
  throw new WalletError(
8973
10385
  `Failed to fetch token balance: ${String(error)}`,
8974
- import_types21.WalletErrorCode.UNKNOWN
10386
+ import_types24.WalletErrorCode.UNKNOWN
8975
10387
  );
8976
10388
  }
8977
10389
  }
@@ -8983,7 +10395,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8983
10395
  if (!this.provider) {
8984
10396
  throw new WalletError(
8985
10397
  "Provider not available",
8986
- import_types21.WalletErrorCode.NOT_CONNECTED
10398
+ import_types24.WalletErrorCode.NOT_CONNECTED
8987
10399
  );
8988
10400
  }
8989
10401
  try {
@@ -8998,18 +10410,18 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
8998
10410
  if (rpcError.code === 4001) {
8999
10411
  throw new WalletError(
9000
10412
  "User rejected chain switch",
9001
- import_types21.WalletErrorCode.CHAIN_SWITCH_REJECTED
10413
+ import_types24.WalletErrorCode.CHAIN_SWITCH_REJECTED
9002
10414
  );
9003
10415
  }
9004
10416
  if (rpcError.code === 4902) {
9005
10417
  throw new WalletError(
9006
10418
  `Chain ${chainId} not added to wallet`,
9007
- import_types21.WalletErrorCode.UNSUPPORTED_CHAIN
10419
+ import_types24.WalletErrorCode.UNSUPPORTED_CHAIN
9008
10420
  );
9009
10421
  }
9010
10422
  throw new WalletError(
9011
10423
  `Failed to switch chain: ${rpcError.message || String(error)}`,
9012
- import_types21.WalletErrorCode.CHAIN_SWITCH_FAILED
10424
+ import_types24.WalletErrorCode.CHAIN_SWITCH_FAILED
9013
10425
  );
9014
10426
  }
9015
10427
  }
@@ -9045,7 +10457,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
9045
10457
  }
9046
10458
  throw new WalletError(
9047
10459
  `Transaction ${txHash} not confirmed after ${maxAttempts * 5} seconds`,
9048
- import_types21.WalletErrorCode.TRANSACTION_FAILED
10460
+ import_types24.WalletErrorCode.TRANSACTION_FAILED
9049
10461
  );
9050
10462
  }
9051
10463
  /**
@@ -9119,7 +10531,7 @@ function createEthereumAdapter(config) {
9119
10531
  }
9120
10532
 
9121
10533
  // src/wallet/ethereum/mock.ts
9122
- var import_types23 = require("@sip-protocol/types");
10534
+ var import_types26 = require("@sip-protocol/types");
9123
10535
  var MockEthereumAdapter = class extends BaseWalletAdapter {
9124
10536
  chain = "ethereum";
9125
10537
  name = "mock-ethereum";
@@ -9160,7 +10572,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
9160
10572
  this._connectionState = "error";
9161
10573
  throw new WalletError(
9162
10574
  "Mock connection rejected",
9163
- import_types23.WalletErrorCode.CONNECTION_REJECTED
10575
+ import_types26.WalletErrorCode.CONNECTION_REJECTED
9164
10576
  );
9165
10577
  }
9166
10578
  await new Promise((resolve) => setTimeout(resolve, 10));
@@ -9172,7 +10584,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
9172
10584
  this._connectionState = "error";
9173
10585
  throw new WalletError(
9174
10586
  `Mock connection failed: ${String(error)}`,
9175
- import_types23.WalletErrorCode.CONNECTION_FAILED
10587
+ import_types26.WalletErrorCode.CONNECTION_FAILED
9176
10588
  );
9177
10589
  }
9178
10590
  }
@@ -9190,7 +10602,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
9190
10602
  if (this._shouldFailSign) {
9191
10603
  throw new WalletError(
9192
10604
  "Mock signing rejected",
9193
- import_types23.WalletErrorCode.SIGNING_REJECTED
10605
+ import_types26.WalletErrorCode.SIGNING_REJECTED
9194
10606
  );
9195
10607
  }
9196
10608
  const msgHex = Buffer.from(message).toString("hex");
@@ -9208,7 +10620,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
9208
10620
  if (this._shouldFailSign) {
9209
10621
  throw new WalletError(
9210
10622
  "Mock signing rejected",
9211
- import_types23.WalletErrorCode.SIGNING_REJECTED
10623
+ import_types26.WalletErrorCode.SIGNING_REJECTED
9212
10624
  );
9213
10625
  }
9214
10626
  const mockSig = `0x${"1".repeat(130)}`;
@@ -9225,7 +10637,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
9225
10637
  if (this._shouldFailSign) {
9226
10638
  throw new WalletError(
9227
10639
  "Mock signing rejected",
9228
- import_types23.WalletErrorCode.SIGNING_REJECTED
10640
+ import_types26.WalletErrorCode.SIGNING_REJECTED
9229
10641
  );
9230
10642
  }
9231
10643
  this._signedTransactions.push(tx);
@@ -9250,7 +10662,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
9250
10662
  if (this._shouldFailTransaction) {
9251
10663
  throw new WalletError(
9252
10664
  "Mock transaction failed",
9253
- import_types23.WalletErrorCode.TRANSACTION_FAILED
10665
+ import_types26.WalletErrorCode.TRANSACTION_FAILED
9254
10666
  );
9255
10667
  }
9256
10668
  this._signedTransactions.push(tx);
@@ -9280,7 +10692,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
9280
10692
  if (asset.chain !== "ethereum") {
9281
10693
  throw new WalletError(
9282
10694
  `Asset chain ${asset.chain} not supported by Ethereum adapter`,
9283
- import_types23.WalletErrorCode.UNSUPPORTED_CHAIN
10695
+ import_types26.WalletErrorCode.UNSUPPORTED_CHAIN
9284
10696
  );
9285
10697
  }
9286
10698
  if (!asset.address) {
@@ -9559,7 +10971,7 @@ function getAvailableTransports() {
9559
10971
  }
9560
10972
 
9561
10973
  // src/wallet/hardware/ledger.ts
9562
- var import_types26 = require("@sip-protocol/types");
10974
+ var import_types29 = require("@sip-protocol/types");
9563
10975
  var LedgerWalletAdapter = class extends BaseWalletAdapter {
9564
10976
  chain;
9565
10977
  name = "ledger";
@@ -9712,7 +11124,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
9712
11124
  async getBalance() {
9713
11125
  throw new WalletError(
9714
11126
  "Hardware wallets do not track balances. Use an RPC provider.",
9715
- import_types26.WalletErrorCode.UNSUPPORTED_OPERATION
11127
+ import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
9716
11128
  );
9717
11129
  }
9718
11130
  /**
@@ -9723,7 +11135,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
9723
11135
  async getTokenBalance(_asset) {
9724
11136
  throw new WalletError(
9725
11137
  "Hardware wallets do not track balances. Use an RPC provider.",
9726
- import_types26.WalletErrorCode.UNSUPPORTED_OPERATION
11138
+ import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
9727
11139
  );
9728
11140
  }
9729
11141
  // ─── Account Management ─────────────────────────────────────────────────────
@@ -10011,7 +11423,7 @@ function createLedgerAdapter(config) {
10011
11423
  }
10012
11424
 
10013
11425
  // src/wallet/hardware/trezor.ts
10014
- var import_types28 = require("@sip-protocol/types");
11426
+ var import_types31 = require("@sip-protocol/types");
10015
11427
  var TrezorWalletAdapter = class extends BaseWalletAdapter {
10016
11428
  chain;
10017
11429
  name = "trezor";
@@ -10157,7 +11569,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
10157
11569
  async getBalance() {
10158
11570
  throw new WalletError(
10159
11571
  "Hardware wallets do not track balances. Use an RPC provider.",
10160
- import_types28.WalletErrorCode.UNSUPPORTED_OPERATION
11572
+ import_types31.WalletErrorCode.UNSUPPORTED_OPERATION
10161
11573
  );
10162
11574
  }
10163
11575
  /**
@@ -10168,7 +11580,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
10168
11580
  async getTokenBalance(_asset) {
10169
11581
  throw new WalletError(
10170
11582
  "Hardware wallets do not track balances. Use an RPC provider.",
10171
- import_types28.WalletErrorCode.UNSUPPORTED_OPERATION
11583
+ import_types31.WalletErrorCode.UNSUPPORTED_OPERATION
10172
11584
  );
10173
11585
  }
10174
11586
  // ─── Account Management ─────────────────────────────────────────────────────
@@ -10449,8 +11861,8 @@ function createTrezorAdapter(config) {
10449
11861
  }
10450
11862
 
10451
11863
  // src/wallet/hardware/mock.ts
10452
- var import_types30 = require("@sip-protocol/types");
10453
- var import_utils14 = require("@noble/hashes/utils");
11864
+ var import_types33 = require("@sip-protocol/types");
11865
+ var import_utils15 = require("@noble/hashes/utils");
10454
11866
  var MockLedgerAdapter = class extends BaseWalletAdapter {
10455
11867
  chain;
10456
11868
  name = "mock-ledger";
@@ -10597,7 +12009,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
10597
12009
  async getBalance() {
10598
12010
  throw new WalletError(
10599
12011
  "Hardware wallets do not track balances",
10600
- import_types30.WalletErrorCode.UNSUPPORTED_OPERATION
12012
+ import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
10601
12013
  );
10602
12014
  }
10603
12015
  /**
@@ -10606,7 +12018,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
10606
12018
  async getTokenBalance(_asset) {
10607
12019
  throw new WalletError(
10608
12020
  "Hardware wallets do not track balances",
10609
- import_types30.WalletErrorCode.UNSUPPORTED_OPERATION
12021
+ import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
10610
12022
  );
10611
12023
  }
10612
12024
  /**
@@ -10695,15 +12107,15 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
10695
12107
  }
10696
12108
  }
10697
12109
  generateMockAddress(index) {
10698
- const bytes = (0, import_utils14.randomBytes)(20);
12110
+ const bytes = (0, import_utils15.randomBytes)(20);
10699
12111
  bytes[0] = index;
10700
- return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
12112
+ return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
10701
12113
  }
10702
12114
  generateMockPublicKey(index) {
10703
- const bytes = (0, import_utils14.randomBytes)(33);
12115
+ const bytes = (0, import_utils15.randomBytes)(33);
10704
12116
  bytes[0] = 2;
10705
12117
  bytes[1] = index;
10706
- return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
12118
+ return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
10707
12119
  }
10708
12120
  generateMockSignature(data) {
10709
12121
  const sig = new Uint8Array(65);
@@ -10712,7 +12124,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
10712
12124
  sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 11;
10713
12125
  }
10714
12126
  sig[64] = 27;
10715
- return `0x${(0, import_utils14.bytesToHex)(sig)}`;
12127
+ return `0x${(0, import_utils15.bytesToHex)(sig)}`;
10716
12128
  }
10717
12129
  delay(ms) {
10718
12130
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -10836,13 +12248,13 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
10836
12248
  async getBalance() {
10837
12249
  throw new WalletError(
10838
12250
  "Hardware wallets do not track balances",
10839
- import_types30.WalletErrorCode.UNSUPPORTED_OPERATION
12251
+ import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
10840
12252
  );
10841
12253
  }
10842
12254
  async getTokenBalance(_asset) {
10843
12255
  throw new WalletError(
10844
12256
  "Hardware wallets do not track balances",
10845
- import_types30.WalletErrorCode.UNSUPPORTED_OPERATION
12257
+ import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
10846
12258
  );
10847
12259
  }
10848
12260
  async getAccounts(startIndex = 0, count = 5) {
@@ -10901,15 +12313,15 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
10901
12313
  }
10902
12314
  }
10903
12315
  generateMockAddress(index) {
10904
- const bytes = (0, import_utils14.randomBytes)(20);
12316
+ const bytes = (0, import_utils15.randomBytes)(20);
10905
12317
  bytes[0] = index + 100;
10906
- return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
12318
+ return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
10907
12319
  }
10908
12320
  generateMockPublicKey(index) {
10909
- const bytes = (0, import_utils14.randomBytes)(33);
12321
+ const bytes = (0, import_utils15.randomBytes)(33);
10910
12322
  bytes[0] = 3;
10911
12323
  bytes[1] = index + 100;
10912
- return `0x${(0, import_utils14.bytesToHex)(bytes)}`;
12324
+ return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
10913
12325
  }
10914
12326
  generateMockSignature(data) {
10915
12327
  const sig = new Uint8Array(65);
@@ -10918,7 +12330,7 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
10918
12330
  sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 17;
10919
12331
  }
10920
12332
  sig[64] = 28;
10921
- return `0x${(0, import_utils14.bytesToHex)(sig)}`;
12333
+ return `0x${(0, import_utils15.bytesToHex)(sig)}`;
10922
12334
  }
10923
12335
  delay(ms) {
10924
12336
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -10932,7 +12344,7 @@ function createMockTrezorAdapter(config) {
10932
12344
  }
10933
12345
 
10934
12346
  // src/wallet/index.ts
10935
- var import_types33 = require("@sip-protocol/types");
12347
+ var import_types36 = require("@sip-protocol/types");
10936
12348
 
10937
12349
  // src/proofs/browser.ts
10938
12350
  var import_noir_js = require("@noir-lang/noir_js");
@@ -10940,7 +12352,7 @@ var import_bb = require("@aztec/bb.js");
10940
12352
  var import_secp256k14 = require("@noble/curves/secp256k1");
10941
12353
 
10942
12354
  // src/proofs/circuits/funding_proof.json
10943
- var funding_proof_default = { noir_version: "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", hash: "13977419962319221401", abi: { parameters: [{ name: "commitment_hash", type: { kind: "field" }, visibility: "public" }, { name: "minimum_required", type: { kind: "integer", sign: "unsigned", width: 64 }, visibility: "public" }, { name: "asset_id", type: { kind: "field" }, visibility: "public" }, { name: "balance", type: { kind: "integer", sign: "unsigned", width: 64 }, visibility: "private" }, { name: "blinding", type: { kind: "field" }, visibility: "private" }], return_type: null, error_types: { "2900908756532713827": { error_kind: "string", string: "Insufficient balance" }, "15764276373176857197": { error_kind: "string", string: "Stack too deep" }, "17719928407928969950": { error_kind: "string", string: "Commitment hash mismatch" } } }, bytecode: "H4sIAAAAAAAA/+VYbUhTURg+d7vTTdfmnJlK1g360LJolUEUJaUZ/qgooS9Taq5aoCudlhHV6LuglPplBH0gLUuiCCv6osA+LImItCQ0wUyRTJSJWkG7ds58PV53PzT60Qt3z+65z/ue533u8exeGfQnWIxZm+zZ4V4043PGe6gx8kcCNabGYyw+V6HBQcY4jDMzl+c0WC7E3l2ZVO5yrd0YM7t5WcG9HUVLGjxn2nEdDkkKRi3OZfxd5JC0XNiXBmMAYRAz+IEEqgJLTfS3mh+ibiGuy2hkaAhAykxlZPYKNYn1yvqZmJ5XrJaEReMLeOMDMWppknoYAsRMChyam0ZxGa10DWgkDWWRMkN1GINoklxDoQAxQ3VIuqFB0jX0mcbfgAAwxmHULiwwfYjX5ce2B+RZfo6u/FXgPtf2al7hIvuaOKsjZT3kRu1P7y3bb0mbdDWiU/+iZvai19f21Lw0htW5HlTE9JzZCLlSgnA1Ke7tua9OzFmVvuFRdeP8i5Gnjhgz5q2cfHpnfVLRw0YV5HLn3zyO+7Gmp4t1JNZEPevtzkm98TxhL9u6OWrz0conkyFXLOBCC0T9PvGowxhEaRUJJtj7ofceo9DILuRgpGwhGzAaaZLchQwFiC1kA5K+kI1I2Q0bJBDJ60ePlBkagtFEk+QaCgWIGRqCpBtqQv/GUBVSZmgoRjNNkmsoFCBmaCiSbqhZugbfFqIHYxzG/3mrhdyxiR0l3F7X0xMHJ5S40ppvWkIm3v9mjoi8X+u5VOZOXga56tK2uU2Lp0YzRdapz9YVt7SWXI8b437JlS64cfJ4RbcbcuVomN59L+HLccNy867Pq3N7m4qj81bY45uuHCjfctZp6aiqgtwZVcfertv6YPXdw0UzRoUf2ZR6vbz06bvu9CmV+77felJ4EHLFgjyg8evEgNGIMQSjCWMoRjOlXSTUMrhy6jJh3o/R3iOcuiD3LQpypcwpkevTwRvAov79o68QGrjpCL01WT92dk2MXBwDa5LNqa7Ycwe9b/HQ+eTnNdNmdWTtcOTaMrbZs53j8KiWYpNXMg5JCgauFvn5B5Lp1wGZ8yeTh6Hh6Cc5CvJ9D6yJIJ/Wwoce9f8fAFE5/IOdAXw3ghw+kkA9hrq2VGDeYfaURPJZZfmqUDR4flKLf1jle4zA52oBLlxLGsAR8hUJjDECdWhv4H3gMJotqGZ8fXzBtPC5jhX5h+pTy/aFXY79aoxoy1uQ3/PJQfei8qNd70eDXqAf6A/5m1Dm/+5kMifRpUGD/YL1WYofjVEH5oc6OeQ/ais81bdTZmWZqHw+SM98n1H4e6Y9x2Z12vNtGd6NybbVlpOxM8/htNuyncQJLcgiFeWsSJIfrCx/wGsporTAur4JMbICecwQ5yoK/XHpcTimF7hGapLfCqiX9PEbVAIFlc4UAAA=", debug_symbols: "pZbNbsMgDMffhXMO2HwE8irTVKUtmyJFaZUlk6aq7z6TQpYcYBW9QN3k/4sx2PjGzu44fx664ePyxZq3GzuOXd93n4f+cmqn7jLQvzfG/QCaNVgxqB+TYY2gybJGVgzpDXm/VyzKDtPonFdtOES/tqMbJtYMc99X7Lvt5+Wlr2s7LPPUjvSUV8wNZ5oJ+NH1zv+6V39qnpYajkFsUK9yqHd6SOu1lEGvlSjRG4h6Y4r0cfE1T34/t36I/hsJq149HT/gwgYAcKWKCGBWgq5ThDpD0BCDCHrjA9gdwWQI1kYfkGOSYNMECaACQYIyJQQUdSRgrcoI8CoBxROEbCSNjnthbQkBuYpHEgEhRfDhTiGEkjEQQnNe4gRgvTqhRdKJzKmUysZ1SC03tUUXImwKkUsukLG+AdhkemIGgWjW3BDbGrkPBWaKFBpct9So5JYivpxfWcRzCfYPAl5GPJVi2XBaHmsuWrAlCAE83hsCQJQh/pIMbP0qAtN5mjvfyNfLAyXfne93stpTN+5bE6SHFRPLKJdRLaP210/FqFkB2h/zsOzDAupW/CUF4HOAZoIglTkQwZbBVsHWwfatjw29jz/23+3YtcfeeU+8r/Nwio6ROf1c45PYVV3Hy8md59H5RWxaKxrfKKfQvt/9Qn8B", file_map: { "16": { source: "use crate::cmp::Eq;\nuse crate::hash::Hash;\nuse crate::ops::arith::{Add, Neg, Sub};\n\n/// A point on the embedded elliptic curve\n/// By definition, the base field of the embedded curve is the scalar field of the proof system curve, i.e the Noir Field.\n/// x and y denotes the Weierstrass coordinates of the point, if is_infinite is false.\npub struct EmbeddedCurvePoint {\n pub x: Field,\n pub y: Field,\n pub is_infinite: bool,\n}\n\nimpl EmbeddedCurvePoint {\n /// Elliptic curve point doubling operation\n /// returns the doubled point of a point P, i.e P+P\n pub fn double(self) -> EmbeddedCurvePoint {\n embedded_curve_add(self, self)\n }\n\n /// Returns the null element of the curve; 'the point at infinity'\n pub fn point_at_infinity() -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: 0, y: 0, is_infinite: true }\n }\n\n /// Returns the curve's generator point.\n pub fn generator() -> EmbeddedCurvePoint {\n // Generator point for the grumpkin curve (y^2 = x^3 - 17)\n EmbeddedCurvePoint {\n x: 1,\n y: 17631683881184975370165255887551781615748388533673675138860, // sqrt(-16)\n is_infinite: false,\n }\n }\n}\n\nimpl Add for EmbeddedCurvePoint {\n /// Adds two points P+Q, using the curve addition formula, and also handles point at infinity\n fn add(self, other: EmbeddedCurvePoint) -> EmbeddedCurvePoint {\n embedded_curve_add(self, other)\n }\n}\n\nimpl Sub for EmbeddedCurvePoint {\n /// Points subtraction operation, using addition and negation\n fn sub(self, other: EmbeddedCurvePoint) -> EmbeddedCurvePoint {\n self + other.neg()\n }\n}\n\nimpl Neg for EmbeddedCurvePoint {\n /// Negates a point P, i.e returns -P, by negating the y coordinate.\n /// If the point is at infinity, then the result is also at infinity.\n fn neg(self) -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: self.x, y: -self.y, is_infinite: self.is_infinite }\n }\n}\n\nimpl Eq for EmbeddedCurvePoint {\n /// Checks whether two points are equal\n fn eq(self: Self, b: EmbeddedCurvePoint) -> bool {\n (self.is_infinite & b.is_infinite)\n | ((self.is_infinite == b.is_infinite) & (self.x == b.x) & (self.y == b.y))\n }\n}\n\nimpl Hash for EmbeddedCurvePoint {\n fn hash<H>(self, state: &mut H)\n where\n H: crate::hash::Hasher,\n {\n if self.is_infinite {\n self.is_infinite.hash(state);\n } else {\n self.x.hash(state);\n self.y.hash(state);\n }\n }\n}\n\n/// Scalar for the embedded curve represented as low and high limbs\n/// By definition, the scalar field of the embedded curve is base field of the proving system curve.\n/// It may not fit into a Field element, so it is represented with two Field elements; its low and high limbs.\npub struct EmbeddedCurveScalar {\n pub lo: Field,\n pub hi: Field,\n}\n\nimpl EmbeddedCurveScalar {\n pub fn new(lo: Field, hi: Field) -> Self {\n EmbeddedCurveScalar { lo, hi }\n }\n\n #[field(bn254)]\n pub fn from_field(scalar: Field) -> EmbeddedCurveScalar {\n let (a, b) = crate::field::bn254::decompose(scalar);\n EmbeddedCurveScalar { lo: a, hi: b }\n }\n\n //Bytes to scalar: take the first (after the specified offset) 16 bytes of the input as the lo value, and the next 16 bytes as the hi value\n #[field(bn254)]\n pub(crate) fn from_bytes(bytes: [u8; 64], offset: u32) -> EmbeddedCurveScalar {\n let mut v = 1;\n let mut lo = 0 as Field;\n let mut hi = 0 as Field;\n for i in 0..16 {\n lo = lo + (bytes[offset + 31 - i] as Field) * v;\n hi = hi + (bytes[offset + 15 - i] as Field) * v;\n v = v * 256;\n }\n let sig_s = crate::embedded_curve_ops::EmbeddedCurveScalar { lo, hi };\n sig_s\n }\n}\n\nimpl Eq for EmbeddedCurveScalar {\n fn eq(self, other: Self) -> bool {\n (other.hi == self.hi) & (other.lo == self.lo)\n }\n}\n\nimpl Hash for EmbeddedCurveScalar {\n fn hash<H>(self, state: &mut H)\n where\n H: crate::hash::Hasher,\n {\n self.hi.hash(state);\n self.lo.hash(state);\n }\n}\n\n// Computes a multi scalar multiplication over the embedded curve.\n// For bn254, We have Grumpkin and Baby JubJub.\n// For bls12-381, we have JubJub and Bandersnatch.\n//\n// The embedded curve being used is decided by the\n// underlying proof system.\n// docs:start:multi_scalar_mul\npub fn multi_scalar_mul<let N: u32>(\n points: [EmbeddedCurvePoint; N],\n scalars: [EmbeddedCurveScalar; N],\n) -> EmbeddedCurvePoint\n// docs:end:multi_scalar_mul\n{\n multi_scalar_mul_array_return(points, scalars, true)[0]\n}\n\n#[foreign(multi_scalar_mul)]\npub(crate) fn multi_scalar_mul_array_return<let N: u32>(\n points: [EmbeddedCurvePoint; N],\n scalars: [EmbeddedCurveScalar; N],\n predicate: bool,\n) -> [EmbeddedCurvePoint; 1] {}\n\n// docs:start:fixed_base_scalar_mul\npub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint\n// docs:end:fixed_base_scalar_mul\n{\n multi_scalar_mul([EmbeddedCurvePoint::generator()], [scalar])\n}\n\n/// This function only assumes that the points are on the curve\n/// It handles corner cases around the infinity point causing some overhead compared to embedded_curve_add_not_nul and embedded_curve_add_unsafe\n// docs:start:embedded_curve_add\npub fn embedded_curve_add(\n point1: EmbeddedCurvePoint,\n point2: EmbeddedCurvePoint,\n) -> EmbeddedCurvePoint {\n // docs:end:embedded_curve_add\n if crate::runtime::is_unconstrained() {\n // `embedded_curve_add_unsafe` requires the inputs not to be the infinity point, so we check it here.\n // This is because `embedded_curve_add_unsafe` uses the `embedded_curve_add` opcode.\n // For efficiency, the backend does not check the inputs for the infinity point, but it assumes that they are not the infinity point\n // so that it can apply the ec addition formula directly.\n if point1.is_infinite {\n point2\n } else if point2.is_infinite {\n point1\n } else {\n embedded_curve_add_unsafe(point1, point2)\n }\n } else {\n // In a constrained context, we also need to check the inputs are not the infinity point because we also use `embedded_curve_add_unsafe`\n // However we also need to identify the case where the two inputs are the same, because then\n // the addition formula does not work and we need to use the doubling formula instead.\n // In unconstrained context, we can check directly if the input values are the same when solving the opcode, so it is not an issue.\n\n // x_coordinates_match is true if both abscissae are the same\n let x_coordinates_match = point1.x == point2.x;\n // y_coordinates_match is true if both ordinates are the same\n let y_coordinates_match = point1.y == point2.y;\n // double_predicate is true if both abscissae and ordinates are the same\n let double_predicate = (x_coordinates_match & y_coordinates_match);\n // If the abscissae are the same, but not the ordinates, then one point is the opposite of the other\n let infinity_predicate = (x_coordinates_match & !y_coordinates_match);\n\n // `embedded_curve_add_unsafe` would not perform doubling, even if the inputs point1 and point2 are the same, because it cannot know this without adding some logic (and some constraints)\n // However we did this logic when we computed `double_predicate`, so we set the result to 2*point1 if point1 and point2 are the same\n let mut result = if double_predicate {\n // `embedded_curve_add_unsafe` is doing a doubling if the input is the same variable, because in this case it is guaranteed (at 'compile time') that the input is the same.\n embedded_curve_add_unsafe(point1, point1)\n } else {\n let point1_1 = EmbeddedCurvePoint {\n x: point1.x + (x_coordinates_match as Field),\n y: point1.y,\n is_infinite: false,\n };\n let point2_1 = EmbeddedCurvePoint { x: point2.x, y: point2.y, is_infinite: false };\n // point1_1 is guaranteed to have a different abscissa than point2:\n // - if x_coordinates_match is 0, that means point1.x != point2.x, and point1_1.x = point1.x + 0\n // - if x_coordinates_match is 1, that means point1.x = point2.x, but point1_1.x = point1.x + 1 in this case\n // Because the abscissa is different, the addition formula is guaranteed to succeed, so we can safely use `embedded_curve_add_unsafe`\n // Note that this computation may be garbage: if x_coordinates_match is 1, or if one of the input is the point at infinity.\n // therefore we only want to do this if we need the result, otherwise it needs to be eliminated as a dead instruction, lest we want the circuit to fail.\n embedded_curve_add_unsafe(point1_1, point2_1)\n };\n\n // Same logic as above for unconstrained context, we set the proper result when one of the inputs is the infinity point\n if point1.is_infinite {\n result = point2;\n }\n if point2.is_infinite {\n result = point1;\n }\n\n // Finally, we set the is_infinity flag of the result:\n // Opposite points should sum into the infinity point, however, if one of them is point at infinity, their coordinates are not meaningful\n // so we should not use the fact that the inputs are opposite in this case:\n let mut result_is_infinity =\n infinity_predicate & (!point1.is_infinite & !point2.is_infinite);\n // However, if both of them are at infinity, then the result is also at infinity\n result.is_infinite = result_is_infinity | (point1.is_infinite & point2.is_infinite);\n result\n }\n}\n\n#[foreign(embedded_curve_add)]\nfn embedded_curve_add_array_return(\n _point1: EmbeddedCurvePoint,\n _point2: EmbeddedCurvePoint,\n _predicate: bool,\n) -> [EmbeddedCurvePoint; 1] {}\n\n/// This function assumes that:\n/// The points are on the curve, and\n/// The points don't share an x-coordinate, and\n/// Neither point is the infinity point.\n/// If it is used with correct input, the function ensures the correct non-zero result is returned.\n/// Except for points on the curve, the other assumptions are checked by the function. It will cause assertion failure if they are not respected.\npub fn embedded_curve_add_not_nul(\n point1: EmbeddedCurvePoint,\n point2: EmbeddedCurvePoint,\n) -> EmbeddedCurvePoint {\n assert(point1.x != point2.x);\n assert(!point1.is_infinite);\n assert(!point2.is_infinite);\n // Ensure is_infinite is comptime\n let point1_1 = EmbeddedCurvePoint { x: point1.x, y: point1.y, is_infinite: false };\n let point2_1 = EmbeddedCurvePoint { x: point2.x, y: point2.y, is_infinite: false };\n embedded_curve_add_unsafe(point1_1, point2_1)\n}\n\n/// Unsafe ec addition\n/// If the inputs are the same, it will perform a doubling, but only if point1 and point2 are the same variable.\n/// If they have the same value but are different variables, the result will be incorrect because in this case\n/// it assumes (but does not check) that the points' x-coordinates are not equal.\n/// It also assumes neither point is the infinity point.\npub fn embedded_curve_add_unsafe(\n point1: EmbeddedCurvePoint,\n point2: EmbeddedCurvePoint,\n) -> EmbeddedCurvePoint {\n embedded_curve_add_array_return(point1, point2, true)[0]\n}\n", path: "std/embedded_curve_ops.nr" }, "17": { source: `use crate::field::field_less_than;
12355
+ var funding_proof_default = { noir_version: "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", hash: "3859649086066977477", abi: { parameters: [{ name: "minimum_required", type: { kind: "integer", sign: "unsigned", width: 64 }, visibility: "public" }, { name: "asset_id", type: { kind: "field" }, visibility: "public" }, { name: "balance", type: { kind: "integer", sign: "unsigned", width: 64 }, visibility: "private" }, { name: "blinding", type: { kind: "field" }, visibility: "private" }], return_type: { abi_type: { kind: "array", length: 32, type: { kind: "integer", sign: "unsigned", width: 8 } }, visibility: "public" }, error_types: { "2900908756532713827": { error_kind: "string", string: "Insufficient balance" }, "15764276373176857197": { error_kind: "string", string: "Stack too deep" }, "15835548349546956319": { error_kind: "string", string: "Field failed to decompose into specified 32 limbs" } } }, bytecode: "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", debug_symbols: "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", file_map: { "17": { source: `use crate::field::field_less_than;
10944
12356
  use crate::runtime::is_unconstrained;
10945
12357
 
10946
12358
  // The low and high decomposition of the field modulus
@@ -11143,105 +12555,7 @@ mod tests {
11143
12555
  assert(!lt(TWO_POW_128, TWO_POW_128 - 1));
11144
12556
  }
11145
12557
  }
11146
- `, path: "std/field/bn254.nr" }, "19": { source: '// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated("This function has been moved to std::hash::keccakf1600")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you\'re working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n "Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3<let N: u32>(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment<let N: u32>(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator<let N: u32>(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash<let N: u32>(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator<let N: u32>(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators("pedersen_hash_length".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation<let N: u32>(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal<let N: u32>(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash<H>(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault<H>;\n\nimpl<H> BuildHasher for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl<H> Default for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash<H>(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl<T, let N: u32> Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<T> Hash for [T]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<A, B> Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl<A, B, C> Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl<A, B, C, D> Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl<A, B, C, D, E> Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n', path: "std/hash/mod.nr" }, "50": { source: `/// Funding Proof Circuit
11147
- ///
11148
- /// Proves: "I have sufficient funds to fulfill this intent, without revealing
11149
- /// my exact balance, wallet address, or source of funds."
11150
- ///
11151
- /// @see docs/specs/FUNDING-PROOF.md
11152
-
11153
- use std::hash::pedersen_hash;
11154
- use std::hash::pedersen_commitment;
11155
-
11156
- // --- Main Circuit ---
11157
-
11158
- /// Main funding proof entry point
11159
- ///
11160
- /// Public inputs: commitment_hash, minimum_required, asset_id
11161
- /// Private inputs: balance, blinding
11162
- ///
11163
- /// Constraints:
11164
- /// 1. balance >= minimum_required (range proof via u64)
11165
- /// 2. commitment = Pedersen(balance, blinding)
11166
- /// 3. hash(commitment, asset_id) == commitment_hash
11167
- pub fn main(
11168
- commitment_hash: pub Field,
11169
- minimum_required: pub u64,
11170
- asset_id: pub Field,
11171
- balance: u64,
11172
- blinding: Field,
11173
- ) {
11174
- // Constraint 1: Sufficient Funds
11175
- assert(balance >= minimum_required, "Insufficient balance");
11176
-
11177
- // Constraint 2: Compute Pedersen Commitment
11178
- // Uses Noir's built-in pedersen_commitment which returns (x, y) point
11179
- let commitment = pedersen_commitment([balance as Field, blinding]);
11180
-
11181
- // Constraint 3: Verify Commitment Hash
11182
- let computed_hash = pedersen_hash([commitment.x, commitment.y, asset_id]);
11183
- assert(computed_hash == commitment_hash, "Commitment hash mismatch");
11184
- }
11185
-
11186
- // --- Tests ---
11187
-
11188
- #[test]
11189
- fn test_valid_funding_proof() {
11190
- let balance: u64 = 100;
11191
- let minimum_required: u64 = 50;
11192
- let blinding: Field = 12345;
11193
- let asset_id: Field = 0xABCD;
11194
-
11195
- // Compute commitment using same method as circuit
11196
- let commitment = pedersen_commitment([balance as Field, blinding]);
11197
- let commitment_hash = pedersen_hash([commitment.x, commitment.y, asset_id]);
11198
-
11199
- // This should pass
11200
- main(commitment_hash, minimum_required, asset_id, balance, blinding);
11201
- }
11202
-
11203
- #[test(should_fail_with = "Insufficient balance")]
11204
- fn test_insufficient_balance() {
11205
- let balance: u64 = 50;
11206
- let minimum_required: u64 = 100;
11207
- let blinding: Field = 12345;
11208
- let asset_id: Field = 0xABCD;
11209
-
11210
- let commitment = pedersen_commitment([balance as Field, blinding]);
11211
- let commitment_hash = pedersen_hash([commitment.x, commitment.y, asset_id]);
11212
-
11213
- // This should fail - balance < minimum
11214
- main(commitment_hash, minimum_required, asset_id, balance, blinding);
11215
- }
11216
-
11217
- #[test(should_fail_with = "Commitment hash mismatch")]
11218
- fn test_wrong_commitment_hash() {
11219
- let balance: u64 = 100;
11220
- let minimum_required: u64 = 50;
11221
- let blinding: Field = 12345;
11222
- let asset_id: Field = 0xABCD;
11223
- let wrong_hash: Field = 0xDEADBEEF;
11224
-
11225
- // This should fail - wrong hash
11226
- main(wrong_hash, minimum_required, asset_id, balance, blinding);
11227
- }
11228
-
11229
- #[test(should_fail_with = "Commitment hash mismatch")]
11230
- fn test_wrong_blinding() {
11231
- let balance: u64 = 100;
11232
- let minimum_required: u64 = 50;
11233
- let correct_blinding: Field = 12345;
11234
- let wrong_blinding: Field = 54321;
11235
- let asset_id: Field = 0xABCD;
11236
-
11237
- // Compute hash with correct blinding
11238
- let commitment = pedersen_commitment([balance as Field, correct_blinding]);
11239
- let commitment_hash = pedersen_hash([commitment.x, commitment.y, asset_id]);
11240
-
11241
- // Try to prove with wrong blinding - should fail
11242
- main(commitment_hash, minimum_required, asset_id, balance, wrong_blinding);
11243
- }
11244
- `, path: "/Users/rz/local-dev/sip-protocol/packages/circuits/funding_proof/src/main.nr" } }, expression_width: { Bounded: { width: 4 } } };
12558
+ `, path: "std/field/bn254.nr" }, "18": { source: 'pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size<let BIT_SIZE: u32>(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n "BIT_SIZE must be less than modulus_num_bits",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits<let N: u32>(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits<let N: u32>(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the \'self\',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n "N must be less than or equal to modulus_le_bytes().len()",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the \'self\',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n "N must be less than or equal to modulus_le_bytes().len()",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, "radix must be greater than 1");\n static_assert(radix <= 256, "radix must be less than or equal to 256");\n static_assert(radix & (radix - 1) == 0, "radix must be a power of 2");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, "radix must be greater than 1");\n static_assert(radix <= 256, "radix must be less than or equal to 256");\n static_assert(radix & (radix - 1) == 0, "radix must be a power of 2");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n "N must be less than or equal to modulus_le_bytes().len()",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits<let N: u32>(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits<let N: u32>(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = "radix must be greater than 1")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f"radix must be greater than 1");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = "radix must be greater than 1")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f"radix must be greater than 1");\n }\n }\n\n #[test(should_fail_with = "radix must be a power of 2")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f"radix must be a power of 2");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, "unexpected result");\n }\n }\n\n #[test(should_fail_with = "radix must be less than or equal to 256")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f"radix must be less than or equal to 256")\n }\n }\n\n #[test(should_fail_with = "Field failed to decompose into specified 16 limbs")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = "Field failed to decompose into specified 16 limbs")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = "Field failed to decompose into specified 8 limbs")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can\'t represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = "Field failed to decompose into specified 4 limbs")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can\'t represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits<let N: u32>(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n "N must be less than or equal to modulus_le_bits().len()",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits<let N: u32>(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n', path: "std/field/mod.nr" }, "19": { source: '// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated("This function has been moved to std::hash::keccakf1600")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you\'re working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n "Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3<let N: u32>(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment<let N: u32>(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator<let N: u32>(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash<let N: u32>(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator<let N: u32>(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators("pedersen_hash_length".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation<let N: u32>(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal<let N: u32>(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash<H>(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault<H>;\n\nimpl<H> BuildHasher for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl<H> Default for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash<H>(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl<T, let N: u32> Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<T> Hash for [T]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<A, B> Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl<A, B, C> Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl<A, B, C, D> Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl<A, B, C, D, E> Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n', path: "std/hash/mod.nr" }, "50": { source: '/// Funding Proof Circuit\n///\n/// Proves that a user has sufficient balance to cover a transaction\n/// without revealing the actual balance.\n///\n/// Public inputs:\n/// - commitment_hash: Hash of the Pedersen commitment to balance\n/// - minimum_required: Minimum balance required\n/// - asset_id: Asset identifier\n///\n/// Private inputs (witness):\n/// - balance: Actual user balance\n/// - blinding: Blinding factor for commitment\n///\n/// Constraints:\n/// 1. balance >= minimum_required\n/// 2. commitment = pedersen([balance, blinding])\n/// 3. commitment_hash = hash(commitment, asset_id)\n\nuse std::hash::pedersen_hash;\nuse std::hash::blake3;\n\n/// Main entry point for the funding proof circuit\n///\n/// Returns the commitment hash as a public output rather than taking it as input.\n/// This allows the SDK to verify the proof without needing to compute Pedersen hashes.\nfn main(\n // Public inputs\n minimum_required: pub u64,\n asset_id: pub Field,\n\n // Private inputs (witness)\n balance: u64,\n blinding: Field,\n) -> pub [u8; 32] {\n // Constraint 1: Balance must be at least the minimum required\n assert(balance >= minimum_required, "Insufficient balance");\n\n // Constraint 2: Compute the Pedersen commitment to (balance, blinding)\n let balance_field = balance as Field;\n let commitment = pedersen_hash([balance_field, blinding]);\n\n // Constraint 3: Compute and return the commitment hash\n // We hash: commitment || asset_id to bind the commitment to the asset\n let commitment_hash = compute_commitment_hash(commitment, asset_id);\n\n commitment_hash\n}\n\n/// Compute the commitment hash from commitment and asset_id\n/// Uses BLAKE3 for efficiency (built-in to Noir)\nfn compute_commitment_hash(commitment: Field, asset_id: Field) -> [u8; 32] {\n // Convert commitment to bytes (32 bytes, big-endian)\n let commitment_bytes: [u8; 32] = commitment.to_be_bytes();\n\n // Convert asset_id to bytes (32 bytes, big-endian)\n let asset_bytes: [u8; 32] = asset_id.to_be_bytes();\n\n // Create preimage: commitment || asset_id (64 bytes)\n let mut preimage: [u8; 64] = [0; 64];\n for i in 0..32 {\n preimage[i] = commitment_bytes[i];\n preimage[i + 32] = asset_bytes[i];\n }\n\n // Hash with BLAKE3\n blake3(preimage)\n}\n\n// --- Tests ---\n\n#[test]\nfn test_valid_funding_proof() {\n // Test case: balance = 100, minimum = 50\n let balance: u64 = 100;\n let minimum_required: u64 = 50;\n let blinding = 12345 as Field;\n let asset_id = 1 as Field;\n\n // Execute the circuit - it should return the commitment hash\n let commitment_hash = main(minimum_required, asset_id, balance, blinding);\n\n // Verify it returned a hash (not all zeros)\n let mut has_nonzero = false;\n for i in 0..32 {\n if commitment_hash[i] != 0 {\n has_nonzero = true;\n }\n }\n assert(has_nonzero, "Commitment hash should not be all zeros");\n}\n\n#[test]\nfn test_exact_balance_passes() {\n // Test case: balance exactly equals minimum\n let balance: u64 = 50;\n let minimum_required: u64 = 50;\n let blinding = 67890 as Field;\n let asset_id = 2 as Field;\n\n // Should succeed and return a hash\n let _commitment_hash = main(minimum_required, asset_id, balance, blinding);\n}\n\n#[test(should_fail_with = "Insufficient balance")]\nfn test_insufficient_balance_fails() {\n // Test case: balance < minimum should fail\n let balance: u64 = 40;\n let minimum_required: u64 = 50;\n let blinding = 11111 as Field;\n let asset_id = 1 as Field;\n\n // Should fail because balance < minimum_required\n let _commitment_hash = main(minimum_required, asset_id, balance, blinding);\n}\n\n#[test]\nfn test_different_blinding_produces_different_hash() {\n // Test that different blinding factors produce different commitment hashes\n let balance: u64 = 100;\n let minimum_required: u64 = 50;\n let blinding1 = 12345 as Field;\n let blinding2 = 99999 as Field;\n let asset_id = 1 as Field;\n\n let hash1 = main(minimum_required, asset_id, balance, blinding1);\n let hash2 = main(minimum_required, asset_id, balance, blinding2);\n\n // Hashes should be different\n let mut hashes_differ = false;\n for i in 0..32 {\n if hash1[i] != hash2[i] {\n hashes_differ = true;\n }\n }\n assert(hashes_differ, "Different blindings should produce different hashes");\n}\n', path: "/Users/rz/local-dev/circuits/funding_proof/src/main.nr" } }, expression_width: { Bounded: { width: 4 } } };
11245
12559
 
11246
12560
  // src/proofs/circuits/validity_proof.json
11247
12561
  var validity_proof_default = { noir_version: "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", hash: "17105369051450454041", abi: { parameters: [{ name: "intent_hash", type: { kind: "field" }, visibility: "public" }, { name: "sender_commitment_x", type: { kind: "field" }, visibility: "public" }, { name: "sender_commitment_y", type: { kind: "field" }, visibility: "public" }, { name: "nullifier", type: { kind: "field" }, visibility: "public" }, { name: "timestamp", type: { kind: "integer", sign: "unsigned", width: 64 }, visibility: "public" }, { name: "expiry", type: { kind: "integer", sign: "unsigned", width: 64 }, visibility: "public" }, { name: "sender_address", type: { kind: "field" }, visibility: "private" }, { name: "sender_blinding", type: { kind: "field" }, visibility: "private" }, { name: "sender_secret", type: { kind: "field" }, visibility: "private" }, { name: "pub_key_x", type: { kind: "array", length: 32, type: { kind: "integer", sign: "unsigned", width: 8 } }, visibility: "private" }, { name: "pub_key_y", type: { kind: "array", length: 32, type: { kind: "integer", sign: "unsigned", width: 8 } }, visibility: "private" }, { name: "signature", type: { kind: "array", length: 64, type: { kind: "integer", sign: "unsigned", width: 8 } }, visibility: "private" }, { name: "message_hash", type: { kind: "array", length: 32, type: { kind: "integer", sign: "unsigned", width: 8 } }, visibility: "private" }, { name: "nonce", type: { kind: "field" }, visibility: "private" }], return_type: null, error_types: { "4743545721632785176": { error_kind: "string", string: "Nullifier mismatch" }, "4924752953922582949": { error_kind: "string", string: "Invalid ECDSA signature" }, "5940733937471987676": { error_kind: "string", string: "Intent expired" }, "9872184990886929843": { error_kind: "string", string: "Sender commitment X mismatch" }, "14620555433709191364": { error_kind: "string", string: "Sender commitment Y mismatch" }, "15764276373176857197": { error_kind: "string", string: "Stack too deep" } } }, bytecode: "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", debug_symbols: "pZbNjuIwDIDfJeceYsf541VGI1SgM6pUFdSBlVaId9+YxaU9JMuGS+O69dfYsV1f1aHbXb63/fh1/FGbj6vaTf0w9N/b4bhvz/1xTNqr0nwBpzbYKPB/l6A2Ji1RbahRmN6g261RYrY9T13HVgtOop/aqRvPajNehqFRv9rhcn/p59SO9/XcTumpblQ3HtKagF/90LF0a57WOm8aND6MA7rZHPzKHvL2juhh76ypsQ8g9iFU2YvzXme/X/AfCCQAQO4ZAbuOoC0QHIgL4Kx97iGuCK5AiDE8CKgxS/B5AgHYB4HAhhoCGi8E9LaOAO8S0LxAKEYyODmLGGsIqK0kNAJCjgAmjzCWJBDGaV2zCUA/b8KZ7CYKWUk2ih/kaFHZrhIRc4hicfkox2GBcsVVIlinZ8LiQP+D4IOUBgQKOQKWENpJXgKYRSDo5U0EN/eI4HWFGykvYU4JDVk3CnmJGOY2Y5bNfp1VSAVEwLk6gs1WB9q3W1UR8Vqv+gcC3ka81K2K4Yxa6gMjxBqEAS0FYlJy1iGe/QqifxeB+ZZXym+AZ9+lmkJHREksRDIrwme6a/f9tJ7SwGEae9JM5gxXNgv0UFhROO53LHguXRYCu8VC5K3yfKdFAP40C4mLbOUNnywLJBorGicaLxqeEO/miWyIR0bNfxMWQAQUwbBw43BMfbsbOvaIfb6Me3Ew3Z5/n+SJDKqn6bjvDpep42AsptV0/UhnjPHzxgH7Aw==", file_map: { "14": { source: "// docs:start:ecdsa_secp256k1\n/// Verifies a ECDSA signature over the secp256k1 curve.\n/// - inputs:\n/// - x coordinate of public key as 32 bytes\n/// - y coordinate of public key as 32 bytes\n/// - the signature, as a 64 bytes array\n/// The signature internally will be represented as `(r, s)`,\n/// where `r` and `s` are fixed-sized big endian scalar values.\n/// As the `secp256k1` has a 256-bit modulus, we have a 64 byte signature\n/// while `r` and `s` will both be 32 bytes.\n/// We expect `s` to be normalized. This means given the curve's order,\n/// `s` should be less than or equal to `order / 2`.\n/// This is done to prevent malleability.\n/// For more context regarding malleability you can reference BIP 0062.\n/// - the hash of the message, as a vector of bytes\n/// - output: false for failure and true for success\npub fn verify_signature(\n public_key_x: [u8; 32],\n public_key_y: [u8; 32],\n signature: [u8; 64],\n message_hash: [u8; 32],\n) -> bool\n// docs:end:ecdsa_secp256k1\n{\n _verify_signature(public_key_x, public_key_y, signature, message_hash, true)\n}\n\n#[foreign(ecdsa_secp256k1)]\npub fn _verify_signature(\n public_key_x: [u8; 32],\n public_key_y: [u8; 32],\n signature: [u8; 64],\n message_hash: [u8; 32],\n predicate: bool,\n) -> bool {}\n", path: "std/ecdsa_secp256k1.nr" }, "16": { source: "use crate::cmp::Eq;\nuse crate::hash::Hash;\nuse crate::ops::arith::{Add, Neg, Sub};\n\n/// A point on the embedded elliptic curve\n/// By definition, the base field of the embedded curve is the scalar field of the proof system curve, i.e the Noir Field.\n/// x and y denotes the Weierstrass coordinates of the point, if is_infinite is false.\npub struct EmbeddedCurvePoint {\n pub x: Field,\n pub y: Field,\n pub is_infinite: bool,\n}\n\nimpl EmbeddedCurvePoint {\n /// Elliptic curve point doubling operation\n /// returns the doubled point of a point P, i.e P+P\n pub fn double(self) -> EmbeddedCurvePoint {\n embedded_curve_add(self, self)\n }\n\n /// Returns the null element of the curve; 'the point at infinity'\n pub fn point_at_infinity() -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: 0, y: 0, is_infinite: true }\n }\n\n /// Returns the curve's generator point.\n pub fn generator() -> EmbeddedCurvePoint {\n // Generator point for the grumpkin curve (y^2 = x^3 - 17)\n EmbeddedCurvePoint {\n x: 1,\n y: 17631683881184975370165255887551781615748388533673675138860, // sqrt(-16)\n is_infinite: false,\n }\n }\n}\n\nimpl Add for EmbeddedCurvePoint {\n /// Adds two points P+Q, using the curve addition formula, and also handles point at infinity\n fn add(self, other: EmbeddedCurvePoint) -> EmbeddedCurvePoint {\n embedded_curve_add(self, other)\n }\n}\n\nimpl Sub for EmbeddedCurvePoint {\n /// Points subtraction operation, using addition and negation\n fn sub(self, other: EmbeddedCurvePoint) -> EmbeddedCurvePoint {\n self + other.neg()\n }\n}\n\nimpl Neg for EmbeddedCurvePoint {\n /// Negates a point P, i.e returns -P, by negating the y coordinate.\n /// If the point is at infinity, then the result is also at infinity.\n fn neg(self) -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: self.x, y: -self.y, is_infinite: self.is_infinite }\n }\n}\n\nimpl Eq for EmbeddedCurvePoint {\n /// Checks whether two points are equal\n fn eq(self: Self, b: EmbeddedCurvePoint) -> bool {\n (self.is_infinite & b.is_infinite)\n | ((self.is_infinite == b.is_infinite) & (self.x == b.x) & (self.y == b.y))\n }\n}\n\nimpl Hash for EmbeddedCurvePoint {\n fn hash<H>(self, state: &mut H)\n where\n H: crate::hash::Hasher,\n {\n if self.is_infinite {\n self.is_infinite.hash(state);\n } else {\n self.x.hash(state);\n self.y.hash(state);\n }\n }\n}\n\n/// Scalar for the embedded curve represented as low and high limbs\n/// By definition, the scalar field of the embedded curve is base field of the proving system curve.\n/// It may not fit into a Field element, so it is represented with two Field elements; its low and high limbs.\npub struct EmbeddedCurveScalar {\n pub lo: Field,\n pub hi: Field,\n}\n\nimpl EmbeddedCurveScalar {\n pub fn new(lo: Field, hi: Field) -> Self {\n EmbeddedCurveScalar { lo, hi }\n }\n\n #[field(bn254)]\n pub fn from_field(scalar: Field) -> EmbeddedCurveScalar {\n let (a, b) = crate::field::bn254::decompose(scalar);\n EmbeddedCurveScalar { lo: a, hi: b }\n }\n\n //Bytes to scalar: take the first (after the specified offset) 16 bytes of the input as the lo value, and the next 16 bytes as the hi value\n #[field(bn254)]\n pub(crate) fn from_bytes(bytes: [u8; 64], offset: u32) -> EmbeddedCurveScalar {\n let mut v = 1;\n let mut lo = 0 as Field;\n let mut hi = 0 as Field;\n for i in 0..16 {\n lo = lo + (bytes[offset + 31 - i] as Field) * v;\n hi = hi + (bytes[offset + 15 - i] as Field) * v;\n v = v * 256;\n }\n let sig_s = crate::embedded_curve_ops::EmbeddedCurveScalar { lo, hi };\n sig_s\n }\n}\n\nimpl Eq for EmbeddedCurveScalar {\n fn eq(self, other: Self) -> bool {\n (other.hi == self.hi) & (other.lo == self.lo)\n }\n}\n\nimpl Hash for EmbeddedCurveScalar {\n fn hash<H>(self, state: &mut H)\n where\n H: crate::hash::Hasher,\n {\n self.hi.hash(state);\n self.lo.hash(state);\n }\n}\n\n// Computes a multi scalar multiplication over the embedded curve.\n// For bn254, We have Grumpkin and Baby JubJub.\n// For bls12-381, we have JubJub and Bandersnatch.\n//\n// The embedded curve being used is decided by the\n// underlying proof system.\n// docs:start:multi_scalar_mul\npub fn multi_scalar_mul<let N: u32>(\n points: [EmbeddedCurvePoint; N],\n scalars: [EmbeddedCurveScalar; N],\n) -> EmbeddedCurvePoint\n// docs:end:multi_scalar_mul\n{\n multi_scalar_mul_array_return(points, scalars, true)[0]\n}\n\n#[foreign(multi_scalar_mul)]\npub(crate) fn multi_scalar_mul_array_return<let N: u32>(\n points: [EmbeddedCurvePoint; N],\n scalars: [EmbeddedCurveScalar; N],\n predicate: bool,\n) -> [EmbeddedCurvePoint; 1] {}\n\n// docs:start:fixed_base_scalar_mul\npub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint\n// docs:end:fixed_base_scalar_mul\n{\n multi_scalar_mul([EmbeddedCurvePoint::generator()], [scalar])\n}\n\n/// This function only assumes that the points are on the curve\n/// It handles corner cases around the infinity point causing some overhead compared to embedded_curve_add_not_nul and embedded_curve_add_unsafe\n// docs:start:embedded_curve_add\npub fn embedded_curve_add(\n point1: EmbeddedCurvePoint,\n point2: EmbeddedCurvePoint,\n) -> EmbeddedCurvePoint {\n // docs:end:embedded_curve_add\n if crate::runtime::is_unconstrained() {\n // `embedded_curve_add_unsafe` requires the inputs not to be the infinity point, so we check it here.\n // This is because `embedded_curve_add_unsafe` uses the `embedded_curve_add` opcode.\n // For efficiency, the backend does not check the inputs for the infinity point, but it assumes that they are not the infinity point\n // so that it can apply the ec addition formula directly.\n if point1.is_infinite {\n point2\n } else if point2.is_infinite {\n point1\n } else {\n embedded_curve_add_unsafe(point1, point2)\n }\n } else {\n // In a constrained context, we also need to check the inputs are not the infinity point because we also use `embedded_curve_add_unsafe`\n // However we also need to identify the case where the two inputs are the same, because then\n // the addition formula does not work and we need to use the doubling formula instead.\n // In unconstrained context, we can check directly if the input values are the same when solving the opcode, so it is not an issue.\n\n // x_coordinates_match is true if both abscissae are the same\n let x_coordinates_match = point1.x == point2.x;\n // y_coordinates_match is true if both ordinates are the same\n let y_coordinates_match = point1.y == point2.y;\n // double_predicate is true if both abscissae and ordinates are the same\n let double_predicate = (x_coordinates_match & y_coordinates_match);\n // If the abscissae are the same, but not the ordinates, then one point is the opposite of the other\n let infinity_predicate = (x_coordinates_match & !y_coordinates_match);\n\n // `embedded_curve_add_unsafe` would not perform doubling, even if the inputs point1 and point2 are the same, because it cannot know this without adding some logic (and some constraints)\n // However we did this logic when we computed `double_predicate`, so we set the result to 2*point1 if point1 and point2 are the same\n let mut result = if double_predicate {\n // `embedded_curve_add_unsafe` is doing a doubling if the input is the same variable, because in this case it is guaranteed (at 'compile time') that the input is the same.\n embedded_curve_add_unsafe(point1, point1)\n } else {\n let point1_1 = EmbeddedCurvePoint {\n x: point1.x + (x_coordinates_match as Field),\n y: point1.y,\n is_infinite: false,\n };\n let point2_1 = EmbeddedCurvePoint { x: point2.x, y: point2.y, is_infinite: false };\n // point1_1 is guaranteed to have a different abscissa than point2:\n // - if x_coordinates_match is 0, that means point1.x != point2.x, and point1_1.x = point1.x + 0\n // - if x_coordinates_match is 1, that means point1.x = point2.x, but point1_1.x = point1.x + 1 in this case\n // Because the abscissa is different, the addition formula is guaranteed to succeed, so we can safely use `embedded_curve_add_unsafe`\n // Note that this computation may be garbage: if x_coordinates_match is 1, or if one of the input is the point at infinity.\n // therefore we only want to do this if we need the result, otherwise it needs to be eliminated as a dead instruction, lest we want the circuit to fail.\n embedded_curve_add_unsafe(point1_1, point2_1)\n };\n\n // Same logic as above for unconstrained context, we set the proper result when one of the inputs is the infinity point\n if point1.is_infinite {\n result = point2;\n }\n if point2.is_infinite {\n result = point1;\n }\n\n // Finally, we set the is_infinity flag of the result:\n // Opposite points should sum into the infinity point, however, if one of them is point at infinity, their coordinates are not meaningful\n // so we should not use the fact that the inputs are opposite in this case:\n let mut result_is_infinity =\n infinity_predicate & (!point1.is_infinite & !point2.is_infinite);\n // However, if both of them are at infinity, then the result is also at infinity\n result.is_infinite = result_is_infinity | (point1.is_infinite & point2.is_infinite);\n result\n }\n}\n\n#[foreign(embedded_curve_add)]\nfn embedded_curve_add_array_return(\n _point1: EmbeddedCurvePoint,\n _point2: EmbeddedCurvePoint,\n _predicate: bool,\n) -> [EmbeddedCurvePoint; 1] {}\n\n/// This function assumes that:\n/// The points are on the curve, and\n/// The points don't share an x-coordinate, and\n/// Neither point is the infinity point.\n/// If it is used with correct input, the function ensures the correct non-zero result is returned.\n/// Except for points on the curve, the other assumptions are checked by the function. It will cause assertion failure if they are not respected.\npub fn embedded_curve_add_not_nul(\n point1: EmbeddedCurvePoint,\n point2: EmbeddedCurvePoint,\n) -> EmbeddedCurvePoint {\n assert(point1.x != point2.x);\n assert(!point1.is_infinite);\n assert(!point2.is_infinite);\n // Ensure is_infinite is comptime\n let point1_1 = EmbeddedCurvePoint { x: point1.x, y: point1.y, is_infinite: false };\n let point2_1 = EmbeddedCurvePoint { x: point2.x, y: point2.y, is_infinite: false };\n embedded_curve_add_unsafe(point1_1, point2_1)\n}\n\n/// Unsafe ec addition\n/// If the inputs are the same, it will perform a doubling, but only if point1 and point2 are the same variable.\n/// If they have the same value but are different variables, the result will be incorrect because in this case\n/// it assumes (but does not check) that the points' x-coordinates are not equal.\n/// It also assumes neither point is the infinity point.\npub fn embedded_curve_add_unsafe(\n point1: EmbeddedCurvePoint,\n point2: EmbeddedCurvePoint,\n) -> EmbeddedCurvePoint {\n embedded_curve_add_array_return(point1, point2, true)[0]\n}\n", path: "std/embedded_curve_ops.nr" }, "17": { source: `use crate::field::field_less_than;
@@ -11921,6 +13235,9 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
11921
13235
  framework = "noir";
11922
13236
  _isReady = false;
11923
13237
  config;
13238
+ // Mobile device info (cached)
13239
+ deviceInfo = null;
13240
+ wasmCompatibility = null;
11924
13241
  // Circuit instances
11925
13242
  fundingNoir = null;
11926
13243
  fundingBackend = null;
@@ -11932,17 +13249,25 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
11932
13249
  worker = null;
11933
13250
  workerPending = /* @__PURE__ */ new Map();
11934
13251
  constructor(config = {}) {
13252
+ this.deviceInfo = getMobileDeviceInfo();
13253
+ const isMobile = this.deviceInfo.isMobile;
13254
+ const defaultTimeout = isMobile ? 12e4 : 6e4;
11935
13255
  this.config = {
11936
13256
  useWorker: config.useWorker ?? true,
11937
13257
  verbose: config.verbose ?? false,
11938
13258
  oraclePublicKey: config.oraclePublicKey ?? void 0,
11939
- timeout: config.timeout ?? 6e4
13259
+ timeout: config.timeout ?? defaultTimeout,
13260
+ mobileMode: config.mobileMode ?? isMobile,
13261
+ forceInitialize: config.forceInitialize ?? false
11940
13262
  };
11941
13263
  if (!isBrowser()) {
11942
13264
  console.warn(
11943
13265
  "[BrowserNoirProvider] Not running in browser environment. Consider using NoirProofProvider for Node.js."
11944
13266
  );
11945
13267
  }
13268
+ if (this.config.verbose && this.deviceInfo) {
13269
+ console.log("[BrowserNoirProvider] Device info:", this.deviceInfo);
13270
+ }
11946
13271
  }
11947
13272
  get isReady() {
11948
13273
  return this._isReady;
@@ -11972,6 +13297,67 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
11972
13297
  missing
11973
13298
  };
11974
13299
  }
13300
+ /**
13301
+ * Get detailed mobile device information
13302
+ */
13303
+ static getMobileInfo() {
13304
+ return getMobileDeviceInfo();
13305
+ }
13306
+ /**
13307
+ * Check mobile WASM compatibility
13308
+ *
13309
+ * Returns detailed compatibility information including:
13310
+ * - Feature support (WASM, SharedArrayBuffer, Workers, SIMD)
13311
+ * - Compatibility score (0-100)
13312
+ * - Issues and recommendations
13313
+ *
13314
+ * @example
13315
+ * ```typescript
13316
+ * const compat = BrowserNoirProvider.checkMobileCompatibility()
13317
+ * if (compat.score < 70) {
13318
+ * console.warn('Limited mobile support:', compat.issues)
13319
+ * }
13320
+ * ```
13321
+ */
13322
+ static checkMobileCompatibility() {
13323
+ return checkMobileWASMCompatibility();
13324
+ }
13325
+ /**
13326
+ * Check if the current device is mobile
13327
+ */
13328
+ static isMobile() {
13329
+ return getMobileDeviceInfo().isMobile;
13330
+ }
13331
+ /**
13332
+ * Get recommended configuration for the current device
13333
+ *
13334
+ * Automatically adjusts settings based on device capabilities:
13335
+ * - Mobile devices get longer timeouts
13336
+ * - Low-memory devices disable workers
13337
+ * - Tablets get intermediate settings
13338
+ */
13339
+ static getRecommendedConfig() {
13340
+ const deviceInfo = getMobileDeviceInfo();
13341
+ const compat = checkMobileWASMCompatibility();
13342
+ const config = {};
13343
+ if (deviceInfo.isMobile) {
13344
+ config.timeout = 12e4;
13345
+ config.mobileMode = true;
13346
+ if (deviceInfo.deviceMemoryGB !== null && deviceInfo.deviceMemoryGB < 2) {
13347
+ config.useWorker = false;
13348
+ }
13349
+ if (deviceInfo.platform === "ios" && deviceInfo.browser === "safari") {
13350
+ config.useWorker = compat.sharedArrayBuffer;
13351
+ }
13352
+ } else if (deviceInfo.isTablet) {
13353
+ config.timeout = 9e4;
13354
+ config.mobileMode = true;
13355
+ }
13356
+ if (compat.score < 50) {
13357
+ config.forceInitialize = false;
13358
+ }
13359
+ return config;
13360
+ }
11975
13361
  /**
11976
13362
  * Derive secp256k1 public key coordinates from a private key
11977
13363
  */
@@ -11981,6 +13367,18 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
11981
13367
  const y = Array.from(uncompressedPubKey.slice(33, 65));
11982
13368
  return { x, y };
11983
13369
  }
13370
+ /**
13371
+ * Get the cached WASM compatibility info (available after construction)
13372
+ */
13373
+ getWASMCompatibility() {
13374
+ return this.wasmCompatibility;
13375
+ }
13376
+ /**
13377
+ * Get the cached device info (available after construction)
13378
+ */
13379
+ getDeviceInfo() {
13380
+ return this.deviceInfo;
13381
+ }
11984
13382
  /**
11985
13383
  * Initialize the browser provider
11986
13384
  *
@@ -11993,8 +13391,18 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
11993
13391
  if (this._isReady) {
11994
13392
  return;
11995
13393
  }
13394
+ this.wasmCompatibility = checkMobileWASMCompatibility();
13395
+ if (this.config.verbose) {
13396
+ console.log("[BrowserNoirProvider] WASM compatibility:", this.wasmCompatibility);
13397
+ }
13398
+ if (this.wasmCompatibility.score < 50 && !this.config.forceInitialize) {
13399
+ throw new ProofError(
13400
+ `Device has poor WASM compatibility (score: ${this.wasmCompatibility.score}). Issues: ${this.wasmCompatibility.issues.join(", ")}. Set forceInitialize: true to override.`,
13401
+ "SIP_4004" /* PROOF_PROVIDER_NOT_READY */
13402
+ );
13403
+ }
11996
13404
  const { supported, missing } = _BrowserNoirProvider.checkBrowserSupport();
11997
- if (!supported) {
13405
+ if (!supported && !this.config.forceInitialize) {
11998
13406
  throw new ProofError(
11999
13407
  `Browser missing required features: ${missing.join(", ")}`,
12000
13408
  "SIP_4004" /* PROOF_PROVIDER_NOT_READY */
@@ -12058,8 +13466,69 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12058
13466
  * Initialize Web Worker for off-main-thread proof generation
12059
13467
  */
12060
13468
  async initializeWorker() {
12061
- if (this.config.verbose) {
12062
- console.log("[BrowserNoirProvider] Worker support: using async main-thread");
13469
+ if (!supportsWebWorkers()) {
13470
+ if (this.config.verbose) {
13471
+ console.log("[BrowserNoirProvider] Web Workers not supported, using main thread");
13472
+ }
13473
+ return;
13474
+ }
13475
+ try {
13476
+ const workerCode = this.getWorkerCode();
13477
+ const blob = new Blob([workerCode], { type: "application/javascript" });
13478
+ const workerURL = URL.createObjectURL(blob);
13479
+ this.worker = new Worker(workerURL, { type: "module" });
13480
+ this.worker.onmessage = (event) => {
13481
+ this.handleWorkerMessage(event.data);
13482
+ };
13483
+ this.worker.onerror = (error) => {
13484
+ console.error("[BrowserNoirProvider] Worker error:", error);
13485
+ for (const [id, { reject }] of this.workerPending) {
13486
+ reject(new Error(`Worker error: ${error.message}`));
13487
+ this.workerPending.delete(id);
13488
+ }
13489
+ this.worker?.terminate();
13490
+ this.worker = null;
13491
+ };
13492
+ URL.revokeObjectURL(workerURL);
13493
+ if (this.config.verbose) {
13494
+ console.log("[BrowserNoirProvider] Web Worker initialized successfully");
13495
+ }
13496
+ } catch (error) {
13497
+ if (this.config.verbose) {
13498
+ console.warn("[BrowserNoirProvider] Failed to initialize worker, using main thread:", error);
13499
+ }
13500
+ this.worker = null;
13501
+ }
13502
+ }
13503
+ /**
13504
+ * Get inline worker code for bundler compatibility
13505
+ */
13506
+ getWorkerCode() {
13507
+ return `
13508
+ self.onmessage = async function(event) {
13509
+ const { id, type } = event.data;
13510
+ // Signal that worker received message but proof gen happens on main thread
13511
+ self.postMessage({ id, type: 'fallback', message: 'Worker initialized, using main thread for proofs' });
13512
+ };
13513
+ `;
13514
+ }
13515
+ /**
13516
+ * Handle messages from worker
13517
+ */
13518
+ handleWorkerMessage(data) {
13519
+ const pending = this.workerPending.get(data.id);
13520
+ if (!pending) return;
13521
+ switch (data.type) {
13522
+ case "success":
13523
+ this.workerPending.delete(data.id);
13524
+ pending.resolve(data.result);
13525
+ break;
13526
+ case "error":
13527
+ this.workerPending.delete(data.id);
13528
+ pending.reject(new Error(data.error));
13529
+ break;
13530
+ case "fallback":
13531
+ break;
12063
13532
  }
12064
13533
  }
12065
13534
  /**
@@ -12081,15 +13550,10 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12081
13550
  percent: 10,
12082
13551
  message: "Preparing witness inputs..."
12083
13552
  });
12084
- const { commitmentHash, blindingField } = await this.computeCommitmentHash(
12085
- params.balance,
12086
- params.blindingFactor,
12087
- params.assetId
12088
- );
13553
+ const blindingField = this.bytesToField(params.blindingFactor);
12089
13554
  const witnessInputs = {
12090
- commitment_hash: commitmentHash,
12091
13555
  minimum_required: params.minimumRequired.toString(),
12092
- asset_id: this.assetIdToField(params.assetId),
13556
+ asset_id: `0x${this.assetIdToField(params.assetId)}`,
12093
13557
  balance: params.balance.toString(),
12094
13558
  blinding: blindingField
12095
13559
  };
@@ -12098,7 +13562,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12098
13562
  percent: 30,
12099
13563
  message: "Generating witness..."
12100
13564
  });
12101
- const { witness } = await this.fundingNoir.execute(witnessInputs);
13565
+ const { witness, returnValue } = await this.fundingNoir.execute(witnessInputs);
12102
13566
  onProgress?.({
12103
13567
  stage: "proving",
12104
13568
  percent: 50,
@@ -12110,10 +13574,12 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12110
13574
  percent: 100,
12111
13575
  message: "Proof generated successfully"
12112
13576
  });
13577
+ const commitmentHashBytes = returnValue;
13578
+ const commitmentHashHex = bytesToHex7(new Uint8Array(commitmentHashBytes));
12113
13579
  const publicInputs = [
12114
- `0x${commitmentHash}`,
12115
13580
  `0x${params.minimumRequired.toString(16).padStart(16, "0")}`,
12116
- `0x${this.assetIdToField(params.assetId)}`
13581
+ `0x${this.assetIdToField(params.assetId)}`,
13582
+ `0x${commitmentHashHex}`
12117
13583
  ];
12118
13584
  const proof = {
12119
13585
  type: "funding",
@@ -12515,6 +13981,314 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12515
13981
  return { x, y };
12516
13982
  }
12517
13983
  };
13984
+
13985
+ // src/proofs/worker.ts
13986
+ function createWorkerBlobURL() {
13987
+ const workerCode = `
13988
+ // Proof Generation Worker
13989
+ // This code runs in a separate thread
13990
+
13991
+ let fundingNoir = null;
13992
+ let fundingBackend = null;
13993
+ let validityNoir = null;
13994
+ let validityBackend = null;
13995
+ let fulfillmentNoir = null;
13996
+ let fulfillmentBackend = null;
13997
+ let isReady = false;
13998
+ let config = { verbose: false };
13999
+
14000
+ // Helper to send progress updates
14001
+ function sendProgress(id, stage, percent, message) {
14002
+ self.postMessage({
14003
+ id,
14004
+ type: 'progress',
14005
+ progress: { stage, percent, message }
14006
+ });
14007
+ }
14008
+
14009
+ // Helper to send error
14010
+ function sendError(id, error) {
14011
+ self.postMessage({
14012
+ id,
14013
+ type: 'error',
14014
+ error: error.message || String(error)
14015
+ });
14016
+ }
14017
+
14018
+ // Helper to send success
14019
+ function sendSuccess(id, result) {
14020
+ self.postMessage({
14021
+ id,
14022
+ type: 'success',
14023
+ result
14024
+ });
14025
+ }
14026
+
14027
+ // Initialize circuits (called once)
14028
+ async function initialize(id, initConfig) {
14029
+ try {
14030
+ sendProgress(id, 'initializing', 10, 'Loading Noir JS...');
14031
+
14032
+ // Dynamic imports for Noir
14033
+ const { Noir } = await import('@noir-lang/noir_js');
14034
+ const { UltraHonkBackend } = await import('@aztec/bb.js');
14035
+
14036
+ sendProgress(id, 'initializing', 30, 'Loading circuit artifacts...');
14037
+
14038
+ // Load circuit artifacts
14039
+ const [fundingArtifact, validityArtifact, fulfillmentArtifact] = await Promise.all([
14040
+ fetch(new URL('./circuits/funding_proof.json', import.meta.url)).then(r => r.json()),
14041
+ fetch(new URL('./circuits/validity_proof.json', import.meta.url)).then(r => r.json()),
14042
+ fetch(new URL('./circuits/fulfillment_proof.json', import.meta.url)).then(r => r.json()),
14043
+ ]);
14044
+
14045
+ sendProgress(id, 'initializing', 50, 'Initializing backends...');
14046
+
14047
+ // Initialize Noir instances
14048
+ fundingNoir = new Noir(fundingArtifact);
14049
+ fundingBackend = new UltraHonkBackend(fundingArtifact.bytecode);
14050
+
14051
+ sendProgress(id, 'initializing', 70, 'Initializing validity circuit...');
14052
+ validityNoir = new Noir(validityArtifact);
14053
+ validityBackend = new UltraHonkBackend(validityArtifact.bytecode);
14054
+
14055
+ sendProgress(id, 'initializing', 90, 'Initializing fulfillment circuit...');
14056
+ fulfillmentNoir = new Noir(fulfillmentArtifact);
14057
+ fulfillmentBackend = new UltraHonkBackend(fulfillmentArtifact.bytecode);
14058
+
14059
+ config = initConfig || { verbose: false };
14060
+ isReady = true;
14061
+
14062
+ sendProgress(id, 'complete', 100, 'Worker initialized');
14063
+ sendSuccess(id, { initialized: true });
14064
+ } catch (error) {
14065
+ sendError(id, error);
14066
+ }
14067
+ }
14068
+
14069
+ // Generate funding proof
14070
+ async function generateFundingProof(id, params) {
14071
+ if (!isReady) {
14072
+ sendError(id, new Error('Worker not initialized'));
14073
+ return;
14074
+ }
14075
+
14076
+ try {
14077
+ sendProgress(id, 'witness', 20, 'Preparing witness...');
14078
+
14079
+ // Convert blinding factor to field
14080
+ const blindingField = bytesToField(params.blindingFactor);
14081
+
14082
+ const witnessInputs = {
14083
+ minimum_required: params.minimumRequired.toString(),
14084
+ asset_id: '0x' + assetIdToField(params.assetId),
14085
+ balance: params.balance.toString(),
14086
+ blinding: blindingField,
14087
+ };
14088
+
14089
+ sendProgress(id, 'witness', 40, 'Executing circuit...');
14090
+ const { witness, returnValue } = await fundingNoir.execute(witnessInputs);
14091
+
14092
+ sendProgress(id, 'proving', 60, 'Generating proof...');
14093
+ const proofData = await fundingBackend.generateProof(witness);
14094
+
14095
+ sendProgress(id, 'complete', 100, 'Proof generated');
14096
+
14097
+ // Extract commitment hash from return value
14098
+ const commitmentHashHex = bytesToHex(new Uint8Array(returnValue));
14099
+
14100
+ const publicInputs = [
14101
+ '0x' + params.minimumRequired.toString(16).padStart(16, '0'),
14102
+ '0x' + assetIdToField(params.assetId),
14103
+ '0x' + commitmentHashHex,
14104
+ ];
14105
+
14106
+ const proof = {
14107
+ type: 'funding',
14108
+ proof: '0x' + bytesToHex(proofData.proof),
14109
+ publicInputs,
14110
+ };
14111
+
14112
+ sendSuccess(id, { proof, publicInputs });
14113
+ } catch (error) {
14114
+ sendError(id, error);
14115
+ }
14116
+ }
14117
+
14118
+ // Helper functions
14119
+ function bytesToField(bytes) {
14120
+ let result = 0n;
14121
+ const len = Math.min(bytes.length, 31);
14122
+ for (let i = 0; i < len; i++) {
14123
+ result = result * 256n + BigInt(bytes[i]);
14124
+ }
14125
+ return result.toString();
14126
+ }
14127
+
14128
+ function assetIdToField(assetId) {
14129
+ if (assetId.startsWith('0x')) {
14130
+ return assetId.slice(2).padStart(64, '0');
14131
+ }
14132
+ const encoder = new TextEncoder();
14133
+ const bytes = encoder.encode(assetId);
14134
+ let result = 0n;
14135
+ for (let i = 0; i < bytes.length && i < 31; i++) {
14136
+ result = result * 256n + BigInt(bytes[i]);
14137
+ }
14138
+ return result.toString(16).padStart(64, '0');
14139
+ }
14140
+
14141
+ function bytesToHex(bytes) {
14142
+ return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
14143
+ }
14144
+
14145
+ // Message handler
14146
+ self.onmessage = async function(event) {
14147
+ const { id, type, params, config: initConfig } = event.data;
14148
+
14149
+ switch (type) {
14150
+ case 'init':
14151
+ await initialize(id, initConfig);
14152
+ break;
14153
+ case 'generateFundingProof':
14154
+ await generateFundingProof(id, params);
14155
+ break;
14156
+ case 'generateValidityProof':
14157
+ // TODO: Implement
14158
+ sendError(id, new Error('Validity proof not yet implemented in worker'));
14159
+ break;
14160
+ case 'generateFulfillmentProof':
14161
+ // TODO: Implement
14162
+ sendError(id, new Error('Fulfillment proof not yet implemented in worker'));
14163
+ break;
14164
+ case 'destroy':
14165
+ // Cleanup
14166
+ fundingNoir = null;
14167
+ fundingBackend = null;
14168
+ validityNoir = null;
14169
+ validityBackend = null;
14170
+ fulfillmentNoir = null;
14171
+ fulfillmentBackend = null;
14172
+ isReady = false;
14173
+ sendSuccess(id, { destroyed: true });
14174
+ break;
14175
+ default:
14176
+ sendError(id, new Error('Unknown message type: ' + type));
14177
+ }
14178
+ };
14179
+ `;
14180
+ const blob = new Blob([workerCode], { type: "application/javascript" });
14181
+ return URL.createObjectURL(blob);
14182
+ }
14183
+ var ProofWorker = class _ProofWorker {
14184
+ worker = null;
14185
+ pendingRequests = /* @__PURE__ */ new Map();
14186
+ _isReady = false;
14187
+ requestCounter = 0;
14188
+ /**
14189
+ * Check if Web Workers are supported
14190
+ */
14191
+ static isSupported() {
14192
+ return typeof Worker !== "undefined" && typeof Blob !== "undefined";
14193
+ }
14194
+ /**
14195
+ * Check if worker is initialized and ready
14196
+ */
14197
+ get isReady() {
14198
+ return this._isReady;
14199
+ }
14200
+ /**
14201
+ * Initialize the worker
14202
+ */
14203
+ async initialize(config) {
14204
+ if (this._isReady) {
14205
+ return;
14206
+ }
14207
+ if (!_ProofWorker.isSupported()) {
14208
+ throw new Error("Web Workers not supported in this environment");
14209
+ }
14210
+ const workerURL = createWorkerBlobURL();
14211
+ this.worker = new Worker(workerURL, { type: "module" });
14212
+ this.worker.onmessage = (event) => {
14213
+ this.handleWorkerMessage(event.data);
14214
+ };
14215
+ this.worker.onerror = (error) => {
14216
+ console.error("[ProofWorker] Worker error:", error);
14217
+ for (const [id, { reject }] of this.pendingRequests) {
14218
+ reject(new Error(`Worker error: ${error.message}`));
14219
+ this.pendingRequests.delete(id);
14220
+ }
14221
+ };
14222
+ await this.sendRequest("init", void 0, config);
14223
+ this._isReady = true;
14224
+ URL.revokeObjectURL(workerURL);
14225
+ }
14226
+ /**
14227
+ * Generate a proof using the worker
14228
+ */
14229
+ async generateProof(type, params, onProgress) {
14230
+ if (!this._isReady || !this.worker) {
14231
+ throw new Error("Worker not initialized. Call initialize() first.");
14232
+ }
14233
+ const messageType = type === "funding" ? "generateFundingProof" : type === "validity" ? "generateValidityProof" : "generateFulfillmentProof";
14234
+ return this.sendRequest(messageType, params, void 0, onProgress);
14235
+ }
14236
+ /**
14237
+ * Destroy the worker and free resources
14238
+ */
14239
+ async destroy() {
14240
+ if (this.worker) {
14241
+ try {
14242
+ await this.sendRequest("destroy");
14243
+ } catch {
14244
+ }
14245
+ this.worker.terminate();
14246
+ this.worker = null;
14247
+ }
14248
+ this._isReady = false;
14249
+ this.pendingRequests.clear();
14250
+ }
14251
+ /**
14252
+ * Send a request to the worker
14253
+ */
14254
+ sendRequest(type, params, config, onProgress) {
14255
+ return new Promise((resolve, reject) => {
14256
+ if (!this.worker) {
14257
+ reject(new Error("Worker not available"));
14258
+ return;
14259
+ }
14260
+ const id = `req_${++this.requestCounter}_${Date.now()}`;
14261
+ this.pendingRequests.set(id, { resolve, reject, onProgress });
14262
+ const request = { id, type, params, config };
14263
+ this.worker.postMessage(request);
14264
+ });
14265
+ }
14266
+ /**
14267
+ * Handle messages from the worker
14268
+ */
14269
+ handleWorkerMessage(response) {
14270
+ const pending = this.pendingRequests.get(response.id);
14271
+ if (!pending) {
14272
+ console.warn("[ProofWorker] Received response for unknown request:", response.id);
14273
+ return;
14274
+ }
14275
+ switch (response.type) {
14276
+ case "success":
14277
+ this.pendingRequests.delete(response.id);
14278
+ pending.resolve(response.result);
14279
+ break;
14280
+ case "error":
14281
+ this.pendingRequests.delete(response.id);
14282
+ pending.reject(new Error(response.error));
14283
+ break;
14284
+ case "progress":
14285
+ if (pending.onProgress && response.progress) {
14286
+ pending.onProgress(response.progress);
14287
+ }
14288
+ break;
14289
+ }
14290
+ }
14291
+ };
12518
14292
  // Annotate the CommonJS export names for ESM import in node:
12519
14293
  0 && (module.exports = {
12520
14294
  ATTESTATION_VERSION,
@@ -12545,6 +14319,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12545
14319
  MockWalletAdapter,
12546
14320
  NATIVE_TOKENS,
12547
14321
  NEARIntentsAdapter,
14322
+ NEARIntentsBackend,
12548
14323
  NetworkError,
12549
14324
  ORACLE_DOMAIN,
12550
14325
  OneClickClient,
@@ -12558,6 +14333,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12558
14333
  ProofError,
12559
14334
  ProofGenerationError,
12560
14335
  ProofNotImplementedError,
14336
+ ProofWorker,
12561
14337
  ProposalStatus,
12562
14338
  ReportStatus,
12563
14339
  SIP,
@@ -12566,13 +14342,18 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12566
14342
  STABLECOIN_ADDRESSES,
12567
14343
  STABLECOIN_DECIMALS,
12568
14344
  STABLECOIN_INFO,
14345
+ SettlementRegistry,
14346
+ SettlementRegistryError,
14347
+ SmartRouter,
12569
14348
  SolanaWalletAdapter,
14349
+ SwapStatus,
12570
14350
  Treasury,
12571
14351
  TrezorWalletAdapter,
12572
14352
  ValidationError,
12573
14353
  WalletError,
12574
14354
  WalletErrorCode,
12575
14355
  ZcashErrorCode,
14356
+ ZcashNativeBackend,
12576
14357
  ZcashRPCClient,
12577
14358
  ZcashRPCError,
12578
14359
  ZcashShieldedService,
@@ -12585,6 +14366,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12585
14366
  browserBytesToHex,
12586
14367
  browserHexToBytes,
12587
14368
  checkEd25519StealthAddress,
14369
+ checkMobileWASMCompatibility,
12588
14370
  checkStealthAddress,
12589
14371
  commit,
12590
14372
  commitZero,
@@ -12601,15 +14383,19 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12601
14383
  createMockSolver,
12602
14384
  createMockTrezorAdapter,
12603
14385
  createNEARIntentsAdapter,
14386
+ createNEARIntentsBackend,
12604
14387
  createOracleRegistry,
12605
14388
  createProductionSIP,
12606
14389
  createSIP,
12607
14390
  createShieldedIntent,
12608
14391
  createShieldedPayment,
14392
+ createSmartRouter,
12609
14393
  createSolanaAdapter,
12610
14394
  createTrezorAdapter,
12611
14395
  createWalletFactory,
14396
+ createWorkerBlobURL,
12612
14397
  createZcashClient,
14398
+ createZcashNativeBackend,
12613
14399
  createZcashShieldedService,
12614
14400
  createZcashSwapService,
12615
14401
  decodeStealthMetaAddress,
@@ -12623,6 +14409,8 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12623
14409
  deserializeIntent,
12624
14410
  deserializePayment,
12625
14411
  detectEthereumWallets,
14412
+ detectMobileBrowser,
14413
+ detectMobilePlatform,
12626
14414
  detectSolanaWallets,
12627
14415
  ed25519PublicKeyToNearAddress,
12628
14416
  ed25519PublicKeyToSolanaAddress,
@@ -12643,6 +14431,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12643
14431
  getActiveOracles,
12644
14432
  getAvailableTransports,
12645
14433
  getBrowserInfo,
14434
+ getBrowserVersion,
12646
14435
  getChainNumericId,
12647
14436
  getChainsForStablecoin,
12648
14437
  getCurveForChain,
@@ -12652,6 +14441,8 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12652
14441
  getEthereumProvider,
12653
14442
  getGenerators,
12654
14443
  getIntentSummary,
14444
+ getMobileDeviceInfo,
14445
+ getOSVersion,
12655
14446
  getPaymentSummary,
12656
14447
  getPaymentTimeRemaining,
12657
14448
  getPrivacyConfig,
@@ -12677,6 +14468,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12677
14468
  isSIPError,
12678
14469
  isStablecoin,
12679
14470
  isStablecoinOnChain,
14471
+ isTablet,
12680
14472
  isValidAmount,
12681
14473
  isValidChainId,
12682
14474
  isValidCompressedPublicKey,
@@ -12708,7 +14500,10 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
12708
14500
  subtractBlindings,
12709
14501
  subtractCommitments,
12710
14502
  supportsSharedArrayBuffer,
14503
+ supportsTouch,
12711
14504
  supportsViewingKey,
14505
+ supportsWASMBulkMemory,
14506
+ supportsWASMSimd,
12712
14507
  supportsWebBluetooth,
12713
14508
  supportsWebHID,
12714
14509
  supportsWebUSB,