@sip-protocol/sdk 0.7.3 → 0.7.4

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 (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +267 -0
  3. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  4. package/dist/browser.d.mts +10 -4
  5. package/dist/browser.d.ts +10 -4
  6. package/dist/browser.js +47556 -19603
  7. package/dist/browser.mjs +628 -48
  8. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  9. package/dist/chunk-5D7A3L3W.mjs +717 -0
  10. package/dist/chunk-64AYA5F5.mjs +7834 -0
  11. package/dist/chunk-GMDGB22A.mjs +379 -0
  12. package/dist/chunk-I534WKN7.mjs +328 -0
  13. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  14. package/dist/chunk-PRRZAWJE.mjs +223 -0
  15. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  16. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  17. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  18. package/dist/constants-LHAAUC2T.mjs +51 -0
  19. package/dist/dist-2OGQ7FED.mjs +3957 -0
  20. package/dist/dist-IFHPYLDX.mjs +254 -0
  21. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  22. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  23. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  24. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48396 -19623
  28. package/dist/index.mjs +537 -19
  29. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  30. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  31. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  32. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  33. package/dist/proofs/halo2.d.mts +151 -0
  34. package/dist/proofs/halo2.d.ts +151 -0
  35. package/dist/proofs/halo2.js +350 -0
  36. package/dist/proofs/halo2.mjs +11 -0
  37. package/dist/proofs/kimchi.d.mts +160 -0
  38. package/dist/proofs/kimchi.d.ts +160 -0
  39. package/dist/proofs/kimchi.js +431 -0
  40. package/dist/proofs/kimchi.mjs +13 -0
  41. package/dist/proofs/noir.d.mts +1 -1
  42. package/dist/proofs/noir.d.ts +1 -1
  43. package/dist/proofs/noir.js +74 -18
  44. package/dist/proofs/noir.mjs +84 -24
  45. package/dist/solana-U3MEGU7W.mjs +280 -0
  46. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  47. package/package.json +54 -21
  48. package/src/adapters/index.ts +41 -0
  49. package/src/adapters/jupiter.ts +571 -0
  50. package/src/adapters/near-intents.ts +135 -0
  51. package/src/advisor/advisor.ts +653 -0
  52. package/src/advisor/index.ts +54 -0
  53. package/src/advisor/tools.ts +303 -0
  54. package/src/advisor/types.ts +164 -0
  55. package/src/chains/ethereum/announcement.ts +536 -0
  56. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  57. package/src/chains/ethereum/commitment.ts +522 -0
  58. package/src/chains/ethereum/constants.ts +462 -0
  59. package/src/chains/ethereum/deployment.ts +596 -0
  60. package/src/chains/ethereum/gas-estimation.ts +538 -0
  61. package/src/chains/ethereum/index.ts +268 -0
  62. package/src/chains/ethereum/optimizations.ts +614 -0
  63. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  64. package/src/chains/ethereum/registry.ts +584 -0
  65. package/src/chains/ethereum/rpc.ts +905 -0
  66. package/src/chains/ethereum/stealth.ts +491 -0
  67. package/src/chains/ethereum/token.ts +790 -0
  68. package/src/chains/ethereum/transfer.ts +637 -0
  69. package/src/chains/ethereum/types.ts +456 -0
  70. package/src/chains/ethereum/viewing-key.ts +455 -0
  71. package/src/chains/near/commitment.ts +608 -0
  72. package/src/chains/near/constants.ts +284 -0
  73. package/src/chains/near/function-call.ts +871 -0
  74. package/src/chains/near/history.ts +654 -0
  75. package/src/chains/near/implicit-account.ts +840 -0
  76. package/src/chains/near/index.ts +393 -0
  77. package/src/chains/near/native-transfer.ts +658 -0
  78. package/src/chains/near/nep141.ts +775 -0
  79. package/src/chains/near/privacy-adapter.ts +889 -0
  80. package/src/chains/near/resolver.ts +971 -0
  81. package/src/chains/near/rpc.ts +1016 -0
  82. package/src/chains/near/stealth.ts +419 -0
  83. package/src/chains/near/types.ts +317 -0
  84. package/src/chains/near/viewing-key.ts +876 -0
  85. package/src/chains/solana/anchor-transfer.ts +386 -0
  86. package/src/chains/solana/commitment.ts +577 -0
  87. package/src/chains/solana/constants.ts +126 -12
  88. package/src/chains/solana/ephemeral-keys.ts +543 -0
  89. package/src/chains/solana/index.ts +252 -1
  90. package/src/chains/solana/key-derivation.ts +418 -0
  91. package/src/chains/solana/kit-compat.ts +334 -0
  92. package/src/chains/solana/optimizations.ts +560 -0
  93. package/src/chains/solana/privacy-adapter.ts +605 -0
  94. package/src/chains/solana/providers/generic.ts +47 -6
  95. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  96. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  97. package/src/chains/solana/providers/helius.ts +186 -33
  98. package/src/chains/solana/providers/index.ts +31 -0
  99. package/src/chains/solana/providers/interface.ts +61 -18
  100. package/src/chains/solana/providers/quicknode.ts +409 -0
  101. package/src/chains/solana/providers/triton.ts +426 -0
  102. package/src/chains/solana/providers/webhook.ts +338 -67
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +83 -66
  105. package/src/chains/solana/sol-transfer.ts +732 -0
  106. package/src/chains/solana/spl-transfer.ts +886 -0
  107. package/src/chains/solana/stealth-scanner.ts +703 -0
  108. package/src/chains/solana/sunspot-verifier.ts +453 -0
  109. package/src/chains/solana/transaction-builder.ts +755 -0
  110. package/src/chains/solana/transfer.ts +74 -5
  111. package/src/chains/solana/types.ts +57 -6
  112. package/src/chains/solana/utils.ts +110 -0
  113. package/src/chains/solana/viewing-key.ts +807 -0
  114. package/src/compliance/fireblocks.ts +921 -0
  115. package/src/compliance/index.ts +23 -0
  116. package/src/compliance/range-sas.ts +398 -33
  117. package/src/config/endpoints.ts +100 -0
  118. package/src/crypto.ts +11 -8
  119. package/src/errors.ts +82 -0
  120. package/src/evm/erc4337-relayer.ts +830 -0
  121. package/src/evm/index.ts +47 -0
  122. package/src/fees/calculator.ts +396 -0
  123. package/src/fees/index.ts +87 -0
  124. package/src/fees/near-contract.ts +429 -0
  125. package/src/fees/types.ts +268 -0
  126. package/src/index.ts +686 -1
  127. package/src/intent.ts +6 -3
  128. package/src/logger.ts +324 -0
  129. package/src/network/index.ts +80 -0
  130. package/src/network/proxy.ts +691 -0
  131. package/src/optimizations/index.ts +541 -0
  132. package/src/oracle/types.ts +1 -0
  133. package/src/privacy-backends/arcium-types.ts +727 -0
  134. package/src/privacy-backends/arcium.ts +719 -0
  135. package/src/privacy-backends/combined-privacy.ts +866 -0
  136. package/src/privacy-backends/cspl-token.ts +595 -0
  137. package/src/privacy-backends/cspl-types.ts +512 -0
  138. package/src/privacy-backends/cspl.ts +907 -0
  139. package/src/privacy-backends/health.ts +488 -0
  140. package/src/privacy-backends/inco-types.ts +323 -0
  141. package/src/privacy-backends/inco.ts +616 -0
  142. package/src/privacy-backends/index.ts +254 -4
  143. package/src/privacy-backends/interface.ts +649 -6
  144. package/src/privacy-backends/lru-cache.ts +343 -0
  145. package/src/privacy-backends/magicblock.ts +458 -0
  146. package/src/privacy-backends/mock.ts +258 -0
  147. package/src/privacy-backends/privacycash.ts +13 -17
  148. package/src/privacy-backends/private-swap.ts +570 -0
  149. package/src/privacy-backends/rate-limiter.ts +683 -0
  150. package/src/privacy-backends/registry.ts +414 -2
  151. package/src/privacy-backends/router.ts +283 -3
  152. package/src/privacy-backends/shadowwire.ts +449 -0
  153. package/src/privacy-backends/sip-native.ts +3 -0
  154. package/src/privacy-logger.ts +191 -0
  155. package/src/production-safety.ts +373 -0
  156. package/src/proofs/aggregator.ts +1029 -0
  157. package/src/proofs/browser-composer.ts +1150 -0
  158. package/src/proofs/browser.ts +113 -25
  159. package/src/proofs/cache/index.ts +127 -0
  160. package/src/proofs/cache/interface.ts +545 -0
  161. package/src/proofs/cache/key-generator.ts +188 -0
  162. package/src/proofs/cache/lru-cache.ts +481 -0
  163. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  164. package/src/proofs/cache/persistent-cache.ts +788 -0
  165. package/src/proofs/compliance-proof.ts +872 -0
  166. package/src/proofs/composer/base.ts +923 -0
  167. package/src/proofs/composer/index.ts +25 -0
  168. package/src/proofs/composer/interface.ts +518 -0
  169. package/src/proofs/composer/types.ts +383 -0
  170. package/src/proofs/converters/halo2.ts +452 -0
  171. package/src/proofs/converters/index.ts +208 -0
  172. package/src/proofs/converters/interface.ts +363 -0
  173. package/src/proofs/converters/kimchi.ts +462 -0
  174. package/src/proofs/converters/noir.ts +451 -0
  175. package/src/proofs/fallback.ts +888 -0
  176. package/src/proofs/halo2.ts +42 -0
  177. package/src/proofs/index.ts +471 -0
  178. package/src/proofs/interface.ts +13 -0
  179. package/src/proofs/kimchi.ts +42 -0
  180. package/src/proofs/lazy.ts +1004 -0
  181. package/src/proofs/mock.ts +25 -1
  182. package/src/proofs/noir.ts +110 -29
  183. package/src/proofs/orchestrator.ts +960 -0
  184. package/src/proofs/parallel/concurrency.ts +297 -0
  185. package/src/proofs/parallel/dependency-graph.ts +602 -0
  186. package/src/proofs/parallel/executor.ts +420 -0
  187. package/src/proofs/parallel/index.ts +131 -0
  188. package/src/proofs/parallel/interface.ts +685 -0
  189. package/src/proofs/parallel/worker-pool.ts +644 -0
  190. package/src/proofs/providers/halo2.ts +560 -0
  191. package/src/proofs/providers/index.ts +34 -0
  192. package/src/proofs/providers/kimchi.ts +641 -0
  193. package/src/proofs/validator.ts +881 -0
  194. package/src/proofs/verifier.ts +867 -0
  195. package/src/quantum/index.ts +112 -0
  196. package/src/quantum/winternitz-vault.ts +639 -0
  197. package/src/quantum/wots.ts +611 -0
  198. package/src/settlement/backends/direct-chain.ts +1 -0
  199. package/src/settlement/index.ts +9 -0
  200. package/src/settlement/router.ts +732 -46
  201. package/src/solana/index.ts +72 -0
  202. package/src/solana/jito-relayer.ts +687 -0
  203. package/src/solana/noir-verifier-types.ts +430 -0
  204. package/src/solana/noir-verifier.ts +816 -0
  205. package/src/stealth/address-derivation.ts +193 -0
  206. package/src/stealth/ed25519.ts +431 -0
  207. package/src/stealth/index.ts +233 -0
  208. package/src/stealth/meta-address.ts +221 -0
  209. package/src/stealth/secp256k1.ts +368 -0
  210. package/src/stealth/utils.ts +194 -0
  211. package/src/stealth.ts +50 -1504
  212. package/src/sync/index.ts +106 -0
  213. package/src/sync/manager.ts +504 -0
  214. package/src/sync/mock-provider.ts +318 -0
  215. package/src/sync/oblivious.ts +625 -0
  216. package/src/tokens/index.ts +15 -0
  217. package/src/tokens/registry.ts +301 -0
  218. package/src/utils/deprecation.ts +94 -0
  219. package/src/utils/index.ts +9 -0
  220. package/src/wallet/ethereum/index.ts +68 -0
  221. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  222. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  223. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  224. package/src/wallet/ethereum/types.ts +3 -1
  225. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  226. package/src/wallet/hardware/index.ts +10 -0
  227. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  228. package/src/wallet/index.ts +71 -0
  229. package/src/wallet/near/adapter.ts +626 -0
  230. package/src/wallet/near/index.ts +86 -0
  231. package/src/wallet/near/meteor-wallet.ts +1153 -0
  232. package/src/wallet/near/my-near-wallet.ts +790 -0
  233. package/src/wallet/near/wallet-selector.ts +702 -0
  234. package/src/wallet/solana/adapter.ts +6 -4
  235. package/src/wallet/solana/index.ts +13 -0
  236. package/src/wallet/solana/privacy-adapter.ts +567 -0
  237. package/src/wallet/sui/types.ts +6 -4
  238. package/src/zcash/rpc-client.ts +13 -6
  239. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  240. package/dist/chunk-3INS3PR5.mjs +0 -884
  241. package/dist/chunk-3OVABDRH.mjs +0 -17096
  242. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  243. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  244. package/dist/chunk-E6SZWREQ.mjs +0 -57
  245. package/dist/chunk-F6F73W35.mjs +0 -16166
  246. package/dist/chunk-G33LB27A.mjs +0 -16166
  247. package/dist/chunk-HGU6HZRC.mjs +0 -231
  248. package/dist/chunk-L2K34JCU.mjs +0 -1496
  249. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  250. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  251. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  252. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  253. package/dist/constants-VOI7BSLK.mjs +0 -27
  254. package/dist/index-B71aXVzk.d.ts +0 -13264
  255. package/dist/index-BYZbDjal.d.ts +0 -11390
  256. package/dist/index-CHB3KuOB.d.mts +0 -11859
  257. package/dist/index-CzWPI6Le.d.ts +0 -11859
  258. package/dist/index-pOIIuwfV.d.mts +0 -13264
  259. package/dist/index-xbWjohNq.d.mts +0 -11390
  260. package/dist/solana-4O4K45VU.mjs +0 -46
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-NDABAZ6P.mjs +0 -56
  263. package/dist/solana-Q4NAVBTS.mjs +0 -46
  264. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -5,6 +5,13 @@
5
5
  * - User preferences (privacy, speed, cost, compliance)
6
6
  * - Backend capabilities and availability
7
7
  * - Transfer parameters
8
+ * - Backend health status (circuit breaker)
9
+ *
10
+ * ## Features
11
+ *
12
+ * - **Health-aware selection**: Skips backends with open circuit breakers
13
+ * - **Automatic fallback**: Tries alternatives when primary backend fails
14
+ * - **Metrics tracking**: Records success/failure for health monitoring
8
15
  *
9
16
  * @example
10
17
  * ```typescript
@@ -15,10 +22,11 @@
15
22
  *
16
23
  * const router = new SmartRouter(registry)
17
24
  *
18
- * // Auto-select best backend
25
+ * // Auto-select best backend with fallback
19
26
  * const result = await router.execute(params, {
20
27
  * prioritize: 'compliance',
21
28
  * requireViewingKeys: true,
29
+ * enableFallback: true,
22
30
  * })
23
31
  *
24
32
  * // Or just select without executing
@@ -31,10 +39,13 @@ import type {
31
39
  PrivacyBackend,
32
40
  TransferParams,
33
41
  TransactionResult,
42
+ ComputationParams,
43
+ ComputationResult,
34
44
  SmartRouterConfig,
35
45
  BackendSelectionResult,
36
46
  AvailabilityResult,
37
47
  } from './interface'
48
+ import { AllBackendsFailedError } from './interface'
38
49
  import { PrivacyBackendRegistry } from './registry'
39
50
 
40
51
  /**
@@ -44,6 +55,9 @@ const DEFAULT_CONFIG: SmartRouterConfig = {
44
55
  prioritize: 'privacy',
45
56
  requireViewingKeys: false,
46
57
  allowComputePrivacy: true,
58
+ enableFallback: true,
59
+ includeUnhealthy: false,
60
+ maxFallbackAttempts: 3,
47
61
  }
48
62
 
49
63
  /**
@@ -131,6 +145,11 @@ export class SmartRouter {
131
145
  continue
132
146
  }
133
147
 
148
+ // Check health status (circuit breaker)
149
+ if (!fullConfig.includeUnhealthy && !this.registry.isHealthy(backend.name)) {
150
+ continue
151
+ }
152
+
134
153
  // Check availability
135
154
  const availability = await backend.checkAvailability(params)
136
155
  if (!availability.available) {
@@ -233,16 +252,277 @@ export class SmartRouter {
233
252
  /**
234
253
  * Execute a transfer using the best available backend
235
254
  *
255
+ * Includes automatic fallback to alternatives if the primary backend fails
256
+ * (when enableFallback is true). Records success/failure for health tracking.
257
+ *
236
258
  * @param params - Transfer parameters
237
259
  * @param config - Router configuration
238
260
  * @returns Transaction result
261
+ * @throws AllBackendsFailedError if all backends fail
239
262
  */
240
263
  async execute(
241
264
  params: TransferParams,
242
265
  config: Partial<SmartRouterConfig> = {}
243
266
  ): Promise<TransactionResult> {
244
- const selection = await this.selectBackend(params, config)
245
- return selection.backend.execute(params)
267
+ const fullConfig = {
268
+ ...DEFAULT_CONFIG,
269
+ ...config,
270
+ allowComputePrivacy: false, // Only transaction backends for execute()
271
+ }
272
+ const selection = await this.selectBackend(params, fullConfig)
273
+
274
+ // Try primary backend
275
+ const result = await this.executeOnBackend(selection.backend, params)
276
+
277
+ if (result.success) {
278
+ return result
279
+ }
280
+
281
+ // Primary failed, try fallback if enabled
282
+ if (!fullConfig.enableFallback || selection.alternatives.length === 0) {
283
+ return result
284
+ }
285
+
286
+ // Try alternatives
287
+ const attemptedBackends = [selection.backend.name]
288
+ const errors = new Map<string, string>()
289
+ errors.set(selection.backend.name, result.error || 'Unknown error')
290
+
291
+ const maxFallbackAttempts = fullConfig.maxFallbackAttempts ?? 3
292
+
293
+ // Iterate over all alternatives, but limit actual attempts
294
+ // Skipped backends (unhealthy/already attempted) don't count against the limit
295
+ let actualAttempts = 0
296
+ for (
297
+ let i = 0;
298
+ i < selection.alternatives.length && actualAttempts < maxFallbackAttempts;
299
+ i++
300
+ ) {
301
+ const alternative = selection.alternatives[i]
302
+
303
+ // Skip if already attempted (defensive - shouldn't happen with unique names)
304
+ if (attemptedBackends.includes(alternative.backend.name)) {
305
+ continue
306
+ }
307
+
308
+ // Skip unhealthy backends unless explicitly included
309
+ if (!fullConfig.includeUnhealthy && !this.registry.isHealthy(alternative.backend.name)) {
310
+ continue
311
+ }
312
+
313
+ // This counts as an actual attempt
314
+ actualAttempts++
315
+ attemptedBackends.push(alternative.backend.name)
316
+ const fallbackResult = await this.executeOnBackend(alternative.backend, params)
317
+
318
+ if (fallbackResult.success) {
319
+ // Add metadata about fallback
320
+ return {
321
+ ...fallbackResult,
322
+ metadata: {
323
+ ...fallbackResult.metadata,
324
+ fallbackFrom: selection.backend.name,
325
+ attemptedBackends,
326
+ },
327
+ }
328
+ }
329
+
330
+ errors.set(alternative.backend.name, fallbackResult.error || 'Unknown error')
331
+ }
332
+
333
+ // All attempts failed
334
+ throw new AllBackendsFailedError(attemptedBackends, errors, params)
335
+ }
336
+
337
+ /**
338
+ * Execute on a specific backend with health tracking
339
+ *
340
+ * @param backend - Backend to execute on
341
+ * @param params - Transfer parameters
342
+ * @returns Transaction result (never throws, returns error in result)
343
+ */
344
+ private async executeOnBackend(
345
+ backend: PrivacyBackend,
346
+ params: TransferParams
347
+ ): Promise<TransactionResult> {
348
+ const startTime = Date.now()
349
+
350
+ try {
351
+ const result = await backend.execute(params)
352
+ const latency = Date.now() - startTime
353
+
354
+ if (result.success) {
355
+ this.registry.recordSuccess(backend.name, latency)
356
+ } else {
357
+ this.registry.recordFailure(backend.name, result.error || 'Execution returned failure')
358
+ }
359
+
360
+ return result
361
+ } catch (error) {
362
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error'
363
+ this.registry.recordFailure(backend.name, errorMessage)
364
+
365
+ return {
366
+ success: false,
367
+ error: errorMessage,
368
+ backend: backend.name,
369
+ }
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Execute a computation using the best available compute backend
375
+ *
376
+ * Selects from compute-type backends (Arcium, Inco) and executes
377
+ * the computation via MPC/FHE.
378
+ *
379
+ * @param params - Computation parameters
380
+ * @param config - Router configuration
381
+ * @returns Computation result
382
+ * @throws Error if no compute backend is available or supports the computation
383
+ *
384
+ * @example
385
+ * ```typescript
386
+ * const result = await router.executeComputation({
387
+ * chain: 'solana',
388
+ * circuitId: 'private-swap',
389
+ * encryptedInputs: [encryptedAmount, encryptedPrice],
390
+ * })
391
+ * ```
392
+ */
393
+ async executeComputation(
394
+ params: ComputationParams,
395
+ config: Partial<SmartRouterConfig> = {}
396
+ ): Promise<ComputationResult> {
397
+ const selection = await this.selectComputeBackend(params, config)
398
+
399
+ if (!selection.backend.executeComputation) {
400
+ throw new Error(
401
+ `Backend '${selection.backend.name}' does not support compute operations. ` +
402
+ `This should not happen - please report this bug.`
403
+ )
404
+ }
405
+
406
+ return selection.backend.executeComputation(params)
407
+ }
408
+
409
+ /**
410
+ * Select the best compute backend for a computation
411
+ *
412
+ * @param params - Computation parameters
413
+ * @param config - Router configuration
414
+ * @returns Selection result with backend and reasoning
415
+ * @throws Error if no suitable compute backend is found
416
+ */
417
+ async selectComputeBackend(
418
+ params: ComputationParams,
419
+ config: Partial<SmartRouterConfig> = {}
420
+ ): Promise<BackendSelectionResult> {
421
+ const fullConfig = { ...DEFAULT_CONFIG, ...config }
422
+
423
+ // Get all backends for the chain
424
+ const chainBackends = this.registry.getByChain(params.chain)
425
+
426
+ // Filter to compute backends only
427
+ const computeBackends = chainBackends.filter(
428
+ b => b.type === 'compute' || b.type === 'both'
429
+ )
430
+
431
+ if (computeBackends.length === 0) {
432
+ throw new Error(
433
+ `No compute backends available for chain '${params.chain}'. ` +
434
+ `Register a compute backend (e.g., ArciumBackend) that supports this chain.`
435
+ )
436
+ }
437
+
438
+ // Filter and score backends
439
+ const scoredBackends: Array<{
440
+ backend: PrivacyBackend
441
+ availability: AvailabilityResult
442
+ score: number
443
+ reason: string
444
+ }> = []
445
+
446
+ for (const backend of computeBackends) {
447
+ // Check exclusions
448
+ if (fullConfig.excludeBackends?.includes(backend.name)) {
449
+ continue
450
+ }
451
+
452
+ // Check availability
453
+ const availability = await backend.checkAvailability(params)
454
+ if (!availability.available) {
455
+ continue
456
+ }
457
+
458
+ // Check cost limit
459
+ if (fullConfig.maxCost && availability.estimatedCost) {
460
+ if (availability.estimatedCost > fullConfig.maxCost) {
461
+ continue
462
+ }
463
+ }
464
+
465
+ // Check latency limit
466
+ if (fullConfig.maxLatency && availability.estimatedTime) {
467
+ if (availability.estimatedTime > fullConfig.maxLatency) {
468
+ continue
469
+ }
470
+ }
471
+
472
+ // Score this backend
473
+ const { score, reason } = this.scoreBackend(
474
+ backend,
475
+ availability,
476
+ fullConfig
477
+ )
478
+
479
+ scoredBackends.push({
480
+ backend,
481
+ availability,
482
+ score,
483
+ reason,
484
+ })
485
+ }
486
+
487
+ if (scoredBackends.length === 0) {
488
+ throw new Error(
489
+ `No compute backends meet the requirements for this computation. ` +
490
+ `Check that the circuit exists and the cluster is available.`
491
+ )
492
+ }
493
+
494
+ // Sort by score (descending)
495
+ scoredBackends.sort((a, b) => b.score - a.score)
496
+
497
+ // Preferred backend bonus
498
+ if (fullConfig.preferredBackend) {
499
+ const preferredIndex = scoredBackends.findIndex(
500
+ s => s.backend.name === fullConfig.preferredBackend
501
+ )
502
+ if (preferredIndex > 0) {
503
+ const preferred = scoredBackends[preferredIndex]
504
+ const leader = scoredBackends[0]
505
+ if (leader.score - preferred.score <= 10) {
506
+ scoredBackends.splice(preferredIndex, 1)
507
+ scoredBackends.unshift(preferred)
508
+ preferred.reason = `Preferred backend (within 10pts of optimal)`
509
+ }
510
+ }
511
+ }
512
+
513
+ const selected = scoredBackends[0]
514
+ const alternatives = scoredBackends.slice(1).map(s => ({
515
+ backend: s.backend,
516
+ score: s.score,
517
+ reason: s.reason,
518
+ }))
519
+
520
+ return {
521
+ backend: selected.backend,
522
+ reason: selected.reason,
523
+ alternatives,
524
+ score: selected.score,
525
+ }
246
526
  }
247
527
 
248
528
  /**