@sip-protocol/sdk 0.7.3 → 0.8.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 (263) hide show
  1. package/README.md +267 -0
  2. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  3. package/dist/browser.d.mts +10 -4
  4. package/dist/browser.d.ts +10 -4
  5. package/dist/browser.js +47556 -19603
  6. package/dist/browser.mjs +628 -48
  7. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  8. package/dist/chunk-5D7A3L3W.mjs +717 -0
  9. package/dist/chunk-64AYA5F5.mjs +7834 -0
  10. package/dist/chunk-GMDGB22A.mjs +379 -0
  11. package/dist/chunk-I534WKN7.mjs +328 -0
  12. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  13. package/dist/chunk-PRRZAWJE.mjs +223 -0
  14. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  15. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  16. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  17. package/dist/constants-LHAAUC2T.mjs +51 -0
  18. package/dist/dist-2OGQ7FED.mjs +3957 -0
  19. package/dist/dist-IFHPYLDX.mjs +254 -0
  20. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  21. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  22. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  23. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  24. package/dist/index.d.mts +9 -3
  25. package/dist/index.d.ts +9 -3
  26. package/dist/index.js +48396 -19623
  27. package/dist/index.mjs +537 -19
  28. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  29. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  30. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  31. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  32. package/dist/proofs/halo2.d.mts +151 -0
  33. package/dist/proofs/halo2.d.ts +151 -0
  34. package/dist/proofs/halo2.js +350 -0
  35. package/dist/proofs/halo2.mjs +11 -0
  36. package/dist/proofs/kimchi.d.mts +160 -0
  37. package/dist/proofs/kimchi.d.ts +160 -0
  38. package/dist/proofs/kimchi.js +431 -0
  39. package/dist/proofs/kimchi.mjs +13 -0
  40. package/dist/proofs/noir.d.mts +1 -1
  41. package/dist/proofs/noir.d.ts +1 -1
  42. package/dist/proofs/noir.js +74 -18
  43. package/dist/proofs/noir.mjs +84 -24
  44. package/dist/solana-U3MEGU7W.mjs +280 -0
  45. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  46. package/package.json +44 -11
  47. package/src/adapters/index.ts +41 -0
  48. package/src/adapters/jupiter.ts +571 -0
  49. package/src/adapters/near-intents.ts +135 -0
  50. package/src/advisor/advisor.ts +653 -0
  51. package/src/advisor/index.ts +54 -0
  52. package/src/advisor/tools.ts +303 -0
  53. package/src/advisor/types.ts +164 -0
  54. package/src/chains/ethereum/announcement.ts +536 -0
  55. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  56. package/src/chains/ethereum/commitment.ts +522 -0
  57. package/src/chains/ethereum/constants.ts +462 -0
  58. package/src/chains/ethereum/deployment.ts +596 -0
  59. package/src/chains/ethereum/gas-estimation.ts +538 -0
  60. package/src/chains/ethereum/index.ts +268 -0
  61. package/src/chains/ethereum/optimizations.ts +614 -0
  62. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  63. package/src/chains/ethereum/registry.ts +584 -0
  64. package/src/chains/ethereum/rpc.ts +905 -0
  65. package/src/chains/ethereum/stealth.ts +491 -0
  66. package/src/chains/ethereum/token.ts +790 -0
  67. package/src/chains/ethereum/transfer.ts +637 -0
  68. package/src/chains/ethereum/types.ts +456 -0
  69. package/src/chains/ethereum/viewing-key.ts +455 -0
  70. package/src/chains/near/commitment.ts +608 -0
  71. package/src/chains/near/constants.ts +284 -0
  72. package/src/chains/near/function-call.ts +871 -0
  73. package/src/chains/near/history.ts +654 -0
  74. package/src/chains/near/implicit-account.ts +840 -0
  75. package/src/chains/near/index.ts +393 -0
  76. package/src/chains/near/native-transfer.ts +658 -0
  77. package/src/chains/near/nep141.ts +775 -0
  78. package/src/chains/near/privacy-adapter.ts +889 -0
  79. package/src/chains/near/resolver.ts +971 -0
  80. package/src/chains/near/rpc.ts +1016 -0
  81. package/src/chains/near/stealth.ts +419 -0
  82. package/src/chains/near/types.ts +317 -0
  83. package/src/chains/near/viewing-key.ts +876 -0
  84. package/src/chains/solana/anchor-transfer.ts +386 -0
  85. package/src/chains/solana/commitment.ts +577 -0
  86. package/src/chains/solana/constants.ts +126 -12
  87. package/src/chains/solana/ephemeral-keys.ts +543 -0
  88. package/src/chains/solana/index.ts +252 -1
  89. package/src/chains/solana/key-derivation.ts +418 -0
  90. package/src/chains/solana/kit-compat.ts +334 -0
  91. package/src/chains/solana/optimizations.ts +560 -0
  92. package/src/chains/solana/privacy-adapter.ts +605 -0
  93. package/src/chains/solana/providers/generic.ts +47 -6
  94. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  95. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  96. package/src/chains/solana/providers/helius.ts +186 -33
  97. package/src/chains/solana/providers/index.ts +31 -0
  98. package/src/chains/solana/providers/interface.ts +61 -18
  99. package/src/chains/solana/providers/quicknode.ts +409 -0
  100. package/src/chains/solana/providers/triton.ts +426 -0
  101. package/src/chains/solana/providers/webhook.ts +338 -67
  102. package/src/chains/solana/rpc-client.ts +1150 -0
  103. package/src/chains/solana/scan.ts +83 -66
  104. package/src/chains/solana/sol-transfer.ts +732 -0
  105. package/src/chains/solana/spl-transfer.ts +886 -0
  106. package/src/chains/solana/stealth-scanner.ts +703 -0
  107. package/src/chains/solana/sunspot-verifier.ts +453 -0
  108. package/src/chains/solana/transaction-builder.ts +755 -0
  109. package/src/chains/solana/transfer.ts +74 -5
  110. package/src/chains/solana/types.ts +57 -6
  111. package/src/chains/solana/utils.ts +110 -0
  112. package/src/chains/solana/viewing-key.ts +807 -0
  113. package/src/compliance/fireblocks.ts +921 -0
  114. package/src/compliance/index.ts +23 -0
  115. package/src/compliance/range-sas.ts +398 -33
  116. package/src/config/endpoints.ts +100 -0
  117. package/src/crypto.ts +11 -8
  118. package/src/errors.ts +82 -0
  119. package/src/evm/erc4337-relayer.ts +830 -0
  120. package/src/evm/index.ts +47 -0
  121. package/src/fees/calculator.ts +396 -0
  122. package/src/fees/index.ts +87 -0
  123. package/src/fees/near-contract.ts +429 -0
  124. package/src/fees/types.ts +268 -0
  125. package/src/index.ts +686 -1
  126. package/src/intent.ts +6 -3
  127. package/src/logger.ts +324 -0
  128. package/src/network/index.ts +80 -0
  129. package/src/network/proxy.ts +691 -0
  130. package/src/optimizations/index.ts +541 -0
  131. package/src/oracle/types.ts +1 -0
  132. package/src/privacy-backends/arcium-types.ts +727 -0
  133. package/src/privacy-backends/arcium.ts +719 -0
  134. package/src/privacy-backends/combined-privacy.ts +866 -0
  135. package/src/privacy-backends/cspl-token.ts +595 -0
  136. package/src/privacy-backends/cspl-types.ts +512 -0
  137. package/src/privacy-backends/cspl.ts +907 -0
  138. package/src/privacy-backends/health.ts +488 -0
  139. package/src/privacy-backends/inco-types.ts +323 -0
  140. package/src/privacy-backends/inco.ts +616 -0
  141. package/src/privacy-backends/index.ts +254 -4
  142. package/src/privacy-backends/interface.ts +649 -6
  143. package/src/privacy-backends/lru-cache.ts +343 -0
  144. package/src/privacy-backends/magicblock.ts +458 -0
  145. package/src/privacy-backends/mock.ts +258 -0
  146. package/src/privacy-backends/privacycash.ts +13 -17
  147. package/src/privacy-backends/private-swap.ts +570 -0
  148. package/src/privacy-backends/rate-limiter.ts +683 -0
  149. package/src/privacy-backends/registry.ts +414 -2
  150. package/src/privacy-backends/router.ts +283 -3
  151. package/src/privacy-backends/shadowwire.ts +449 -0
  152. package/src/privacy-backends/sip-native.ts +3 -0
  153. package/src/privacy-logger.ts +191 -0
  154. package/src/production-safety.ts +373 -0
  155. package/src/proofs/aggregator.ts +1029 -0
  156. package/src/proofs/browser-composer.ts +1150 -0
  157. package/src/proofs/browser.ts +113 -25
  158. package/src/proofs/cache/index.ts +127 -0
  159. package/src/proofs/cache/interface.ts +545 -0
  160. package/src/proofs/cache/key-generator.ts +188 -0
  161. package/src/proofs/cache/lru-cache.ts +481 -0
  162. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  163. package/src/proofs/cache/persistent-cache.ts +788 -0
  164. package/src/proofs/compliance-proof.ts +872 -0
  165. package/src/proofs/composer/base.ts +923 -0
  166. package/src/proofs/composer/index.ts +25 -0
  167. package/src/proofs/composer/interface.ts +518 -0
  168. package/src/proofs/composer/types.ts +383 -0
  169. package/src/proofs/converters/halo2.ts +452 -0
  170. package/src/proofs/converters/index.ts +208 -0
  171. package/src/proofs/converters/interface.ts +363 -0
  172. package/src/proofs/converters/kimchi.ts +462 -0
  173. package/src/proofs/converters/noir.ts +451 -0
  174. package/src/proofs/fallback.ts +888 -0
  175. package/src/proofs/halo2.ts +42 -0
  176. package/src/proofs/index.ts +471 -0
  177. package/src/proofs/interface.ts +13 -0
  178. package/src/proofs/kimchi.ts +42 -0
  179. package/src/proofs/lazy.ts +1004 -0
  180. package/src/proofs/mock.ts +25 -1
  181. package/src/proofs/noir.ts +110 -29
  182. package/src/proofs/orchestrator.ts +960 -0
  183. package/src/proofs/parallel/concurrency.ts +297 -0
  184. package/src/proofs/parallel/dependency-graph.ts +602 -0
  185. package/src/proofs/parallel/executor.ts +420 -0
  186. package/src/proofs/parallel/index.ts +131 -0
  187. package/src/proofs/parallel/interface.ts +685 -0
  188. package/src/proofs/parallel/worker-pool.ts +644 -0
  189. package/src/proofs/providers/halo2.ts +560 -0
  190. package/src/proofs/providers/index.ts +34 -0
  191. package/src/proofs/providers/kimchi.ts +641 -0
  192. package/src/proofs/validator.ts +881 -0
  193. package/src/proofs/verifier.ts +867 -0
  194. package/src/quantum/index.ts +112 -0
  195. package/src/quantum/winternitz-vault.ts +639 -0
  196. package/src/quantum/wots.ts +611 -0
  197. package/src/settlement/backends/direct-chain.ts +1 -0
  198. package/src/settlement/index.ts +9 -0
  199. package/src/settlement/router.ts +732 -46
  200. package/src/solana/index.ts +72 -0
  201. package/src/solana/jito-relayer.ts +687 -0
  202. package/src/solana/noir-verifier-types.ts +430 -0
  203. package/src/solana/noir-verifier.ts +816 -0
  204. package/src/stealth/address-derivation.ts +193 -0
  205. package/src/stealth/ed25519.ts +431 -0
  206. package/src/stealth/index.ts +233 -0
  207. package/src/stealth/meta-address.ts +221 -0
  208. package/src/stealth/secp256k1.ts +368 -0
  209. package/src/stealth/utils.ts +194 -0
  210. package/src/stealth.ts +50 -1504
  211. package/src/sync/index.ts +106 -0
  212. package/src/sync/manager.ts +504 -0
  213. package/src/sync/mock-provider.ts +318 -0
  214. package/src/sync/oblivious.ts +625 -0
  215. package/src/tokens/index.ts +15 -0
  216. package/src/tokens/registry.ts +301 -0
  217. package/src/utils/deprecation.ts +94 -0
  218. package/src/utils/index.ts +9 -0
  219. package/src/wallet/ethereum/index.ts +68 -0
  220. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  221. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  222. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  223. package/src/wallet/ethereum/types.ts +3 -1
  224. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  225. package/src/wallet/hardware/index.ts +10 -0
  226. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  227. package/src/wallet/index.ts +71 -0
  228. package/src/wallet/near/adapter.ts +626 -0
  229. package/src/wallet/near/index.ts +86 -0
  230. package/src/wallet/near/meteor-wallet.ts +1153 -0
  231. package/src/wallet/near/my-near-wallet.ts +790 -0
  232. package/src/wallet/near/wallet-selector.ts +702 -0
  233. package/src/wallet/solana/adapter.ts +6 -4
  234. package/src/wallet/solana/index.ts +13 -0
  235. package/src/wallet/solana/privacy-adapter.ts +567 -0
  236. package/src/wallet/sui/types.ts +6 -4
  237. package/src/zcash/rpc-client.ts +13 -6
  238. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  239. package/dist/chunk-3INS3PR5.mjs +0 -884
  240. package/dist/chunk-3OVABDRH.mjs +0 -17096
  241. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  242. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  243. package/dist/chunk-E6SZWREQ.mjs +0 -57
  244. package/dist/chunk-F6F73W35.mjs +0 -16166
  245. package/dist/chunk-G33LB27A.mjs +0 -16166
  246. package/dist/chunk-HGU6HZRC.mjs +0 -231
  247. package/dist/chunk-L2K34JCU.mjs +0 -1496
  248. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  249. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  250. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  251. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  252. package/dist/constants-VOI7BSLK.mjs +0 -27
  253. package/dist/index-B71aXVzk.d.ts +0 -13264
  254. package/dist/index-BYZbDjal.d.ts +0 -11390
  255. package/dist/index-CHB3KuOB.d.mts +0 -11859
  256. package/dist/index-CzWPI6Le.d.ts +0 -11859
  257. package/dist/index-pOIIuwfV.d.mts +0 -13264
  258. package/dist/index-xbWjohNq.d.mts +0 -11390
  259. package/dist/solana-4O4K45VU.mjs +0 -46
  260. package/dist/solana-5EMCTPTS.mjs +0 -46
  261. package/dist/solana-NDABAZ6P.mjs +0 -56
  262. package/dist/solana-Q4NAVBTS.mjs +0 -46
  263. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -2,6 +2,7 @@
