@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
@@ -137,6 +137,159 @@ export interface AvailabilityResult {
137
137
  estimatedTime?: number
138
138
  }
139
139
 
140
+ // ─── Compute Privacy Types ───────────────────────────────────────────────────
141
+
142
+ /**
143
+ * Supported cipher types for encrypted computation
144
+ */
145
+ export type CipherType = 'aes128' | 'aes192' | 'aes256' | 'rescue'
146
+
147
+ /**
148
+ * Computation status for tracking MPC/FHE operations
149
+ */
150
+ export type ComputationStatus =
151
+ | 'submitted'
152
+ | 'encrypting'
153
+ | 'processing'
154
+ | 'finalizing'
155
+ | 'completed'
156
+ | 'failed'
157
+
158
+ /**
159
+ * Parameters for a privacy-preserving computation
160
+ *
161
+ * Used by compute backends (Arcium, Inco) for MPC/FHE operations.
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * const params: ComputationParams = {
166
+ * chain: 'solana',
167
+ * circuitId: 'private-swap',
168
+ * encryptedInputs: [encryptedAmount, encryptedPrice],
169
+ * cluster: 'mainnet-cluster-1',
170
+ * }
171
+ * ```
172
+ */
173
+ export interface ComputationParams {
174
+ /** Target blockchain */
175
+ chain: ChainType
176
+ /** Circuit or program identifier for the computation */
177
+ circuitId: string
178
+ /** Encrypted inputs for the MPC/FHE computation */
179
+ encryptedInputs: Uint8Array[]
180
+ /** MPC cluster or FHE node to use */
181
+ cluster?: string
182
+ /** Callback address for computation results */
183
+ callbackAddress?: string
184
+ /** Cipher type for input encryption */
185
+ cipher?: CipherType
186
+ /** Timeout in milliseconds */
187
+ timeout?: number
188
+ /** Additional backend-specific options */
189
+ options?: Record<string, unknown>
190
+ }
191
+
192
+ /**
193
+ * Result of a privacy-preserving computation
194
+ *
195
+ * Returned by compute backends after MPC/FHE execution.
196
+ */
197
+ export interface ComputationResult {
198
+ /** Whether the computation was successful */
199
+ success: boolean
200
+ /** Unique computation identifier for tracking */
201
+ computationId?: string
202
+ /** Decrypted output data (if available and authorized) */
203
+ output?: Uint8Array
204
+ /** Error message if failed */
205
+ error?: string
206
+ /** Backend that executed the computation */
207
+ backend: string
208
+ /** Current computation status */
209
+ status?: ComputationStatus
210
+ /** Cryptographic proof of correct computation */
211
+ proof?: HexString
212
+ /** Timestamp when computation completed */
213
+ completedAt?: number
214
+ /** Additional metadata */
215
+ metadata?: Record<string, unknown>
216
+ }
217
+
218
+ /**
219
+ * Union type for backend operation parameters
220
+ *
221
+ * Backends accept either transfer params (transaction privacy)
222
+ * or computation params (compute privacy).
223
+ */
224
+ export type BackendParams = TransferParams | ComputationParams
225
+
226
+ /**
227
+ * Type guard to check if params are for computation
228
+ */
229
+ export function isComputationParams(
230
+ params: BackendParams
231
+ ): params is ComputationParams {
232
+ return 'circuitId' in params && 'encryptedInputs' in params
233
+ }
234
+
235
+ /**
236
+ * Type guard to check if params are for transfer
237
+ */
238
+ export function isTransferParams(
239
+ params: BackendParams
240
+ ): params is TransferParams {
241
+ return 'sender' in params && 'recipient' in params && 'amount' in params
242
+ }
243
+
244
+ // ─── Interface Versioning ────────────────────────────────────────────────────
245
+
246
+ /**
247
+ * PrivacyBackend interface version
248
+ *
249
+ * ## Version History
250
+ *
251
+ * - **v1** (initial): Basic backend interface with execute/checkAvailability
252
+ * - **v2** (current): Added version field, compute privacy support, circuit breaker integration
253
+ *
254
+ * ## Migration Guide
255
+ *
256
+ * ### v1 → v2
257
+ *
258
+ * 1. Add `version` property (set to 2)
259
+ * 2. Optional: Implement `executeComputation()` for compute backends
260
+ * 3. Optional: Add circuit breaker integration via `onHealthChange` callback
261
+ *
262
+ * ```typescript
263
+ * // v1 backend (deprecated)
264
+ * class MyBackendV1 implements PrivacyBackend {
265
+ * name = 'my-backend'
266
+ * type = 'transaction'
267
+ * chains = ['solana']
268
+ * // ... no version field
269
+ * }
270
+ *
271
+ * // v2 backend (current)
272
+ * class MyBackendV2 implements PrivacyBackend {
273
+ * version = 2
274
+ * name = 'my-backend'
275
+ * type = 'transaction'
276
+ * chains = ['solana']
277
+ * // ...
278
+ * }
279
+ * ```
280
+ */
281
+ export type PrivacyBackendVersion = 1 | 2
282
+
283
+ /**
284
+ * Current interface version
285
+ */
286
+ export const CURRENT_BACKEND_VERSION: PrivacyBackendVersion = 2
287
+
288
+ /**
289
+ * Minimum supported version (backends below this will be rejected)
290
+ */
291
+ export const MIN_SUPPORTED_VERSION: PrivacyBackendVersion = 1
292
+
140
293
  // ─── Privacy Backend Interface ───────────────────────────────────────────────
