@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
|
@@ -69,6 +69,12 @@ import {
|
|
|
69
69
|
type PoolInfo,
|
|
70
70
|
type IPrivacyCashSDK,
|
|
71
71
|
} from './privacycash-types'
|
|
72
|
+
import { createPrivacyLogger } from '../privacy-logger'
|
|
73
|
+
|
|
74
|
+
/** Privacy-aware logger for PrivacyCash backend */
|
|
75
|
+
const privacyCashLogger = createPrivacyLogger('PrivacyCash')
|
|
76
|
+
|
|
77
|
+
import { randomBytes, bytesToHex } from '@noble/hashes/utils'
|
|
72
78
|
|
|
73
79
|
/**
|
|
74
80
|
* Default estimated anonymity set size
|
|
@@ -219,9 +225,8 @@ export class PrivacyCashBackend implements PrivacyBackend {
|
|
|
219
225
|
|
|
220
226
|
// Viewing keys are not supported - warn if provided
|
|
221
227
|
if (params.viewingKey) {
|
|
222
|
-
|
|
223
|
-
'
|
|
224
|
-
'Use SIP Native backend for compliance features.'
|
|
228
|
+
privacyCashLogger.warn(
|
|
229
|
+
'Viewing keys are not supported. Use SIP Native backend for compliance features.'
|
|
225
230
|
)
|
|
226
231
|
}
|
|
227
232
|
|
|
@@ -432,22 +437,13 @@ export class PrivacyCashBackend implements PrivacyBackend {
|
|
|
432
437
|
|
|
433
438
|
/**
|
|
434
439
|
* Generate a simulated withdrawal note
|
|
435
|
-
*
|
|
440
|
+
*
|
|
441
|
+
* Uses cryptographically secure random bytes.
|
|
442
|
+
* In production, this comes from the deposit transaction.
|
|
436
443
|
*/
|
|
437
444
|
private generateSimulatedNote(): string {
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
crypto.getRandomValues(randomBytes)
|
|
441
|
-
} else {
|
|
442
|
-
for (let i = 0; i < 32; i++) {
|
|
443
|
-
randomBytes[i] = Math.floor(Math.random() * 256)
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
// Convert to hex string (browser-compatible, no Buffer dependency)
|
|
447
|
-
const hex = Array.from(randomBytes)
|
|
448
|
-
.map(b => b.toString(16).padStart(2, '0'))
|
|
449
|
-
.join('')
|
|
450
|
-
return `privacycash:${hex}`
|
|
445
|
+
const bytes = randomBytes(32)
|
|
446
|
+
return `privacycash:${bytesToHex(bytes)}`
|
|
451
447
|
}
|
|
452
448
|
|
|
453
449
|
/**
|
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Private Swap Integration
|
|
3
|
+
*
|
|
4
|
+
* Combines SIP Native (stealth addresses), C-SPL (encrypted amounts),
|
|
5
|
+
* and Arcium (MPC swap logic) for fully private DeFi swaps.
|
|
6
|
+
*
|
|
7
|
+
* ## Privacy Stack
|
|
8
|
+
*
|
|
9
|
+
* ```
|
|
10
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
11
|
+
* │ FULL PRIVACY SWAP │
|
|
12
|
+
* │ │
|
|
13
|
+
* │ 1. SIP Native → Hidden recipient (stealth address) │
|
|
14
|
+
* │ 2. C-SPL → Hidden amounts (encrypted balances) │
|
|
15
|
+
* │ 3. Arcium → Hidden swap logic (MPC computation) │
|
|
16
|
+
* │ │
|
|
17
|
+
* │ Result: No one can see who swapped what for how much │
|
|
18
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ## Use Cases
|
|
22
|
+
*
|
|
23
|
+
* - Private DEX trading (no front-running)
|
|
24
|
+
* - Institutional OTC swaps
|
|
25
|
+
* - Private portfolio rebalancing
|
|
26
|
+
* - Confidential DeFi operations
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import {
|
|
31
|
+
* PrivateSwap,
|
|
32
|
+
* SIPNativeBackend,
|
|
33
|
+
* ArciumBackend,
|
|
34
|
+
* CSPLClient,
|
|
35
|
+
* } from '@sip-protocol/sdk'
|
|
36
|
+
*
|
|
37
|
+
* const swap = new PrivateSwap({
|
|
38
|
+
* sipBackend: new SIPNativeBackend(),
|
|
39
|
+
* arciumBackend: new ArciumBackend(),
|
|
40
|
+
* csplClient: new CSPLClient(),
|
|
41
|
+
* })
|
|
42
|
+
*
|
|
43
|
+
* const result = await swap.execute({
|
|
44
|
+
* inputToken: { mint: 'SOL_MINT', ... },
|
|
45
|
+
* outputToken: { mint: 'USDC_MINT', ... },
|
|
46
|
+
* inputAmount: 1_000_000_000n, // 1 SOL
|
|
47
|
+
* minOutputAmount: 50_000_000n, // Min 50 USDC
|
|
48
|
+
* user: walletAddress,
|
|
49
|
+
* })
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @see https://docs.arcium.com
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
import type { ComputationResult } from './interface'
|
|
56
|
+
import type { SIPNativeBackend } from './sip-native'
|
|
57
|
+
import type { ArciumBackend } from './arcium'
|
|
58
|
+
import type { CSPLClient } from './cspl'
|
|
59
|
+
import type {
|
|
60
|
+
CSPLToken,
|
|
61
|
+
ConfidentialSwapParams,
|
|
62
|
+
ConfidentialSwapResult,
|
|
63
|
+
EncryptedAmount,
|
|
64
|
+
} from './cspl-types'
|
|
65
|
+
|
|
66
|
+
import { sha256 } from '@noble/hashes/sha256'
|
|
67
|
+
import { bytesToHex } from '@noble/hashes/utils'
|
|
68
|
+
|
|
69
|
+
// ─── Configuration ────────────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Configuration for PrivateSwap
|
|
73
|
+
*/
|
|
74
|
+
export interface PrivateSwapConfig {
|
|
75
|
+
/** SIP Native backend for stealth addresses */
|
|
76
|
+
sipBackend: SIPNativeBackend
|
|
77
|
+
/** Arcium backend for MPC swap logic */
|
|
78
|
+
arciumBackend: ArciumBackend
|
|
79
|
+
/** C-SPL client for confidential tokens */
|
|
80
|
+
csplClient: CSPLClient
|
|
81
|
+
/** Default slippage in basis points */
|
|
82
|
+
defaultSlippageBps?: number
|
|
83
|
+
/** Swap deadline in seconds from now */
|
|
84
|
+
defaultDeadlineSeconds?: number
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Parameters for executing a private swap
|
|
89
|
+
*/
|
|
90
|
+
export interface PrivateSwapParams {
|
|
91
|
+
/** Input token being sold */
|
|
92
|
+
inputToken: CSPLToken
|
|
93
|
+
/** Output token being bought */
|
|
94
|
+
outputToken: CSPLToken
|
|
95
|
+
/** Input amount (plaintext, will be encrypted) */
|
|
96
|
+
inputAmount: bigint
|
|
97
|
+
/** Minimum output amount (slippage protection) */
|
|
98
|
+
minOutputAmount?: bigint
|
|
99
|
+
/** Slippage in basis points (overrides default) */
|
|
100
|
+
slippageBps?: number
|
|
101
|
+
/** Deadline timestamp (overrides default) */
|
|
102
|
+
deadline?: number
|
|
103
|
+
/** User's wallet address */
|
|
104
|
+
user: string
|
|
105
|
+
/** Use stealth address for output (full privacy) */
|
|
106
|
+
useStealthOutput?: boolean
|
|
107
|
+
/** Viewing key for compliance (optional) */
|
|
108
|
+
viewingKey?: string
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Result of a private swap
|
|
113
|
+
*/
|
|
114
|
+
export interface PrivateSwapResult {
|
|
115
|
+
/** Whether swap succeeded */
|
|
116
|
+
success: boolean
|
|
117
|
+
/** Combined transaction signatures */
|
|
118
|
+
signatures: string[]
|
|
119
|
+
/** Arcium computation ID */
|
|
120
|
+
computationId?: string
|
|
121
|
+
/** Output amount received (if decryption available) */
|
|
122
|
+
outputAmount?: bigint
|
|
123
|
+
/** Stealth address used for output (if enabled) */
|
|
124
|
+
stealthAddress?: string
|
|
125
|
+
/** Total fees paid */
|
|
126
|
+
totalFees?: bigint
|
|
127
|
+
/** Swap route taken */
|
|
128
|
+
route?: string[]
|
|
129
|
+
/** Error message if failed */
|
|
130
|
+
error?: string
|
|
131
|
+
/** Detailed step results */
|
|
132
|
+
steps?: PrivateSwapStep[]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Individual step in a private swap
|
|
137
|
+
*/
|
|
138
|
+
export interface PrivateSwapStep {
|
|
139
|
+
/** Step name */
|
|
140
|
+
name: string
|
|
141
|
+
/** Step status */
|
|
142
|
+
status: 'pending' | 'processing' | 'completed' | 'failed'
|
|
143
|
+
/** Transaction signature (if applicable) */
|
|
144
|
+
signature?: string
|
|
145
|
+
/** Duration in milliseconds */
|
|
146
|
+
durationMs?: number
|
|
147
|
+
/** Error if step failed */
|
|
148
|
+
error?: string
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ─── Private Swap Class ───────────────────────────────────────────────────────
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Private Swap Orchestrator
|
|
155
|
+
*
|
|
156
|
+
* Coordinates SIP Native, C-SPL, and Arcium for fully private swaps.
|
|
157
|
+
*/
|
|
158
|
+
export class PrivateSwap {
|
|
159
|
+
private sipBackend: SIPNativeBackend
|
|
160
|
+
private arciumBackend: ArciumBackend
|
|
161
|
+
private csplClient: CSPLClient
|
|
162
|
+
private defaultSlippageBps: number
|
|
163
|
+
private defaultDeadlineSeconds: number
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Create a new PrivateSwap instance
|
|
167
|
+
*
|
|
168
|
+
* @param config - Configuration with required backends
|
|
169
|
+
*/
|
|
170
|
+
constructor(config: PrivateSwapConfig) {
|
|
171
|
+
if (!config.sipBackend) {
|
|
172
|
+
throw new Error('SIPNativeBackend is required')
|
|
173
|
+
}
|
|
174
|
+
if (!config.arciumBackend) {
|
|
175
|
+
throw new Error('ArciumBackend is required')
|
|
176
|
+
}
|
|
177
|
+
if (!config.csplClient) {
|
|
178
|
+
throw new Error('CSPLClient is required')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
this.sipBackend = config.sipBackend
|
|
182
|
+
this.arciumBackend = config.arciumBackend
|
|
183
|
+
this.csplClient = config.csplClient
|
|
184
|
+
this.defaultSlippageBps = config.defaultSlippageBps ?? 50 // 0.5%
|
|
185
|
+
this.defaultDeadlineSeconds = config.defaultDeadlineSeconds ?? 300 // 5 minutes
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Execute a fully private swap
|
|
190
|
+
*
|
|
191
|
+
* Steps:
|
|
192
|
+
* 1. Wrap input tokens to C-SPL (if not already)
|
|
193
|
+
* 2. Encrypt input amount
|
|
194
|
+
* 3. Execute swap via Arcium MPC
|
|
195
|
+
* 4. Receive output to stealth address (if enabled)
|
|
196
|
+
*
|
|
197
|
+
* @param params - Swap parameters
|
|
198
|
+
* @returns Swap result
|
|
199
|
+
*/
|
|
200
|
+
async execute(params: PrivateSwapParams): Promise<PrivateSwapResult> {
|
|
201
|
+
const steps: PrivateSwapStep[] = []
|
|
202
|
+
const signatures: string[] = []
|
|
203
|
+
let startTime = Date.now()
|
|
204
|
+
|
|
205
|
+
try {
|
|
206
|
+
// ─── Step 1: Validate Inputs ──────────────────────────────────────────────
|
|
207
|
+
const validation = this.validateParams(params)
|
|
208
|
+
if (!validation.valid) {
|
|
209
|
+
return {
|
|
210
|
+
success: false,
|
|
211
|
+
signatures: [],
|
|
212
|
+
error: validation.error,
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ─── Step 2: Wrap Input Token to C-SPL ────────────────────────────────────
|
|
217
|
+
steps.push({ name: 'wrap_input', status: 'processing' })
|
|
218
|
+
const wrapResult = await this.csplClient.wrapToken({
|
|
219
|
+
mint: params.inputToken.mint,
|
|
220
|
+
amount: params.inputAmount,
|
|
221
|
+
owner: params.user,
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
if (!wrapResult.success) {
|
|
225
|
+
steps[steps.length - 1].status = 'failed'
|
|
226
|
+
steps[steps.length - 1].error = wrapResult.error
|
|
227
|
+
return {
|
|
228
|
+
success: false,
|
|
229
|
+
signatures,
|
|
230
|
+
error: `Failed to wrap input token: ${wrapResult.error}`,
|
|
231
|
+
steps,
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
steps[steps.length - 1].status = 'completed'
|
|
236
|
+
steps[steps.length - 1].signature = wrapResult.signature
|
|
237
|
+
steps[steps.length - 1].durationMs = Date.now() - startTime
|
|
238
|
+
if (wrapResult.signature) signatures.push(wrapResult.signature)
|
|
239
|
+
startTime = Date.now()
|
|
240
|
+
|
|
241
|
+
// ─── Step 3: Encrypt Input Amount ─────────────────────────────────────────
|
|
242
|
+
steps.push({ name: 'encrypt_amount', status: 'processing' })
|
|
243
|
+
const encryptedInput = await this.csplClient.encryptAmount({
|
|
244
|
+
amount: params.inputAmount,
|
|
245
|
+
})
|
|
246
|
+
steps[steps.length - 1].status = 'completed'
|
|
247
|
+
steps[steps.length - 1].durationMs = Date.now() - startTime
|
|
248
|
+
startTime = Date.now()
|
|
249
|
+
|
|
250
|
+
// ─── Step 4: Encrypt Min Output (Slippage Protection) ─────────────────────
|
|
251
|
+
let encryptedMinOutput: EncryptedAmount | undefined
|
|
252
|
+
if (params.minOutputAmount) {
|
|
253
|
+
steps.push({ name: 'encrypt_min_output', status: 'processing' })
|
|
254
|
+
encryptedMinOutput = await this.csplClient.encryptAmount({
|
|
255
|
+
amount: params.minOutputAmount,
|
|
256
|
+
})
|
|
257
|
+
steps[steps.length - 1].status = 'completed'
|
|
258
|
+
steps[steps.length - 1].durationMs = Date.now() - startTime
|
|
259
|
+
startTime = Date.now()
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ─── Step 5: Generate Stealth Address (if enabled) ────────────────────────
|
|
263
|
+
let stealthAddress: string | undefined
|
|
264
|
+
if (params.useStealthOutput) {
|
|
265
|
+
steps.push({ name: 'generate_stealth', status: 'processing' })
|
|
266
|
+
// In production: Use SIP Native to generate stealth address
|
|
267
|
+
// const stealthResult = await this.sipBackend.generateStealthAddress(...)
|
|
268
|
+
stealthAddress = this.generateSimulatedStealthAddress(params.user)
|
|
269
|
+
steps[steps.length - 1].status = 'completed'
|
|
270
|
+
steps[steps.length - 1].durationMs = Date.now() - startTime
|
|
271
|
+
startTime = Date.now()
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// ─── Step 6: Execute Swap via Arcium MPC ──────────────────────────────────
|
|
275
|
+
steps.push({ name: 'arcium_swap', status: 'processing' })
|
|
276
|
+
const swapResult = await this.executeArciumSwap({
|
|
277
|
+
inputToken: params.inputToken,
|
|
278
|
+
outputToken: params.outputToken,
|
|
279
|
+
encryptedInputAmount: encryptedInput.ciphertext,
|
|
280
|
+
encryptedMinOutput: encryptedMinOutput?.ciphertext,
|
|
281
|
+
slippageBps: params.slippageBps ?? this.defaultSlippageBps,
|
|
282
|
+
deadline: params.deadline ?? this.calculateDeadline(),
|
|
283
|
+
user: stealthAddress ?? params.user,
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
if (!swapResult.success) {
|
|
287
|
+
steps[steps.length - 1].status = 'failed'
|
|
288
|
+
steps[steps.length - 1].error = swapResult.error
|
|
289
|
+
return {
|
|
290
|
+
success: false,
|
|
291
|
+
signatures,
|
|
292
|
+
computationId: swapResult.computationId,
|
|
293
|
+
error: `Arcium swap failed: ${swapResult.error}`,
|
|
294
|
+
steps,
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
steps[steps.length - 1].status = 'completed'
|
|
299
|
+
steps[steps.length - 1].durationMs = Date.now() - startTime
|
|
300
|
+
if (swapResult.computationId) {
|
|
301
|
+
// Track computation
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// ─── Step 7: Unwrap Output (Optional) ─────────────────────────────────────
|
|
305
|
+
// In a full implementation, user would decide whether to keep output
|
|
306
|
+
// as C-SPL or unwrap to regular SPL
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
success: true,
|
|
310
|
+
signatures,
|
|
311
|
+
computationId: swapResult.computationId,
|
|
312
|
+
outputAmount: swapResult.decryptedOutputAmount,
|
|
313
|
+
stealthAddress,
|
|
314
|
+
totalFees: this.estimateTotalFees(params),
|
|
315
|
+
route: [params.inputToken.symbol ?? 'INPUT', params.outputToken.symbol ?? 'OUTPUT'],
|
|
316
|
+
steps,
|
|
317
|
+
}
|
|
318
|
+
} catch (error) {
|
|
319
|
+
return {
|
|
320
|
+
success: false,
|
|
321
|
+
signatures,
|
|
322
|
+
error: error instanceof Error ? error.message : 'Unknown error during swap',
|
|
323
|
+
steps,
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Get a quote for a private swap (estimate only)
|
|
330
|
+
*
|
|
331
|
+
* @param params - Swap parameters
|
|
332
|
+
* @returns Estimated output and fees
|
|
333
|
+
*/
|
|
334
|
+
async getQuote(params: Omit<PrivateSwapParams, 'user'>): Promise<{
|
|
335
|
+
estimatedOutput: bigint
|
|
336
|
+
estimatedFees: bigint
|
|
337
|
+
priceImpact: number
|
|
338
|
+
route: string[]
|
|
339
|
+
}> {
|
|
340
|
+
// In production: Query AMM/DEX for actual quote
|
|
341
|
+
// This is a simplified simulation
|
|
342
|
+
|
|
343
|
+
// Simulate price (1 input token = 50 output tokens for demo)
|
|
344
|
+
const mockPrice = BigInt(50)
|
|
345
|
+
const estimatedOutput = params.inputAmount * mockPrice / BigInt(10 ** (params.inputToken.decimals - params.outputToken.decimals))
|
|
346
|
+
|
|
347
|
+
const estimatedFees = this.estimateTotalFees({
|
|
348
|
+
...params,
|
|
349
|
+
user: 'quote',
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
// Simplified price impact (larger trades = more impact)
|
|
353
|
+
const priceImpact = Math.min(
|
|
354
|
+
Number(params.inputAmount) / 1e12, // Normalize
|
|
355
|
+
5.0 // Max 5%
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
return {
|
|
359
|
+
estimatedOutput,
|
|
360
|
+
estimatedFees,
|
|
361
|
+
priceImpact,
|
|
362
|
+
route: [
|
|
363
|
+
params.inputToken.symbol ?? 'INPUT',
|
|
364
|
+
params.outputToken.symbol ?? 'OUTPUT',
|
|
365
|
+
],
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Check if a swap is possible
|
|
371
|
+
*
|
|
372
|
+
* @param params - Swap parameters
|
|
373
|
+
* @returns Whether swap can be executed
|
|
374
|
+
*/
|
|
375
|
+
async canSwap(params: PrivateSwapParams): Promise<{
|
|
376
|
+
canSwap: boolean
|
|
377
|
+
reason?: string
|
|
378
|
+
}> {
|
|
379
|
+
const validation = this.validateParams(params)
|
|
380
|
+
if (!validation.valid) {
|
|
381
|
+
return { canSwap: false, reason: validation.error }
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Check Arcium availability
|
|
385
|
+
const arciumAvailable = await this.arciumBackend.checkAvailability({
|
|
386
|
+
chain: 'solana',
|
|
387
|
+
circuitId: 'confidential-swap',
|
|
388
|
+
encryptedInputs: [new Uint8Array(64)],
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
if (!arciumAvailable.available) {
|
|
392
|
+
return { canSwap: false, reason: arciumAvailable.reason }
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return { canSwap: true }
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ─── Private Methods ──────────────────────────────────────────────────────────
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Validate swap parameters
|
|
402
|
+
*/
|
|
403
|
+
private validateParams(params: PrivateSwapParams): {
|
|
404
|
+
valid: boolean
|
|
405
|
+
error?: string
|
|
406
|
+
} {
|
|
407
|
+
if (!params.inputToken || !params.inputToken.mint) {
|
|
408
|
+
return { valid: false, error: 'Input token is required' }
|
|
409
|
+
}
|
|
410
|
+
if (!params.outputToken || !params.outputToken.mint) {
|
|
411
|
+
return { valid: false, error: 'Output token is required' }
|
|
412
|
+
}
|
|
413
|
+
if (params.inputAmount <= BigInt(0)) {
|
|
414
|
+
return { valid: false, error: 'Input amount must be greater than 0' }
|
|
415
|
+
}
|
|
416
|
+
if (!params.user || params.user.trim() === '') {
|
|
417
|
+
return { valid: false, error: 'User address is required' }
|
|
418
|
+
}
|
|
419
|
+
if (params.inputToken.mint === params.outputToken.mint) {
|
|
420
|
+
return { valid: false, error: 'Cannot swap token for itself' }
|
|
421
|
+
}
|
|
422
|
+
if (params.minOutputAmount && params.minOutputAmount <= BigInt(0)) {
|
|
423
|
+
return { valid: false, error: 'Min output amount must be greater than 0' }
|
|
424
|
+
}
|
|
425
|
+
if (params.slippageBps && (params.slippageBps < 0 || params.slippageBps > 10000)) {
|
|
426
|
+
return { valid: false, error: 'Slippage must be between 0 and 10000 bps' }
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return { valid: true }
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Execute swap via Arcium MPC
|
|
434
|
+
*/
|
|
435
|
+
private async executeArciumSwap(
|
|
436
|
+
params: ConfidentialSwapParams
|
|
437
|
+
): Promise<ConfidentialSwapResult> {
|
|
438
|
+
// Prepare encrypted inputs for Arcium MPC
|
|
439
|
+
const encryptedInputs = [
|
|
440
|
+
params.encryptedInputAmount,
|
|
441
|
+
params.encryptedMinOutput ?? new Uint8Array(64),
|
|
442
|
+
new TextEncoder().encode(params.inputToken.confidentialMint),
|
|
443
|
+
new TextEncoder().encode(params.outputToken.confidentialMint),
|
|
444
|
+
]
|
|
445
|
+
|
|
446
|
+
// Execute via Arcium
|
|
447
|
+
const result: ComputationResult = await this.arciumBackend.executeComputation({
|
|
448
|
+
chain: 'solana',
|
|
449
|
+
circuitId: 'confidential-swap-v1',
|
|
450
|
+
encryptedInputs,
|
|
451
|
+
options: {
|
|
452
|
+
slippageBps: params.slippageBps,
|
|
453
|
+
deadline: params.deadline,
|
|
454
|
+
user: params.user,
|
|
455
|
+
},
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
if (!result.success) {
|
|
459
|
+
return {
|
|
460
|
+
success: false,
|
|
461
|
+
error: result.error,
|
|
462
|
+
computationId: result.computationId,
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Await computation completion
|
|
467
|
+
const completion = await this.arciumBackend.awaitComputation(
|
|
468
|
+
result.computationId!
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
if (!completion.success) {
|
|
472
|
+
return {
|
|
473
|
+
success: false,
|
|
474
|
+
error: completion.error,
|
|
475
|
+
computationId: result.computationId,
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return {
|
|
480
|
+
success: true,
|
|
481
|
+
computationId: result.computationId,
|
|
482
|
+
encryptedOutputAmount: completion.output,
|
|
483
|
+
// In production: Decrypt output for user
|
|
484
|
+
decryptedOutputAmount: this.simulateOutputAmount(params),
|
|
485
|
+
metadata: {
|
|
486
|
+
dex: 'arcium-amm',
|
|
487
|
+
route: [params.inputToken.symbol ?? 'INPUT', params.outputToken.symbol ?? 'OUTPUT'],
|
|
488
|
+
},
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Calculate deadline timestamp
|
|
494
|
+
*/
|
|
495
|
+
private calculateDeadline(): number {
|
|
496
|
+
return Math.floor(Date.now() / 1000) + this.defaultDeadlineSeconds
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Estimate total fees for a swap
|
|
501
|
+
*/
|
|
502
|
+
private estimateTotalFees(params: PrivateSwapParams): bigint {
|
|
503
|
+
void params // Used in real implementation
|
|
504
|
+
// C-SPL wrap + Arcium computation + network fees
|
|
505
|
+
const wrapFee = BigInt(5_000)
|
|
506
|
+
const arciumFee = BigInt(50_000_000) // ~0.05 SOL for MPC
|
|
507
|
+
const networkFee = BigInt(10_000)
|
|
508
|
+
|
|
509
|
+
return wrapFee + arciumFee + networkFee
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Generate simulated stealth address
|
|
514
|
+
*/
|
|
515
|
+
private generateSimulatedStealthAddress(user: string): string {
|
|
516
|
+
const timestamp = Date.now().toString(36)
|
|
517
|
+
const hash = this.simpleHash(user + timestamp)
|
|
518
|
+
return `stealth_${hash}`
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Simulate output amount (for testing)
|
|
523
|
+
*/
|
|
524
|
+
private simulateOutputAmount(params: ConfidentialSwapParams): bigint {
|
|
525
|
+
void params // Would use actual price in production
|
|
526
|
+
// Simulate ~50:1 price ratio
|
|
527
|
+
return BigInt(50_000_000) // 50 USDC for 1 SOL
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Secure hash for simulation
|
|
532
|
+
*
|
|
533
|
+
* Uses SHA-256 for collision-resistant hashing.
|
|
534
|
+
*/
|
|
535
|
+
private simpleHash(input: string): string {
|
|
536
|
+
const encoder = new TextEncoder()
|
|
537
|
+
const hash = sha256(encoder.encode(input))
|
|
538
|
+
return bytesToHex(hash).slice(0, 16)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// ─── Getters ────────────────────────────────────────────────────────────────
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Get default slippage
|
|
545
|
+
*/
|
|
546
|
+
getDefaultSlippageBps(): number {
|
|
547
|
+
return this.defaultSlippageBps
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Get default deadline
|
|
552
|
+
*/
|
|
553
|
+
getDefaultDeadlineSeconds(): number {
|
|
554
|
+
return this.defaultDeadlineSeconds
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Get SIP backend name
|
|
559
|
+
*/
|
|
560
|
+
getSIPBackendName(): string {
|
|
561
|
+
return this.sipBackend.name
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Get Arcium backend name
|
|
566
|
+
*/
|
|
567
|
+
getArciumBackendName(): string {
|
|
568
|
+
return this.arciumBackend.name
|
|
569
|
+
}
|
|
570
|
+
}
|