2
2
  * Privacy Backend Registry
3
3
  *
4
4
  * Manages registration and discovery of privacy backends.
5
+ * Optionally integrates with BackendHealthTracker for circuit breaker support.
5
6
  *
6
7
  * @example
7
8
  * ```typescript
@@ -16,6 +17,10 @@
16
17
  * const byName = registry.get('sip-native')
17
18
  * const forChain = registry.getByChain('solana')
18
19
  * const forType = registry.getByType('transaction')
20
+ *
21
+ * // Health-aware operations (when health tracker is attached)
22
+ * const healthy = registry.getHealthy()
23
+ * const health = registry.getHealthState('sip-native')
19
24
  * ```
20
25
  */
21
26
 
@@ -27,21 +32,118 @@ import type {
27
32
  RegisteredBackend,
28
33
  TransferParams,
29
34
  AvailabilityResult,
35
+ BackendHealthState,
36
+ BackendMetrics,
37
+ CircuitBreakerConfig,
30
38
  } from './interface'
39
+ import { warnIfDeprecatedVersion } from './interface'
40
+ import { BackendHealthTracker } from './health'
41
+ import { RateLimiter, type RateLimiterConfig, type RateLimitStats, type AcquireOptions } from './rate-limiter'
31
42
 
32
43
  /**
33
44
  * Default priority for registered backends
34
45
  */