141
294
 
142
295
  /**
@@ -144,8 +297,42 @@ export interface AvailabilityResult {
144
297
  *
145
298
  * All privacy implementations (SIP Native, PrivacyCash, Arcium, Inco)
146
299
  * must implement this interface for unified access.
300
+ *
301
+ * ## Interface Version
302
+ *
303
+ * The current interface version is **v2**. Backends should set `version: 2`.
304
+ * v1 backends without a version field are still supported but deprecated.
305
+ *
306
+ * ## Backend Types
307
+ *
308
+ * - **Transaction backends** (type: 'transaction'): Implement `execute()` for transfers
309
+ * - **Compute backends** (type: 'compute'): Implement `executeComputation()` for MPC/FHE
310
+ * - **Hybrid backends** (type: 'both'): Implement both methods
311
+ *
312
+ * @example
313
+ * ```typescript
314
+ * // Transaction backend usage
315
+ * const sipNative = new SIPNativeBackend()
316
+ * await sipNative.execute({ chain: 'solana', sender, recipient, amount, ... })
317
+ *
318
+ * // Compute backend usage
319
+ * const arcium = new ArciumBackend()
320
+ * await arcium.executeComputation({ chain: 'solana', circuitId, encryptedInputs, ... })
321
+ * ```
147
322
  */
