@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.
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +47556 -19603
- package/dist/browser.mjs +628 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
- package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48396 -19623
- package/dist/index.mjs +537 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +54 -21
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +252 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +47 -6
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +186 -33
- package/src/chains/solana/providers/index.ts +31 -0
- package/src/chains/solana/providers/interface.ts +61 -18
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +338 -67
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +83 -66
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +57 -6
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +23 -0
- package/src/compliance/range-sas.ts +398 -33
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +686 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +254 -4
- package/src/privacy-backends/interface.ts +649 -6
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash.ts +13 -17
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +414 -2
- package/src/privacy-backends/router.ts +283 -3
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +3 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +110 -29
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-2XIVXWHA.mjs +0 -1930
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-7RFRWDCW.mjs +0 -1504
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-F6F73W35.mjs +0 -16166
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-OFDBEIEK.mjs +0 -16166
- package/dist/chunk-SF7YSLF5.mjs +0 -1515
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/chunk-WWUSGOXE.mjs +0 -17129
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-B71aXVzk.d.ts +0 -13264
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-pOIIuwfV.d.mts +0 -13264
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-4O4K45VU.mjs +0 -46
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-NDABAZ6P.mjs +0 -56
- package/dist/solana-Q4NAVBTS.mjs +0 -46
- 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
|
|
245
|
-
|
|
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
|
/**
|