35
46
  const DEFAULT_PRIORITY = 50
36
47
 
48
+ /**
49
+ * Registry configuration options
50
+ */
51
+ export interface PrivacyBackendRegistryConfig {
52
+ /**
53
+ * Enable health tracking with circuit breaker
54
+ * @default true
55
+ */
56
+ enableHealthTracking?: boolean
57
+ /**
58
+ * Circuit breaker configuration (when health tracking is enabled)
59
+ */
60
+ circuitBreakerConfig?: Partial<CircuitBreakerConfig>
61
+ /**
62
+ * Enable rate limiting for backends
63
+ * @default false
64
+ */
65
+ enableRateLimiting?: boolean
66
+ /**
67
+ * Rate limiter configuration (when rate limiting is enabled)
68
+ */
69
+ rateLimiterConfig?: RateLimiterConfig
70
+ }
71
+
37
72
  /**
38
73
  * Registry for managing privacy backends
39
74
  *
40
75
  * Provides a centralized way to register, discover, and manage
41
- * different privacy backend implementations.
76
+ * different privacy backend implementations. Optionally integrates
77
+ * with BackendHealthTracker for circuit breaker support.
42
78
  */
43
79
  export class PrivacyBackendRegistry {
44
80
  private backends: Map<string, RegisteredBackend> = new Map()
81
+ private healthTracker: BackendHealthTracker | null = null
82
+ private rateLimiter: RateLimiter | null = null
83
+
84
+ /**
85
+ * Create a new registry
86
+ *
87
+ * @param config - Registry configuration
88
+ */
89
+ constructor(config: PrivacyBackendRegistryConfig = {}) {
90
+ const {
91
+ enableHealthTracking = true,
92
+ circuitBreakerConfig,
93
+ enableRateLimiting = false,
94
+ rateLimiterConfig,
95
+ } = config
96
+
97
+ if (enableHealthTracking) {
98
+ this.healthTracker = new BackendHealthTracker(circuitBreakerConfig)
99
+ }
100
+
101
+ if (enableRateLimiting) {
102
+ this.rateLimiter = new RateLimiter(rateLimiterConfig)
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Get the health tracker instance
108
+ *
109
+ * @returns Health tracker or null if not enabled
110
+ */
111
+ getHealthTracker(): BackendHealthTracker | null {
112
+ return this.healthTracker
113
+ }
114
+
115
+ /**
116
+ * Attach an external health tracker
117
+ *
118
+ * Useful for sharing a health tracker between multiple registries
119
+ * or for testing.
120
+ *
121
+ * @param tracker - Health tracker to attach
122
+ */
123
+ setHealthTracker(tracker: BackendHealthTracker | null): void {
124
+ this.healthTracker = tracker
125
+ }
126
+
127
+ /**
128
+ * Get the rate limiter instance
129
+ *
130
+ * @returns Rate limiter or null if not enabled
131
+ */
132
+ getRateLimiter(): RateLimiter | null {
133
+ return this.rateLimiter
134
+ }
135
+
136
+ /**
137
+ * Attach an external rate limiter
138
+ *
139
+ * Useful for sharing a rate limiter between multiple registries
140
+ * or for testing.
141
+ *
142
+ * @param limiter - Rate limiter to attach
143
+ */
144
+ setRateLimiter(limiter: RateLimiter | null): void {
145
+ this.rateLimiter = limiter
146
+ }
45
147
 
46
148
  /**
47
149
  * Register a privacy backend
@@ -69,12 +171,20 @@ export class PrivacyBackendRegistry {
69
171
  )
70
172
  }
71
173
 
174
+ // Warn about deprecated interface versions
175
+ warnIfDeprecatedVersion(backend)
176
+
72
177
  this.backends.set(backend.name, {
73
178
  backend,
74
179
  priority,
75
180
  enabled,
76
181
  registeredAt: Date.now(),
77
182
  })
183
+
184
+ // Register with health tracker if enabled
185
+ if (this.healthTracker) {
186
+ this.healthTracker.register(backend.name)
187
+ }
78
188
  }
79
189
 
80
190
  /**
@@ -84,7 +194,11 @@ export class PrivacyBackendRegistry {
84
194
  * @returns true if backend was removed, false if not found
85
195
  */
86
196
  unregister(name: string): boolean {
87
- return this.backends.delete(name)
197
+ const removed = this.backends.delete(name)
198
+ if (removed && this.healthTracker) {
199
+ this.healthTracker.unregister(name)
200
+ }
201
+ return removed
88
202
  }
89
203
 
90
204
  /**
@@ -251,6 +365,9 @@ export class PrivacyBackendRegistry {
251
365
  */
252
366
  clear(): void {
253
367
  this.backends.clear()
368
+ if (this.healthTracker) {
369
+ this.healthTracker.clear()
370
+ }
254
371
  }
255
372
 
256
373
  /**
@@ -267,6 +384,301 @@ export class PrivacyBackendRegistry {
267
384
  }
268
385
  return Array.from(this.backends.keys())
269
386
  }
387
+
388
+ // ─── Health-Aware Methods ───────────────────────────────────────────────────
389
+
390
+ /**
391
+ * Get all healthy backends (circuit not open)
392
+ *
393
+ * Filters out backends where the circuit breaker is open.
394
+ * Falls back to getAll() if health tracking is disabled.
395
+ *
396
+ * @returns Array of healthy backends
397
+ */
398
+ getHealthy(): PrivacyBackend[] {
399
+ const all = this.getAll()
400
+ if (!this.healthTracker) {
401
+ return all
402
+ }
403
+ return all.filter(backend => this.healthTracker!.isHealthy(backend.name))
404
+ }
405
+
406
+ /**
407
+ * Get healthy backends supporting a specific chain
408
+ *
409
+ * @param chain - Chain type to filter by
410
+ * @returns Array of healthy backends supporting the chain
411
+ */
412
+ getHealthyByChain(chain: ChainType): PrivacyBackend[] {
413
+ return this.getHealthy().filter(backend => backend.chains.includes(chain))
414
+ }
415
+
416
+ /**
417
+ * Get health state for a backend
418
+ *
419
+ * @param name - Backend name
420
+ * @returns Health state or undefined if not tracked
421
+ */
422
+ getHealthState(name: string): BackendHealthState | undefined {
423
+ return this.healthTracker?.getHealth(name)
424
+ }
425
+
426
+ /**
427
+ * Get metrics for a backend
428
+ *
429
+ * @param name - Backend name
430
+ * @returns Metrics or undefined if not tracked
431
+ */
432
+ getMetrics(name: string): BackendMetrics | undefined {
433
+ return this.healthTracker?.getMetrics(name)
434
+ }
435
+
436
+ /**
437
+ * Get summary of all backend health
438
+ *
439
+ * @returns Object with backend names as keys and health info as values
440
+ */
441
+ getHealthSummary(): Record<string, {
442
+ healthy: boolean
443
+ state: string
444
+ failures: number
445
+ lastError?: string
446
+ }> {
447
+ if (!this.healthTracker) {
448
+ // Return all backends as healthy when tracking is disabled
449
+ const summary: Record<string, {
450
+ healthy: boolean
451
+ state: string
452
+ failures: number
453
+ }> = {}
454
+ for (const name of this.getNames()) {
455
+ summary[name] = { healthy: true, state: 'closed', failures: 0 }
456
+ }
457
+ return summary
458
+ }
459
+ return this.healthTracker.getHealthSummary()
460
+ }
461
+
462
+ /**
463
+ * Check if a backend is healthy
464
+ *
465
+ * @param name - Backend name
466
+ * @returns true if healthy or health tracking is disabled
467
+ */
468
+ isHealthy(name: string): boolean {
469
+ if (!this.healthTracker) {
470
+ return true
471
+ }
472
+ return this.healthTracker.isHealthy(name)
473
+ }
474
+
475
+ /**
476
+ * Manually open circuit for a backend
477
+ *
478
+ * Useful for maintenance or known issues.
479
+ *
480
+ * @param name - Backend name
481
+ * @returns true if circuit was opened, false if not found or tracking disabled
482
+ */
483
+ openCircuit(name: string): boolean {
484
+ if (!this.healthTracker || !this.backends.has(name)) {
485
+ return false
486
+ }
487
+ this.healthTracker.forceOpen(name)
488
+ return true
489
+ }
490
+
491
+ /**
492
+ * Manually close circuit for a backend
493
+ *
494
+ * Use with caution - may route requests to failing backend.
495
+ *
496
+ * @param name - Backend name
497
+ * @returns true if circuit was closed, false if not found or tracking disabled
498
+ */
499
+ closeCircuit(name: string): boolean {
500
+ if (!this.healthTracker || !this.backends.has(name)) {
501
+ return false
502
+ }
503
+ this.healthTracker.forceClose(name)
504
+ return true
505
+ }
506
+
507
+ /**
508
+ * Reset health state for a backend
509
+ *
510
+ * Clears failure count and closes circuit.
511
+ *
512
+ * @param name - Backend name
513
+ * @returns true if reset, false if not found or tracking disabled
514
+ */
515
+ resetHealth(name: string): boolean {
516
+ if (!this.healthTracker || !this.backends.has(name)) {
517
+ return false
518
+ }
519
+ this.healthTracker.reset(name)
520
+ return true
521
+ }
522
+
523
+ /**
524
+ * Record a successful execution for a backend
525
+ *
526
+ * @param name - Backend name
527
+ * @param latencyMs - Request latency in milliseconds
528
+ */
529
+ recordSuccess(name: string, latencyMs: number): void {
530
+ if (this.healthTracker) {
531
+ this.healthTracker.recordSuccess(name, latencyMs)
532
+ }
533
+ }
534
+
535
+ /**
536
+ * Record a failed execution for a backend
537
+ *
538
+ * @param name - Backend name
539
+ * @param reason - Failure reason
540
+ */
541
+ recordFailure(name: string, reason: string): void {
542
+ if (this.healthTracker) {
543
+ this.healthTracker.recordFailure(name, reason)
544
+ }
545
+ }
546
+
547
+ // ─── Rate Limiting Methods ─────────────────────────────────────────────────
548
+
549
+ /**
550
+ * Try to acquire rate limit tokens for a backend (non-blocking)
551
+ *
552
+ * @param name - Backend name
553
+ * @param tokens - Number of tokens to acquire (default: 1)
554
+ * @returns true if tokens were acquired, false if rate limited or limiter disabled
555
+ */
556
+ tryAcquire(name: string, tokens: number = 1): boolean {
557
+ if (!this.rateLimiter) {
558
+ return true // No rate limiting enabled
559
+ }
560
+ return this.rateLimiter.tryAcquire(name, tokens)
561
+ }
562
+
563
+ /**
564
+ * Acquire rate limit tokens for a backend (async with queueing)
565
+ *
566
+ * @param name - Backend name
567
+ * @param options - Acquire options (tokens, timeout)
568
+ * @returns Promise resolving when tokens are acquired
569
+ * @throws RateLimitExceededError, QueueFullError, or AcquireTimeoutError
570
+ */
571
+ async acquire(name: string, options?: AcquireOptions): Promise<void> {
572
+ if (!this.rateLimiter) {
573
+ return // No rate limiting enabled
574
+ }
575
+ await this.rateLimiter.acquire(name, options)
576
+ }
577
+
578
+ /**
579
+ * Check if tokens can be acquired without consuming them
580
+ *
581
+ * @param name - Backend name
582
+ * @param tokens - Number of tokens to check (default: 1)
583
+ * @returns true if tokens are available
584
+ */
585
+ canAcquire(name: string, tokens: number = 1): boolean {
586
+ if (!this.rateLimiter) {
587
+ return true // No rate limiting enabled
588
+ }
589
+ return this.rateLimiter.canAcquire(name, tokens)
590
+ }
591
+
592
+ /**
593
+ * Get rate limit statistics for a backend
594
+ *
595
+ * @param name - Backend name
596
+ * @returns Rate limit stats or undefined if limiter disabled
597
+ */
598
+ getRateLimitStats(name: string): RateLimitStats | undefined {
599
+ return this.rateLimiter?.getStats(name)
600
+ }
601
+
602
+ /**
603
+ * Check if a backend is rate limited (no tokens available)
604
+ *
605
+ * @param name - Backend name
606
+ * @returns true if rate limited, false if available or limiter disabled
607
+ */
608
+ isRateLimited(name: string): boolean {
609
+ if (!this.rateLimiter) {
610
+ return false
611
+ }
612
+ return !this.rateLimiter.canAcquire(name)
613
+ }
614
+
615
+ /**
616
+ * Get all backends that are NOT rate limited
617
+ *
618
+ * @returns Array of backends with available rate limit tokens
619
+ */
620
+ getAvailable(): PrivacyBackend[] {
621
+ const all = this.getAll()
622
+ if (!this.rateLimiter) {
623
+ return all
624
+ }
625
+ return all.filter(backend => this.rateLimiter!.canAcquire(backend.name))
626
+ }
627
+
628
+ /**
629
+ * Get available backends for a specific chain
630
+ *
631
+ * Filters by both chain support and rate limit availability.
632
+ *
633
+ * @param chain - Chain type to filter by
634
+ * @returns Array of available backends supporting the chain
635
+ */
636
+ getAvailableByChain(chain: ChainType): PrivacyBackend[] {
637
+ return this.getAvailable().filter(backend => backend.chains.includes(chain))
638
+ }
639
+
640
+ /**
641
+ * Get backends that are both healthy AND not rate limited
642
+ *
643
+ * @returns Array of backends ready for use
644
+ */
645
+ getReady(): PrivacyBackend[] {
646
+ const healthy = this.getHealthy()
647
+ if (!this.rateLimiter) {
648
+ return healthy
649
+ }
650
+ return healthy.filter(backend => this.rateLimiter!.canAcquire(backend.name))
651
+ }
652
+
653
+ /**
654
+ * Get ready backends for a specific chain
655
+ *
656
+ * @param chain - Chain type to filter by
657
+ * @returns Array of ready backends supporting the chain
658
+ */
659
+ getReadyByChain(chain: ChainType): PrivacyBackend[] {
660
+ return this.getReady().filter(backend => backend.chains.includes(chain))
661
+ }
662
+
663
+ /**
664
+ * Reset rate limit state for a backend
665
+ *
666
+ * Refills bucket to max tokens and clears stats.
667
+ *
668
+ * @param name - Backend name
669
+ */
670
+ resetRateLimit(name: string): void {
671
+ this.rateLimiter?.reset(name)
672
+ }
673
+
674
+ /**
675
+ * Dispose rate limiter resources
676
+ *
677
+ * Call when shutting down to clean up queue processing intervals.
678
+ */
679
+ disposeRateLimiter(): void {
680
+ this.rateLimiter?.dispose()
681
+ }
270
682
  }
271
683
 
272
684
  /**