148
323
  export interface PrivacyBackend {
324
+ /**
325
+ * Interface version implemented by this backend
326
+ *
327
+ * - v1: Initial interface (deprecated, no version field)
328
+ * - v2: Current interface with versioning support
329
+ *
330
+ * Backends without a version field are treated as v1 with deprecation warning.
331
+ *
332
+ * @default 1 (for backwards compatibility)
333
+ */
334
+ readonly version?: PrivacyBackendVersion
335
+
149
336
  /** Unique backend identifier */
150
337
  readonly name: string
151
338
 
@@ -153,15 +340,18 @@ export interface PrivacyBackend {
153
340
  readonly type: BackendType
154
341
 
155
342
  /** Supported blockchain networks */
156
- readonly chains: ChainType[]
343
+ readonly chains: string[]
157
344
 
158
345
  /**
159
346
  * Check if backend is available for given parameters
160
347
  *
161
- * @param params - Transfer parameters
348
+ * Accepts either TransferParams (for transaction backends) or
349
+ * ComputationParams (for compute backends).
350
+ *
351
+ * @param params - Transfer or computation parameters
162
352
  * @returns Availability result with cost/time estimates
163
353
  */
164
- checkAvailability(params: TransferParams): Promise<AvailabilityResult>
354
+ checkAvailability(params: BackendParams): Promise<AvailabilityResult>
165
355
 
166
356
  /**
167
357
  * Get backend capabilities and trade-offs
@@ -173,18 +363,34 @@ export interface PrivacyBackend {
173
363
  /**
174
364
  * Execute a privacy-preserving transfer
175
365
  *
366
+ * Implemented by transaction backends (SIP Native, PrivacyCash).
367
+ * Compute backends should return an error directing users to executeComputation().
368
+ *
176
369
  * @param params - Transfer parameters
177
370
  * @returns Transaction result
178
371
  */
179
372
  execute(params: TransferParams): Promise<TransactionResult>
180
373
 
181
374
  /**
182
- * Estimate cost for a transfer (without executing)
375
+ * Execute a privacy-preserving computation
183
376
  *
184
- * @param params - Transfer parameters
377
+ * Implemented by compute backends (Arcium, Inco).
378
+ * Transaction backends do not implement this method.
379
+ *
380
+ * @param params - Computation parameters
381
+ * @returns Computation result with status and output
382
+ */
383
+ executeComputation?(params: ComputationParams): Promise<ComputationResult>
384
+
385
+ /**
386
+ * Estimate cost for an operation (without executing)
387
+ *
388
+ * Accepts either TransferParams or ComputationParams.
389
+ *
390
+ * @param params - Transfer or computation parameters
185
391
  * @returns Estimated cost in native token smallest units
186
392
  */
187
- estimateCost(params: TransferParams): Promise<bigint>
393
+ estimateCost(params: BackendParams): Promise<bigint>
188
394
  }
189
395
 
190
396
  // ─── SmartRouter Types ───────────────────────────────────────────────────────
@@ -214,6 +420,21 @@ export interface SmartRouterConfig {
214
420
  maxCost?: bigint
215
421
  /** Maximum acceptable latency in ms */
216
422
  maxLatency?: number
423
+ /**
424
+ * Enable automatic fallback to alternative backends on failure
425
+ * @default true
426
+ */
427
+ enableFallback?: boolean
428
+ /**
429
+ * Include unhealthy backends (circuit open) in selection
430
+ * @default false
431
+ */
432
+ includeUnhealthy?: boolean
433
+ /**
434
+ * Maximum number of fallback attempts
435
+ * @default 3
436
+ */
437
+ maxFallbackAttempts?: number
217
438
  }
218
439
 
219
440
  /**
@@ -261,3 +482,425 @@ export interface RegisteredBackend {
261
482
  /** Registration timestamp */
262
483
  registeredAt: number
263
484
  }
