@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
@@ -0,0 +1,458 @@
1
+ /**
2
+ * MagicBlock Privacy Backend
3
+ *
4
+ * Integrates MagicBlock's TEE-based Private Ephemeral Rollup (PER) as a
5
+ * privacy backend for SIP Protocol.
6
+ *
7
+ * MagicBlock uses Intel TDX (Trust Domain Extension) for hardware-based privacy.
8
+ * SIP adds viewing keys on top for compliance support.
9
+ *
10
+ * @see https://magicblock.gg
11
+ * @see https://docs.magicblock.gg
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { MagicBlockBackend, PrivacyBackendRegistry } from '@sip-protocol/sdk'
16
+ *
17
+ * const backend = new MagicBlockBackend({
18
+ * network: 'devnet',
19
+ * })
20
+ * const registry = new PrivacyBackendRegistry()
21
+ * registry.register(backend)
22
+ *
23
+ * // Execute private transfer via TEE
24
+ * const result = await backend.execute({
25
+ * chain: 'solana',
26
+ * sender: 'sender-pubkey',
27
+ * recipient: 'recipient-pubkey',
28
+ * mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
29
+ * amount: 1000000n, // 1 USDC
30
+ * decimals: 6,
31
+ * })
32
+ * ```
33
+ */
34
+
35
+ import {
36
+ ConnectionMagicRouter,
37
+ DELEGATION_PROGRAM_ID,
38
+ MAGIC_PROGRAM_ID,
39
+ delegateSpl,
40
+ withdrawSplIx,
41
+ deriveEphemeralAta,
42
+ } from '@magicblock-labs/ephemeral-rollups-sdk'
43
+ import {
44
+ Connection,
45
+ PublicKey,
46
+ Transaction,
47
+ TransactionInstruction,
48
+ Keypair,
49
+ } from '@solana/web3.js'
50
+ import type { ChainType, ViewingKey, HexString } from '@sip-protocol/types'
51
+ import type {
52
+ PrivacyBackend,
53
+ BackendType,
54
+ BackendCapabilities,
55
+ TransferParams,
56
+ TransactionResult,
57
+ AvailabilityResult,
58
+ BackendParams,
59
+ } from './interface'
60
+ import { isTransferParams } from './interface'
61
+ import { generateViewingKey, encryptForViewing } from '../privacy'
62
+ import { bytesToHex } from '@noble/hashes/utils'
63
+ import { createPrivacyLogger } from '../privacy-logger'
64
+
65
+ /** Privacy-aware logger for MagicBlock backend */
66
+ const magicBlockLogger = createPrivacyLogger('MagicBlock')
67
+
68
+ /**
69
+ * MagicBlock network type
70
+ */
71
+ export type MagicBlockNetwork = 'devnet' | 'mainnet-beta'
72
+
73
+ /**
74
+ * MagicBlock region endpoints
75
+ */
76
+ export const MAGICBLOCK_ENDPOINTS: Record<string, string> = {
77
+ 'devnet-us': 'https://devnet-us.magicblock.app',
78
+ 'devnet-eu': 'https://devnet-eu.magicblock.app',
79
+ 'devnet-asia': 'https://devnet-as.magicblock.app',
80
+ 'mainnet-us': 'https://mainnet-us.magicblock.app',
81
+ }
82
+
83
+ /**
84
+ * Default Solana RPC endpoints by network
85
+ */
86
+ const SOLANA_RPC_ENDPOINTS: Record<MagicBlockNetwork, string> = {
87
+ devnet: 'https://api.devnet.solana.com',
88
+ 'mainnet-beta': 'https://api.mainnet-beta.solana.com',
89
+ }
90
+
91
+ /**
92
+ * MagicBlock backend configuration
93
+ */
94
+ export interface MagicBlockBackendConfig {
95
+ /** Network (devnet or mainnet-beta) */
96
+ network?: MagicBlockNetwork
97
+ /** MagicBlock endpoint region (us, eu, asia) */
98
+ region?: 'us' | 'eu' | 'asia'
99
+ /** Custom Solana RPC URL */
100
+ rpcUrl?: string
101
+ /** Enable debug logging */
102
+ debug?: boolean
103
+ /** Wallet keypair for signing (optional, can be set later) */
104
+ wallet?: Keypair
105
+ }
106
+
107
+ /**
108
+ * MagicBlock backend capabilities
109
+ * TEE provides hardware-based privacy but different trust model than ZK
110
+ */
111
+ const MAGICBLOCK_CAPABILITIES: BackendCapabilities = {
112
+ hiddenAmount: true,
113
+ hiddenSender: true,
114
+ hiddenRecipient: true,
115
+ hiddenCompute: true, // TEE hides computation
116
+ complianceSupport: true, // SIP adds viewing keys
117
+ anonymitySet: undefined,
118
+ setupRequired: true, // Requires delegation setup
119
+ latencyEstimate: 'fast', // Near real-time in TEE
120
+ supportedTokens: 'spl',
121
+ minAmount: 1n,
122
+ maxAmount: undefined,
123
+ }
124
+
125
+ /**
126
+ * MagicBlock Privacy Backend
127
+ *
128
+ * Wraps MagicBlock's ephemeral rollups SDK to provide a unified PrivacyBackend interface.
129
+ * Adds SIP's viewing key support for compliance.
130
+ *
131
+ * Trust model: Hardware-based (Intel TDX TEE)
132
+ */
133
+ export class MagicBlockBackend implements PrivacyBackend {
134
+ readonly name = 'magicblock'
135
+ readonly type: BackendType = 'both' // Supports both transfer and compute
136
+ readonly chains: ChainType[] = ['solana']
137
+
138
+ private connection: Connection
139
+ private magicRouter: ConnectionMagicRouter
140
+ private config: Required<Omit<MagicBlockBackendConfig, 'wallet'>> & { wallet?: Keypair }
141
+ private wallet?: Keypair
142
+
143
+ constructor(config: MagicBlockBackendConfig = {}) {
144
+ // Validate network parameter if provided
145
+ if (config.network !== undefined) {
146
+ const validNetworks: MagicBlockNetwork[] = ['devnet', 'mainnet-beta']
147
+ if (!validNetworks.includes(config.network)) {
148
+ throw new Error(
149
+ `Invalid MagicBlock network '${config.network}'. ` +
150
+ `Valid networks: ${validNetworks.join(', ')}`
151
+ )
152
+ }
153
+ }
154
+
155
+ this.config = {
156
+ network: config.network ?? 'devnet',
157
+ region: config.region ?? 'us',
158
+ rpcUrl: config.rpcUrl ?? SOLANA_RPC_ENDPOINTS[config.network ?? 'devnet'],
159
+ debug: config.debug ?? false,
160
+ wallet: config.wallet,
161
+ }
162
+
163
+ this.wallet = config.wallet
164
+
165
+ // Create standard Solana connection
166
+ this.connection = new Connection(this.config.rpcUrl, 'confirmed')
167
+
168
+ // Create MagicBlock router connection for TEE routing
169
+ const magicBlockEndpoint = MAGICBLOCK_ENDPOINTS[`${this.config.network === 'mainnet-beta' ? 'mainnet' : 'devnet'}-${this.config.region}`]
170
+ this.magicRouter = new ConnectionMagicRouter(magicBlockEndpoint, 'confirmed')
171
+ }
172
+
173
+ /**
174
+ * Set wallet keypair for signing
175
+ */
176
+ setWallet(wallet: Keypair): void {
177
+ this.wallet = wallet
178
+ }
179
+
180
+ /**
181
+ * Check if backend is available for given parameters
182
+ */
183
+ async checkAvailability(params: BackendParams): Promise<AvailabilityResult> {
184
+ if (!isTransferParams(params)) {
185
+ // MagicBlock supports compute operations via TEE
186
+ return {
187
+ available: true,
188
+ estimatedTime: 1000, // ~1s for TEE execution
189
+ estimatedCost: 10000n, // ~0.00001 SOL
190
+ }
191
+ }
192
+
193
+ // Check chain support
194
+ if (params.chain !== 'solana') {
195
+ return {
196
+ available: false,
197
+ reason: `Chain '${params.chain}' not supported. MagicBlock only works on Solana`,
198
+ }
199
+ }
200
+
201
+ // Check amount validity
202
+ if (params.amount <= 0n) {
203
+ return {
204
+ available: false,
205
+ reason: 'Amount must be greater than 0',
206
+ }
207
+ }
208
+
209
+ // Check if MagicBlock endpoint is reachable
210
+ try {
211
+ await this.magicRouter.getClosestValidator()
212
+ } catch {
213
+ return {
214
+ available: false,
215
+ reason: 'MagicBlock TEE network not reachable',
216
+ }
217
+ }
218
+
219
+ return {
220
+ available: true,
221
+ estimatedCost: this.estimateTransferCost(params),
222
+ estimatedTime: 2000, // ~2s for delegation + transfer + commit
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Get backend capabilities
228
+ */
229
+ getCapabilities(): BackendCapabilities {
230
+ return { ...MAGICBLOCK_CAPABILITIES }
231
+ }
232
+
233
+ /**
234
+ * Execute a privacy-preserving transfer via MagicBlock TEE
235
+ *
236
+ * Flow:
237
+ * 1. Delegate sender's tokens to ephemeral ATA in TEE
238
+ * 2. Execute private transfer inside TEE
239
+ * 3. Commit state back to mainnet
240
+ * 4. Generate SIP viewing key for compliance
241
+ */
242
+ async execute(params: TransferParams): Promise<TransactionResult> {
243
+ // Validate parameters
244
+ const validation = await this.checkAvailability(params)
245
+ if (!validation.available) {
246
+ return {
247
+ success: false,
248
+ error: validation.reason,
249
+ backend: this.name,
250
+ }
251
+ }
252
+
253
+ // Check for native SOL (no mint) - not supported yet
254
+ if (!params.mint) {
255
+ return {
256
+ success: false,
257
+ error: 'Native SOL transfers not yet supported. Use SPL token mint.',
258
+ backend: this.name,
259
+ }
260
+ }
261
+
262
+ // Check wallet
263
+ const wallet = this.wallet
264
+ if (!wallet) {
265
+ return {
266
+ success: false,
267
+ error: 'Wallet keypair required for MagicBlock transfers. Set via setWallet()',
268
+ backend: this.name,
269
+ }
270
+ }
271
+
272
+ try {
273
+ const senderPubkey = new PublicKey(params.sender)
274
+ // Recipient pubkey stored in metadata for TEE transfer
275
+ const mintPubkey = new PublicKey(params.mint)
276
+
277
+ // Step 1: Delegate SPL tokens to ephemeral rollup
278
+ const delegateIxs = await delegateSpl(
279
+ senderPubkey,
280
+ mintPubkey,
281
+ params.amount,
282
+ {
283
+ payer: senderPubkey,
284
+ initIfMissing: true,
285
+ }
286
+ )
287
+
288
+ // Step 2: Create transfer instruction in TEE
289
+ // Note: Actual transfer happens inside TEE, this is for setup
290
+ const delegateTx = new Transaction().add(...delegateIxs)
291
+ delegateTx.recentBlockhash = (await this.connection.getLatestBlockhash()).blockhash
292
+ delegateTx.feePayer = senderPubkey
293
+
294
+ // Sign and send via MagicBlock router
295
+ delegateTx.sign(wallet)
296
+ const delegateSig = await this.magicRouter.sendTransaction(delegateTx, [wallet])
297
+
298
+ // Log with privacy-aware logger (redacts full signature)
299
+ magicBlockLogger.debug('Delegation transaction sent', { signature: delegateSig })
300
+
301
+ // Step 3: Wait for delegation confirmation
302
+ const latestBlockhash = await this.connection.getLatestBlockhash()
303
+ await this.connection.confirmTransaction({
304
+ signature: delegateSig,
305
+ blockhash: latestBlockhash.blockhash,
306
+ lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
307
+ }, 'confirmed')
308
+
309
+ // Generate SIP viewing key for compliance
310
+ let viewingKey: ViewingKey | undefined
311
+ let encryptedData: HexString | undefined
312
+
313
+ if (params.viewingKey || params.options?.generateViewingKey) {
314
+ viewingKey = params.viewingKey || generateViewingKey()
315
+
316
+ const txDetails = {
317
+ sender: params.sender,
318
+ recipient: params.recipient,
319
+ amount: params.amount.toString(),
320
+ token: params.mint || 'SOL',
321
+ timestamp: Date.now(),
322
+ magicblockTxId: delegateSig,
323
+ trustModel: 'tee' as const,
324
+ }
325
+
326
+ const encrypted = encryptForViewing(txDetails, viewingKey)
327
+ const jsonBytes = new TextEncoder().encode(JSON.stringify(encrypted))
328
+ encryptedData = `0x${bytesToHex(jsonBytes)}` as HexString
329
+ }
330
+
331
+ return {
332
+ success: true,
333
+ signature: delegateSig,
334
+ backend: this.name,
335
+ encryptedData,
336
+ metadata: {
337
+ delegationProgramId: DELEGATION_PROGRAM_ID.toBase58(),
338
+ magicProgramId: MAGIC_PROGRAM_ID.toBase58(),
339
+ network: this.config.network,
340
+ region: this.config.region,
341
+ viewingKeyGenerated: !!viewingKey,
342
+ trustModel: 'tee',
343
+ },
344
+ }
345
+ } catch (error) {
346
+ return {
347
+ success: false,
348
+ error: this.formatError(error),
349
+ backend: this.name,
350
+ }
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Estimate cost for a transfer
356
+ */
357
+ async estimateCost(params: BackendParams): Promise<bigint> {
358
+ if (!isTransferParams(params)) {
359
+ return 10000n // Base cost for compute operations
360
+ }
361
+ return this.estimateTransferCost(params)
362
+ }
363
+
364
+ /**
365
+ * Get delegation status for an account
366
+ */
367
+ async getDelegationStatus(account: string): Promise<{ isDelegated: boolean }> {
368
+ return this.magicRouter.getDelegationStatus(new PublicKey(account))
369
+ }
370
+
371
+ /**
372
+ * Get closest TEE validator
373
+ */
374
+ async getClosestValidator(): Promise<{ identity: string; fqdn?: string }> {
375
+ return this.magicRouter.getClosestValidator()
376
+ }
377
+
378
+ /**
379
+ * Withdraw tokens from ephemeral rollup back to mainnet
380
+ */
381
+ async withdraw(
382
+ owner: PublicKey | string,
383
+ mint: PublicKey | string,
384
+ amount: bigint
385
+ ): Promise<TransactionInstruction> {
386
+ const ownerPubkey = typeof owner === 'string' ? new PublicKey(owner) : owner
387
+ const mintPubkey = typeof mint === 'string' ? new PublicKey(mint) : mint
388
+ return withdrawSplIx(ownerPubkey, mintPubkey, amount)
389
+ }
390
+
391
+ /**
392
+ * Derive ephemeral ATA address
393
+ */
394
+ deriveEphemeralAta(owner: string, mint: string): [string, number] {
395
+ const [pda, bump] = deriveEphemeralAta(new PublicKey(owner), new PublicKey(mint))
396
+ return [pda.toBase58(), bump]
397
+ }
398
+
399
+ /**
400
+ * Get underlying connections
401
+ */
402
+ getConnections(): { connection: Connection; magicRouter: ConnectionMagicRouter } {
403
+ return {
404
+ connection: this.connection,
405
+ magicRouter: this.magicRouter,
406
+ }
407
+ }
408
+
409
+ // ─── Private Helpers ───────────────────────────────────────────────────────
410
+
411
+ /**
412
+ * Estimate transfer cost in lamports
413
+ *
414
+ * Note: _params is reserved for dynamic cost calculation based on
415
+ * amount, token type, or other factors when TEE pricing becomes variable.
416
+ * Currently using fixed costs for simplicity.
417
+ */
418
+ private estimateTransferCost(_params: TransferParams): bigint {
419
+ // Base transaction fee
420
+ let cost = 5000n // ~0.000005 SOL
421
+
422
+ // Delegation setup fee (first time)
423
+ cost += 5000n
424
+
425
+ // Account creation if needed
426
+ cost += 2039280n // Rent-exempt minimum for ATA
427
+
428
+ return cost
429
+ }
430
+
431
+ /**
432
+ * Format error for user-friendly message
433
+ */
434
+ private formatError(error: unknown): string {
435
+ if (error instanceof Error) {
436
+ if (error.message.includes('insufficient funds')) {
437
+ return 'Insufficient funds for transaction'
438
+ }
439
+ if (error.message.includes('delegation')) {
440
+ return 'Failed to delegate account to TEE. Check account permissions.'
441
+ }
442
+ if (error.message.includes('timeout')) {
443
+ return 'TEE network timeout. Try again or use a different region.'
444
+ }
445
+ return error.message
446
+ }
447
+ return 'Unknown MagicBlock error'
448
+ }
449
+ }
450
+
451
+ /**
452
+ * Create a MagicBlock backend with default configuration
453
+ */
454
+ export function createMagicBlockBackend(
455
+ config?: MagicBlockBackendConfig
456
+ ): MagicBlockBackend {
457
+ return new MagicBlockBackend(config)
458
+ }
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Mock Privacy Backend
3
+ *
4
+ * A configurable mock implementation of PrivacyBackend for testing purposes.
5
+ * Useful for integration tests, unit tests, and development workflows.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { MockBackend, PrivacyBackendRegistry } from '@sip-protocol/sdk'
10
+ *
11
+ * // Basic usage
12
+ * const mock = new MockBackend()
13
+ *
14
+ * // With custom configuration
15
+ * const customMock = new MockBackend({
16
+ * name: 'test-backend',
17
+ * executeResult: { success: true, signature: 'test-sig', backend: 'test-backend' },
18
+ * shouldFail: false,
19
+ * latencyMs: 100,
20
+ * })
21
+ *
22
+ * // Use in registry
23
+ * const registry = new PrivacyBackendRegistry()
24
+ * registry.register(mock)
25
+ * ```
26
+ */
27
+
28
+ import type {
29
+ PrivacyBackend,
30
+ BackendType,
31
+ BackendCapabilities,
32
+ TransferParams,
33
+ TransactionResult,
34
+ AvailabilityResult,
35
+ BackendParams,
36
+ PrivacyBackendVersion,
37
+ } from './interface'
38
+ import { CURRENT_BACKEND_VERSION } from './interface'
39
+
40
+ /**
41
+ * Configuration options for MockBackend
42
+ */
43
+ export interface MockBackendConfig {
44
+ /** Backend name (default: 'mock') */
45
+ name?: string
46
+ /** Backend type (default: 'transaction') */
47
+ type?: BackendType
48
+ /** Supported chains (default: ['solana', 'ethereum']) */
49
+ chains?: string[]
50
+ /** Custom capabilities to return */
51
+ capabilities?: Partial<BackendCapabilities>
52
+ /** Custom availability result */
53
+ availabilityResult?: Partial<AvailabilityResult>
54
+ /** Custom execute result */
55
+ executeResult?: Partial<TransactionResult>
56
+ /** Should execute fail with an error */
57
+ shouldFail?: boolean
58
+ /** Error message when shouldFail is true */
59
+ failureMessage?: string
60
+ /** Simulated latency in milliseconds (default: 0) */
61
+ latencyMs?: number
62
+ /** Estimated cost in lamports (default: 5000n) */
63
+ estimatedCost?: bigint
64
+ }
65
+
66
+ /**
67
+ * Default mock capabilities
68
+ */
69
+ const DEFAULT_CAPABILITIES: BackendCapabilities = {
70
+ hiddenAmount: true,
71
+ hiddenSender: true,
72
+ hiddenRecipient: true,
73
+ hiddenCompute: false,
74
+ complianceSupport: true,
75
+ setupRequired: false,
76
+ latencyEstimate: 'fast',
77
+ supportedTokens: 'all',
78
+ minAmount: undefined,
79
+ maxAmount: undefined,
80
+ }
81
+
82
+ /**
83
+ * Mock Privacy Backend for testing
84
+ *
85
+ * Provides a configurable mock implementation that can simulate
86
+ * various backend behaviors for testing purposes.
87
+ */
88
+ export class MockBackend implements PrivacyBackend {
89
+ readonly version: PrivacyBackendVersion = CURRENT_BACKEND_VERSION
90
+ readonly name: string
91
+ readonly type: BackendType
92
+ readonly chains: string[]
93
+
94
+ private config: Required<Omit<MockBackendConfig, 'name' | 'type' | 'chains' | 'capabilities' | 'availabilityResult' | 'executeResult'>>
95
+ private capabilities: BackendCapabilities
96
+ private availabilityResult: AvailabilityResult
97
+ private executeResult: TransactionResult
98
+
99
+ /** Track number of execute calls */
100
+ public executeCalls: TransferParams[] = []
101
+
102
+ /** Track number of checkAvailability calls */
103
+ public availabilityCalls: BackendParams[] = []
104
+
105
+ constructor(config: MockBackendConfig = {}) {
106
+ this.name = config.name ?? 'mock'
107
+ this.type = config.type ?? 'transaction'
108
+ this.chains = config.chains ?? ['solana', 'ethereum']
109
+
110
+ this.config = {
111
+ shouldFail: config.shouldFail ?? false,
112
+ failureMessage: config.failureMessage ?? 'Mock backend failure',
113
+ latencyMs: config.latencyMs ?? 0,
114
+ estimatedCost: config.estimatedCost ?? 5000n,
115
+ }
116
+
117
+ this.capabilities = {
118
+ ...DEFAULT_CAPABILITIES,
119
+ ...config.capabilities,
120
+ }
121
+
122
+ this.availabilityResult = {
123
+ available: true,
124
+ estimatedCost: this.config.estimatedCost,
125
+ estimatedTime: this.config.latencyMs || 1000,
126
+ ...config.availabilityResult,
127
+ }
128
+
129
+ this.executeResult = {
130
+ success: true,
131
+ signature: `mock-sig-${Date.now()}`,
132
+ backend: this.name,
133
+ ...config.executeResult,
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Check if backend is available for given parameters
139
+ */
140
+ async checkAvailability(params: BackendParams): Promise<AvailabilityResult> {
141
+ this.availabilityCalls.push(params)
142
+
143
+ if (this.config.latencyMs > 0) {
144
+ await this.delay(this.config.latencyMs)
145
+ }
146
+
147
+ // Check if chain is supported
148
+ if ('chain' in params && !this.chains.includes(params.chain)) {
149
+ return {
150
+ available: false,
151
+ reason: `Chain ${params.chain} not supported by ${this.name}`,
152
+ }
153
+ }
154
+
155
+ return { ...this.availabilityResult }
156
+ }
157
+
158
+ /**
159
+ * Get backend capabilities
160
+ */
161
+ getCapabilities(): BackendCapabilities {
162
+ return { ...this.capabilities }
163
+ }
164
+
165
+ /**
166
+ * Execute a privacy-preserving transfer
167
+ */
168
+ async execute(params: TransferParams): Promise<TransactionResult> {
169
+ this.executeCalls.push(params)
170
+
171
+ if (this.config.latencyMs > 0) {
172
+ await this.delay(this.config.latencyMs)
173
+ }
174
+
175
+ if (this.config.shouldFail) {
176
+ return {
177
+ success: false,
178
+ error: this.config.failureMessage,
179
+ backend: this.name,
180
+ }
181
+ }
182
+
183
+ return {
184
+ ...this.executeResult,
185
+ signature: `mock-sig-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Estimate cost for an operation
191
+ */
192
+ async estimateCost(_params: BackendParams): Promise<bigint> {
193
+ if (this.config.latencyMs > 0) {
194
+ await this.delay(this.config.latencyMs)
195
+ }
196
+
197
+ return this.config.estimatedCost
198
+ }
199
+
200
+ /**
201
+ * Reset mock state (call counts, etc.)
202
+ */
203
+ reset(): void {
204
+ this.executeCalls = []
205
+ this.availabilityCalls = []
206
+ }
207
+
208
+ /**
209
+ * Configure mock to fail on next execute
210
+ */
211
+ setFailure(shouldFail: boolean, message?: string): void {
212
+ this.config.shouldFail = shouldFail
213
+ if (message) {
214
+ this.config.failureMessage = message
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Update availability result
220
+ */
221
+ setAvailability(available: boolean, reason?: string): void {
222
+ this.availabilityResult = {
223
+ ...this.availabilityResult,
224
+ available,
225
+ reason,
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Helper to simulate latency
231
+ */
232
+ private delay(ms: number): Promise<void> {
233
+ return new Promise(resolve => setTimeout(resolve, ms))
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Create a mock backend factory for parameterized tests
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * const createMock = createMockFactory({ latencyMs: 50 })
243
+ *
244
+ * const fast = createMock('fast-backend')
245
+ * const slow = createMock('slow-backend', { latencyMs: 500 })
246
+ * ```
247
+ */
248
+ export function createMockFactory(
249
+ defaultConfig: MockBackendConfig = {}
250
+ ): (name: string, overrides?: MockBackendConfig) => MockBackend {
251
+ return (name: string, overrides: MockBackendConfig = {}) => {
252
+ return new MockBackend({
253
+ ...defaultConfig,
254
+ ...overrides,
255
+ name,
256
+ })
257
+ }
258
+ }