485
+
486
+ // ─── Health & Circuit Breaker Types ─────────────────────────────────────────
487
+
488
+ /**
489
+ * Circuit breaker state
490
+ *
491
+ * - `closed`: Backend is healthy, requests flow normally
492
+ * - `open`: Backend is failing, requests are blocked
493
+ * - `half-open`: Testing if backend recovered, limited requests allowed
494
+ */
495
+ export type CircuitState = 'closed' | 'open' | 'half-open'
496
+
497
+ /**
498
+ * Health state tracking for circuit breaker pattern
499
+ *
500
+ * Tracks backend health to automatically disable failing backends
501
+ * and re-enable them after recovery.
502
+ */
503
+ export interface BackendHealthState {
504
+ /** Current circuit state */
505
+ circuitState: CircuitState
506
+ /** Whether backend is considered healthy (circuit closed or half-open) */
507
+ isHealthy: boolean
508
+ /** Last health check timestamp */
509
+ lastChecked: number
510
+ /** Number of consecutive failures */
511
+ consecutiveFailures: number
512
+ /** Number of consecutive successes (for half-open recovery) */
513
+ consecutiveSuccesses: number
514
+ /** Last failure reason */
515
+ lastFailureReason?: string
516
+ /** Last failure timestamp */
517
+ lastFailureTime?: number
518
+ /** Timestamp when circuit opened */
519
+ circuitOpenedAt?: number
520
+ }
521
+
522
+ /**
523
+ * Metrics for backend observability
524
+ *
525
+ * Tracks request counts and latency for monitoring and debugging.
526
+ */
527
+ export interface BackendMetrics {
528
+ /** Total requests made to this backend */
529
+ totalRequests: number
530
+ /** Successful requests */
531
+ successfulRequests: number
532
+ /** Failed requests */
533
+ failedRequests: number
534
+ /** Total latency in milliseconds (for average calculation) */
535
+ totalLatencyMs: number
536
+ /** Average latency in milliseconds */
537
+ averageLatencyMs: number
538
+ /** Last request timestamp */
539
+ lastRequestTime: number
540
+ /** Last successful request timestamp */
541
+ lastSuccessTime?: number
542
+ /** Minimum latency observed */
543
+ minLatencyMs?: number
544
+ /** Maximum latency observed */
545
+ maxLatencyMs?: number
546
+ }
547
+
548
+ /**
549
+ * Circuit breaker configuration
550
+ *
551
+ * Controls when backends are disabled and re-enabled.
552
+ */
553
+ export interface CircuitBreakerConfig {
554
+ /**
555
+ * Number of consecutive failures before opening circuit
556
+ * @default 3
557
+ */
558
+ failureThreshold: number
559
+ /**
560
+ * Time in ms before attempting to close circuit (half-open state)
561
+ * @default 30000 (30 seconds)
562
+ */
563
+ resetTimeoutMs: number
564
+ /**
565
+ * Number of successful requests in half-open state before closing circuit
566
+ * @default 2
567
+ */
568
+ successThreshold: number
569
+ /**
570
+ * Whether to track metrics
571
+ * @default true
572
+ */
573
+ enableMetrics: boolean
574
+ }
575
+
576
+ /**
577
+ * Default circuit breaker configuration
578
+ */
579
+ export const DEFAULT_CIRCUIT_BREAKER_CONFIG: CircuitBreakerConfig = {
580
+ failureThreshold: 3,
581
+ resetTimeoutMs: 30000,
582
+ successThreshold: 2,
583
+ enableMetrics: true,
584
+ }
585
+
586
+ // ─── Error Types ────────────────────────────────────────────────────────────
587
+
588
+ /**
589
+ * Error thrown when all backends fail during execution
590
+ *
591
+ * Contains details about which backends were attempted and why they failed.
592
+ */
593
+ export class AllBackendsFailedError extends Error {
594
+ readonly name = 'AllBackendsFailedError'
595
+
596
+ constructor(
597
+ /** Backends that were attempted */
598
+ public readonly attemptedBackends: string[],
599
+ /** Map of backend name to error message */
600
+ public readonly errors: Map<string, string>,
601
+ /** Original transfer parameters */
602
+ public readonly params?: TransferParams
603
+ ) {
604
+ const backendList = attemptedBackends.join(', ')
605
+ super(
606
+ `All ${attemptedBackends.length} backend(s) failed: [${backendList}]. ` +
607
+ `Check errors map for details.`
608
+ )
609
+ // Fix prototype chain for instanceof in transpiled code
610
+ Object.setPrototypeOf(this, AllBackendsFailedError.prototype)
611
+ }
612
+
613
+ /**
614
+ * Get formatted error summary
615
+ */
616
+ getSummary(): string {
617
+ const lines = [`All backends failed (${this.attemptedBackends.length} attempted):`]
618
+ for (const [backend, error] of this.errors) {
619
+ lines.push(` • ${backend}: ${error}`)
620
+ }
621
+ return lines.join('\n')
622
+ }
623
+ }
624
+
625
+ /**
626
+ * Error thrown when circuit breaker is open
627
+ */
628
+ export class CircuitOpenError extends Error {
629
+ readonly name = 'CircuitOpenError'
630
+
631
+ constructor(
632
+ /** Backend name with open circuit */
633
+ public readonly backendName: string,
634
+ /** Time when circuit opened */
635
+ public readonly openedAt: number,
636
+ /** Time until reset attempt */
637
+ public readonly resetTimeoutMs: number
638
+ ) {
639
+ const remainingMs = Math.max(0, (openedAt + resetTimeoutMs) - Date.now())
640
+ const remainingSec = Math.ceil(remainingMs / 1000)
641
+ super(
642
+ `Circuit breaker open for '${backendName}'. ` +
643
+ `Will attempt reset in ${remainingSec}s.`
644
+ )
645
+ // Fix prototype chain for instanceof in transpiled code
646
+ Object.setPrototypeOf(this, CircuitOpenError.prototype)
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Error thrown when a computation times out
652
+ */
653
+ export class ComputationTimeoutError extends Error {
654
+ readonly name = 'ComputationTimeoutError'
655
+
656
+ constructor(
657
+ /** Computation identifier */
658
+ public readonly computationId: string,
659
+ /** Timeout duration in milliseconds */
660
+ public readonly timeoutMs: number,
661
+ /** Backend name where timeout occurred */
662
+ public readonly backendName: string
663
+ ) {
664
+ super(
665
+ `Computation '${computationId}' timed out after ${timeoutMs}ms ` +
666
+ `on backend '${backendName}'`
667
+ )
668
+ // Fix prototype chain for instanceof in transpiled code
669
+ Object.setPrototypeOf(this, ComputationTimeoutError.prototype)
670
+ }
671
+ }
672
+
673
+ // ─── Timeout Utilities ────────────────────────────────────────────────────────
674
+
675
+ /**
676
+ * Wrap a promise with a timeout
677
+ *
678
+ * @param promise - The promise to wrap
679
+ * @param timeoutMs - Timeout in milliseconds
680
+ * @param onTimeout - Function to call when timeout occurs, should throw an error
681
+ * @returns The promise result or throws the timeout error
682
+ *
683
+ * @example
684
+ * ```typescript
685
+ * const result = await withTimeout(
686
+ * fetchData(),
687
+ * 5000,
688
+ * () => { throw new Error('Request timed out') }
689
+ * )
690
+ * ```
691
+ */
692
+ export async function withTimeout<T>(
693
+ promise: Promise<T>,
694
+ timeoutMs: number,
695
+ onTimeout: () => never
696
+ ): Promise<T> {
697
+ let timeoutId: ReturnType<typeof setTimeout> | undefined
698
+
699
+ const timeoutPromise = new Promise<never>((_, reject) => {
700
+ timeoutId = setTimeout(() => {
701
+ try {
702
+ onTimeout()
703
+ } catch (error) {
704
+ reject(error)
705
+ }
706
+ }, timeoutMs)
707
+ })
708
+
709
+ try {
710
+ return await Promise.race([promise, timeoutPromise])
711
+ } finally {
712
+ if (timeoutId !== undefined) {
713
+ clearTimeout(timeoutId)
714
+ }
715
+ }
716
+ }
717
+
718
+ // ─── Utility Functions ────────────────────────────────────────────────────────
719
+
720
+ /**
721
+ * Deep freeze an object to make it truly immutable
722
+ *
723
+ * Unlike Object.freeze() which only freezes the top level,
724
+ * this recursively freezes all nested objects and arrays.
725
+ *
726
+ * @param obj - Object to freeze
727
+ * @returns The same object, deeply frozen
728
+ *
729
+ * @example
730
+ * ```typescript
731
+ * const config = deepFreeze({ network: 'devnet', options: { timeout: 5000 } })
732
+ * config.options.timeout = 10000 // Error in strict mode, silently ignored otherwise
733
+ * ```
734
+ */
735
+ export function deepFreeze<T extends object>(obj: T): Readonly<T> {
736
+ // Get all properties including non-enumerable
737
+ const propNames = Object.getOwnPropertyNames(obj) as (keyof T)[]
738
+
739
+ // Freeze nested objects first (depth-first)
740
+ for (const name of propNames) {
741
+ const value = obj[name]
742
+ if (value && typeof value === 'object' && !Object.isFrozen(value)) {
743
+ deepFreeze(value as object)
744
+ }
745
+ }
746
+
747
+ // Freeze the object itself
748
+ return Object.freeze(obj)
749
+ }
750
+
751
+ // ─── Version Migration Helpers ───────────────────────────────────────────────
752
+
753
+ /**
754
+ * Result of version validation
755
+ */
756
+ export interface VersionValidationResult {
757
+ /** Whether the backend version is valid */
758
+ valid: boolean
759
+ /** Current version of the backend */
760
+ version: PrivacyBackendVersion
761
+ /** Whether the backend is using a deprecated version */
762
+ deprecated: boolean
763
+ /** Warning message if deprecated */
764
+ warning?: string
765
+ /** Error message if invalid */
766
+ error?: string
767
+ }
768
+
769
+ /**
770
+ * Validate a backend's interface version
771
+ *
772
+ * @param backend - The backend to validate
773
+ * @returns Validation result with version info and any warnings/errors
774
+ *
775
+ * @example
776
+ * ```typescript
777
+ * const result = validateBackendVersion(myBackend)
778
+ * if (result.deprecated) {
779
+ * console.warn(result.warning)
780
+ * }
781
+ * if (!result.valid) {
782
+ * throw new Error(result.error)
783
+ * }
784
+ * ```
785
+ */
786
+ export function validateBackendVersion(
787
+ backend: PrivacyBackend
788
+ ): VersionValidationResult {
789
+ const version = backend.version ?? 1
790
+
791
+ // Check if version is below minimum supported
792
+ if (version < MIN_SUPPORTED_VERSION) {
793
+ return {
794
+ valid: false,
795
+ version,
796
+ deprecated: true,
797
+ error: `Backend '${backend.name}' uses unsupported version ${version}. ` +
798
+ `Minimum supported version is ${MIN_SUPPORTED_VERSION}.`,
799
+ }
800
+ }
801
+
802
+ // Check if version is deprecated (v1 without explicit version field)
803
+ if (backend.version === undefined) {
804
+ return {
805
+ valid: true,
806
+ version: 1,
807
+ deprecated: true,
808
+ warning: `Backend '${backend.name}' does not specify a version field. ` +
809
+ `It is treated as v1 which is deprecated. ` +
810
+ `Please update to v${CURRENT_BACKEND_VERSION} by adding 'version: ${CURRENT_BACKEND_VERSION}'.`,
811
+ }
812
+ }
813
+
814
+ // Check if version is older than current
815
+ if (version < CURRENT_BACKEND_VERSION) {
816
+ return {
817
+ valid: true,
818
+ version,
819
+ deprecated: true,
820
+ warning: `Backend '${backend.name}' uses version ${version}. ` +
821
+ `Consider upgrading to v${CURRENT_BACKEND_VERSION} for latest features.`,
822
+ }
823
+ }
824
+
825
+ // Version is current
826
+ return {
827
+ valid: true,
828
+ version,
829
+ deprecated: false,
830
+ }
831
+ }
832
+
833
+ /**
834
+ * Get the effective version of a backend
835
+ *
836
+ * Returns 1 for backends without an explicit version field (v1 legacy).
837
+ *
838
+ * @param backend - The backend to check
839
+ * @returns The backend's interface version
840
+ */
841
+ export function getBackendVersion(backend: PrivacyBackend): PrivacyBackendVersion {
842
+ return backend.version ?? 1
843
+ }
844
+
845
+ /**
846
+ * Check if a backend supports a specific interface version
847
+ *
848
+ * @param backend - The backend to check
849
+ * @param minVersion - Minimum version required
850
+ * @returns True if backend version >= minVersion
851
+ */
852
+ export function backendSupportsVersion(
853
+ backend: PrivacyBackend,
854
+ minVersion: PrivacyBackendVersion
855
+ ): boolean {
856
+ return getBackendVersion(backend) >= minVersion
857
+ }
858
+
859
+ /**
860
+ * Type guard to check if backend is v2 or higher
861
+ *
862
+ * V2 backends have explicit version field and may have additional features.
863
+ */
864
+ export function isV2Backend(backend: PrivacyBackend): backend is PrivacyBackend & { version: 2 } {
865
+ return backend.version === 2
866
+ }
867
+
868
+ /**
869
+ * Log deprecation warning for v1 backends
870
+ *
871
+ * Call this when registering backends to warn about deprecated versions.
872
+ *
873
+ * @param backend - The backend to check
874
+ * @param logger - Optional custom logger (defaults to console.warn)
875
+ */
876
+ export function warnIfDeprecatedVersion(
877
+ backend: PrivacyBackend,
878
+ logger: (message: string) => void = console.warn
879
+ ): void {
880
+ const result = validateBackendVersion(backend)
881
+ if (result.deprecated && result.warning) {
882
+ logger(`[SIP-SDK] DEPRECATION WARNING: ${result.warning}`)
883
+ }
884
+ }
885
+
886
+ /**
887
+ * Error thrown when a backend version is not supported
888
+ */
889
+ export class UnsupportedVersionError extends Error {
890
+ readonly name = 'UnsupportedVersionError'
891
+
892
+ constructor(
893
+ /** Backend name */
894
+ public readonly backendName: string,
895
+ /** Backend version */
896
+ public readonly backendVersion: PrivacyBackendVersion,
897
+ /** Minimum supported version */
898
+ public readonly minSupported: PrivacyBackendVersion
899
+ ) {
900
+ super(
901
+ `Backend '${backendName}' uses version ${backendVersion}, ` +
902
+ `but minimum supported version is ${minSupported}.`
903
+ )
904
+ Object.setPrototypeOf(this, UnsupportedVersionError.prototype)
905
+ }
906
+ }