@sip-protocol/sdk 0.7.2 → 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 (262) 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 +48874 -18336
  7. package/dist/browser.mjs +674 -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-YWGJ77A2.mjs +33806 -0
  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-DXh2IGkz.d.ts +24681 -0
  24. package/dist/index-DeE1ZzA4.d.mts +24681 -0
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48676 -17318
  28. package/dist/index.mjs +583 -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 +276 -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 +201 -0
  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 +402 -0
  98. package/src/chains/solana/providers/index.ts +85 -0
  99. package/src/chains/solana/providers/interface.ts +221 -0
  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 +790 -0
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +170 -73
  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 +77 -7
  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 +37 -0
  116. package/src/compliance/range-sas.ts +956 -0
  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 +785 -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 +336 -0
  143. package/src/privacy-backends/interface.ts +906 -0
  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-types.ts +278 -0
  148. package/src/privacy-backends/privacycash.ts +456 -0
  149. package/src/privacy-backends/private-swap.ts +570 -0
  150. package/src/privacy-backends/rate-limiter.ts +683 -0
  151. package/src/privacy-backends/registry.ts +690 -0
  152. package/src/privacy-backends/router.ts +626 -0
  153. package/src/privacy-backends/shadowwire.ts +449 -0
  154. package/src/privacy-backends/sip-native.ts +256 -0
  155. package/src/privacy-logger.ts +191 -0
  156. package/src/production-safety.ts +373 -0
  157. package/src/proofs/aggregator.ts +1029 -0
  158. package/src/proofs/browser-composer.ts +1150 -0
  159. package/src/proofs/browser.ts +113 -25
  160. package/src/proofs/cache/index.ts +127 -0
  161. package/src/proofs/cache/interface.ts +545 -0
  162. package/src/proofs/cache/key-generator.ts +188 -0
  163. package/src/proofs/cache/lru-cache.ts +481 -0
  164. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  165. package/src/proofs/cache/persistent-cache.ts +788 -0
  166. package/src/proofs/compliance-proof.ts +872 -0
  167. package/src/proofs/composer/base.ts +923 -0
  168. package/src/proofs/composer/index.ts +25 -0
  169. package/src/proofs/composer/interface.ts +518 -0
  170. package/src/proofs/composer/types.ts +383 -0
  171. package/src/proofs/converters/halo2.ts +452 -0
  172. package/src/proofs/converters/index.ts +208 -0
  173. package/src/proofs/converters/interface.ts +363 -0
  174. package/src/proofs/converters/kimchi.ts +462 -0
  175. package/src/proofs/converters/noir.ts +451 -0
  176. package/src/proofs/fallback.ts +888 -0
  177. package/src/proofs/halo2.ts +42 -0
  178. package/src/proofs/index.ts +471 -0
  179. package/src/proofs/interface.ts +13 -0
  180. package/src/proofs/kimchi.ts +42 -0
  181. package/src/proofs/lazy.ts +1004 -0
  182. package/src/proofs/mock.ts +25 -1
  183. package/src/proofs/noir.ts +111 -30
  184. package/src/proofs/orchestrator.ts +960 -0
  185. package/src/proofs/parallel/concurrency.ts +297 -0
  186. package/src/proofs/parallel/dependency-graph.ts +602 -0
  187. package/src/proofs/parallel/executor.ts +420 -0
  188. package/src/proofs/parallel/index.ts +131 -0
  189. package/src/proofs/parallel/interface.ts +685 -0
  190. package/src/proofs/parallel/worker-pool.ts +644 -0
  191. package/src/proofs/providers/halo2.ts +560 -0
  192. package/src/proofs/providers/index.ts +34 -0
  193. package/src/proofs/providers/kimchi.ts +641 -0
  194. package/src/proofs/validator.ts +881 -0
  195. package/src/proofs/verifier.ts +867 -0
  196. package/src/quantum/index.ts +112 -0
  197. package/src/quantum/winternitz-vault.ts +639 -0
  198. package/src/quantum/wots.ts +611 -0
  199. package/src/settlement/backends/direct-chain.ts +1 -0
  200. package/src/settlement/index.ts +9 -0
  201. package/src/settlement/router.ts +732 -46
  202. package/src/solana/index.ts +72 -0
  203. package/src/solana/jito-relayer.ts +687 -0
  204. package/src/solana/noir-verifier-types.ts +430 -0
  205. package/src/solana/noir-verifier.ts +816 -0
  206. package/src/stealth/address-derivation.ts +193 -0
  207. package/src/stealth/ed25519.ts +431 -0
  208. package/src/stealth/index.ts +233 -0
  209. package/src/stealth/meta-address.ts +221 -0
  210. package/src/stealth/secp256k1.ts +368 -0
  211. package/src/stealth/utils.ts +194 -0
  212. package/src/stealth.ts +50 -1504
  213. package/src/surveillance/algorithms/address-reuse.ts +143 -0
  214. package/src/surveillance/algorithms/cluster.ts +247 -0
  215. package/src/surveillance/algorithms/exchange.ts +295 -0
  216. package/src/surveillance/algorithms/temporal.ts +337 -0
  217. package/src/surveillance/analyzer.ts +442 -0
  218. package/src/surveillance/index.ts +64 -0
  219. package/src/surveillance/scoring.ts +372 -0
  220. package/src/surveillance/types.ts +264 -0
  221. package/src/sync/index.ts +106 -0
  222. package/src/sync/manager.ts +504 -0
  223. package/src/sync/mock-provider.ts +318 -0
  224. package/src/sync/oblivious.ts +625 -0
  225. package/src/tokens/index.ts +15 -0
  226. package/src/tokens/registry.ts +301 -0
  227. package/src/utils/deprecation.ts +94 -0
  228. package/src/utils/index.ts +9 -0
  229. package/src/wallet/ethereum/index.ts +68 -0
  230. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  231. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  232. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  233. package/src/wallet/ethereum/types.ts +3 -1
  234. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  235. package/src/wallet/hardware/index.ts +10 -0
  236. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  237. package/src/wallet/index.ts +71 -0
  238. package/src/wallet/near/adapter.ts +626 -0
  239. package/src/wallet/near/index.ts +86 -0
  240. package/src/wallet/near/meteor-wallet.ts +1153 -0
  241. package/src/wallet/near/my-near-wallet.ts +790 -0
  242. package/src/wallet/near/wallet-selector.ts +702 -0
  243. package/src/wallet/solana/adapter.ts +6 -4
  244. package/src/wallet/solana/index.ts +13 -0
  245. package/src/wallet/solana/privacy-adapter.ts +567 -0
  246. package/src/wallet/sui/types.ts +6 -4
  247. package/src/zcash/rpc-client.ts +13 -6
  248. package/dist/chunk-3INS3PR5.mjs +0 -884
  249. package/dist/chunk-3OVABDRH.mjs +0 -17096
  250. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  251. package/dist/chunk-E6SZWREQ.mjs +0 -57
  252. package/dist/chunk-G33LB27A.mjs +0 -16166
  253. package/dist/chunk-HGU6HZRC.mjs +0 -231
  254. package/dist/chunk-L2K34JCU.mjs +0 -1496
  255. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  256. package/dist/constants-VOI7BSLK.mjs +0 -27
  257. package/dist/index-BYZbDjal.d.ts +0 -11390
  258. package/dist/index-CHB3KuOB.d.mts +0 -11859
  259. package/dist/index-CzWPI6Le.d.ts +0 -11859
  260. package/dist/index-xbWjohNq.d.mts +0 -11390
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-Q4NAVBTS.mjs +0 -46
@@ -0,0 +1,560 @@
1
+ /**
2
+ * Solana Chain-Specific Optimizations
3
+ *
4
+ * Provides optimized configurations and utilities for Solana transactions:
5
+ * - Compute unit optimization (CU budgeting)
6
+ * - Priority fee strategies
7
+ * - Address Lookup Tables (ALT) for tx size reduction
8
+ * - Parallel batching strategies
9
+ * - Account rent optimization
10
+ *
11
+ * @module chains/solana/optimizations
12
+ */
13
+
14
+ // ─── Compute Unit Constants ───────────────────────────────────────────────────
15
+
16
+ /**
17
+ * Default compute units for a transaction
18
+ */
19
+ export const DEFAULT_COMPUTE_UNITS = 200_000
20
+
21
+ /**
22
+ * Maximum compute units allowed per transaction
23
+ */
24
+ export const MAX_COMPUTE_UNITS = 1_400_000
25
+
26
+ /**
27
+ * Default priority fee in microlamports per compute unit
28
+ */
29
+ export const DEFAULT_PRIORITY_FEE = 1000
30
+
31
+ // ─── Types ────────────────────────────────────────────────────────────────────
32
+
33
+ /**
34
+ * Compute unit budget configuration
35
+ */
36
+ export interface ComputeBudgetConfig {
37
+ /** Compute units to request */
38
+ units: number
39
+ /** Priority fee in microlamports per CU */
40
+ microLamportsPerCU: number
41
+ /** Total priority fee in lamports */
42
+ totalPriorityFeeLamports: number
43
+ }
44
+
45
+ /**
46
+ * Transaction optimization profile
47
+ */
48
+ export type OptimizationProfile =
49
+ | 'economy' // Lowest fees, may be slower
50
+ | 'standard' // Balanced cost/speed
51
+ | 'fast' // Higher fees, faster confirmation
52
+ | 'urgent' // Maximum priority
53
+
54
+ /**
55
+ * Network congestion level
56
+ */
57
+ export type CongestionLevel = 'low' | 'medium' | 'high' | 'extreme'
58
+
59
+ /**
60
+ * Transaction complexity estimate
61
+ */
62
+ export interface TransactionComplexity {
63
+ /** Estimated compute units needed */
64
+ estimatedCU: number
65
+ /** Number of accounts involved */
66
+ accountCount: number
67
+ /** Number of instructions */
68
+ instructionCount: number
69
+ /** Whether ALT is recommended */
70
+ altRecommended: boolean
71
+ /** Estimated transaction size in bytes */
72
+ estimatedSizeBytes: number
73
+ }
74
+
75
+ /**
76
+ * Optimization result with recommendations
77
+ */
78
+ export interface OptimizationResult {
79
+ /** Computed budget configuration */
80
+ budget: ComputeBudgetConfig
81
+ /** Network congestion assessment */
82
+ congestion: CongestionLevel
83
+ /** Recommendations for the transaction */
84
+ recommendations: string[]
85
+ /** Whether to use versioned transactions */
86
+ useVersionedTx: boolean
87
+ /** Whether to use Address Lookup Tables */
88
+ useALT: boolean
89
+ }
90
+
91
+ /**
92
+ * Priority fee percentiles from recent blocks
93
+ */
94
+ export interface PriorityFeePercentiles {
95
+ p25: number
96
+ p50: number
97
+ p75: number
98
+ p90: number
99
+ p99: number
100
+ timestamp: number
101
+ }
102
+
103
+ // ─── Constants ────────────────────────────────────────────────────────────────
104
+
105
+ /**
106
+ * Base compute units for common operations
107
+ */
108
+ export const OPERATION_CU_COSTS = {
109
+ /** Base transaction overhead */
110
+ base: 5000,
111
+ /** SOL transfer */
112
+ solTransfer: 3000,
113
+ /** SPL token transfer (existing ATA) */
114
+ splTransfer: 10000,
115
+ /** SPL token transfer (new ATA creation) */
116
+ splTransferWithATA: 35000,
117
+ /** Memo program write */
118
+ memo: 500,
119
+ /** Compute budget instruction */
120
+ computeBudget: 150,
121
+ /** System program create account */
122
+ createAccount: 5000,
123
+ /** Ephemeral key derivation */
124
+ keyDerivation: 2000,
125
+ /** Signature verification */
126
+ signatureVerify: 1000,
127
+ } as const
128
+
129
+ /**
130
+ * Priority fee multipliers by profile
131
+ */
132
+ const PROFILE_MULTIPLIERS: Record<OptimizationProfile, number> = {
133
+ economy: 0.5,
134
+ standard: 1.0,
135
+ fast: 2.0,
136
+ urgent: 5.0,
137
+ }
138
+
139
+ /**
140
+ * Congestion thresholds (microlamports per CU)
141
+ */
142
+ const CONGESTION_THRESHOLDS = {
143
+ low: 1000, // < 1000 microlamports/CU
144
+ medium: 5000, // 1000-5000
145
+ high: 20000, // 5000-20000
146
+ // > 20000 = extreme
147
+ }
148
+
149
+ /**
150
+ * Max accounts before ALT is recommended
151
+ */
152
+ const ALT_THRESHOLD_ACCOUNTS = 15
153
+
154
+ /**
155
+ * Max transaction size before ALT is required (bytes)
156
+ */
157
+ const MAX_TX_SIZE_WITHOUT_ALT = 1232
158
+
159
+ // ─── Compute Budget Functions ─────────────────────────────────────────────────
160
+
161
+ /**
162
+ * Calculate optimal compute budget based on transaction complexity
163
+ *
164
+ * @param complexity - Transaction complexity estimate
165
+ * @param profile - Optimization profile
166
+ * @param currentFees - Current priority fee percentiles (optional)
167
+ * @returns Compute budget configuration
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const budget = calculateComputeBudget(
172
+ * { estimatedCU: 50000, accountCount: 5, instructionCount: 3 },
173
+ * 'standard'
174
+ * )
175
+ * console.log(budget.units) // 60000 (with buffer)
176
+ * console.log(budget.microLamportsPerCU) // 1000
177
+ * ```
178
+ */
179
+ export function calculateComputeBudget(
180
+ complexity: Pick<TransactionComplexity, 'estimatedCU'>,
181
+ profile: OptimizationProfile = 'standard',
182
+ currentFees?: PriorityFeePercentiles
183
+ ): ComputeBudgetConfig {
184
+ // Add 20% buffer to estimated CU
185
+ const bufferMultiplier = 1.2
186
+ const requestedUnits = Math.min(
187
+ Math.ceil(complexity.estimatedCU * bufferMultiplier),
188
+ MAX_COMPUTE_UNITS
189
+ )
190
+
191
+ // Base priority fee selection based on percentile
192
+ let baseFee: number
193
+ if (currentFees) {
194
+ // Use percentile based on profile
195
+ switch (profile) {
196
+ case 'economy':
197
+ baseFee = currentFees.p25
198
+ break
199
+ case 'standard':
200
+ baseFee = currentFees.p50
201
+ break
202
+ case 'fast':
203
+ baseFee = currentFees.p75
204
+ break
205
+ case 'urgent':
206
+ baseFee = currentFees.p99
207
+ break
208
+ }
209
+ } else {
210
+ // Use default with multiplier
211
+ baseFee = DEFAULT_PRIORITY_FEE * PROFILE_MULTIPLIERS[profile]
212
+ }
213
+
214
+ // Ensure minimum fee
215
+ const microLamportsPerCU = Math.max(baseFee, 100)
216
+
217
+ // Calculate total fee
218
+ const totalPriorityFeeLamports = Math.ceil(
219
+ (requestedUnits * microLamportsPerCU) / 1_000_000
220
+ )
221
+
222
+ return {
223
+ units: requestedUnits,
224
+ microLamportsPerCU,
225
+ totalPriorityFeeLamports,
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Estimate compute units for a privacy transaction
231
+ *
232
+ * @param options - Transaction options
233
+ * @returns Transaction complexity estimate
234
+ */
235
+ export function estimatePrivacyTxComplexity(options: {
236
+ /** Number of transfers in batch */
237
+ transferCount: number
238
+ /** Whether creating new ATAs */
239
+ createsATAs: boolean
240
+ /** Number of new ATAs to create */
241
+ newATACount?: number
242
+ /** Whether includes memo */
243
+ includesMemo: boolean
244
+ /** Custom instruction count */
245
+ customInstructionCount?: number
246
+ }): TransactionComplexity {
247
+ let estimatedCU = OPERATION_CU_COSTS.base
248
+
249
+ // Add compute budget instruction cost
250
+ estimatedCU += OPERATION_CU_COSTS.computeBudget * 2 // SetUnits + SetPriorityFee
251
+
252
+ // Add transfer costs
253
+ if (options.createsATAs) {
254
+ const ataCount = options.newATACount ?? options.transferCount
255
+ estimatedCU += OPERATION_CU_COSTS.splTransferWithATA * ataCount
256
+ estimatedCU +=
257
+ OPERATION_CU_COSTS.splTransfer * (options.transferCount - ataCount)
258
+ } else {
259
+ estimatedCU += OPERATION_CU_COSTS.splTransfer * options.transferCount
260
+ }
261
+
262
+ // Add memo cost
263
+ if (options.includesMemo) {
264
+ estimatedCU += OPERATION_CU_COSTS.memo
265
+ }
266
+
267
+ // Add ephemeral key derivation
268
+ estimatedCU += OPERATION_CU_COSTS.keyDerivation
269
+
270
+ // Estimate account count
271
+ // Base: fee payer (1) + token program (1) + system program (1)
272
+ // Per transfer: sender ATA (1) + receiver ATA (1) + mint (1)
273
+ const baseAccounts = 3
274
+ const accountsPerTransfer = options.createsATAs ? 5 : 3 // ATA program + rent sysvar for creation
275
+ const accountCount = baseAccounts + accountsPerTransfer * options.transferCount
276
+
277
+ // Instruction count
278
+ const instructionCount =
279
+ 2 + // Compute budget
280
+ options.transferCount + // Transfers
281
+ (options.includesMemo ? 1 : 0) +
282
+ (options.customInstructionCount ?? 0)
283
+
284
+ // Estimate size (rough approximation)
285
+ const baseSize = 100 // Signatures, header
286
+ const perAccountSize = 32 // Pubkey
287
+ const perInstructionSize = 50 // Average instruction data
288
+ const estimatedSizeBytes =
289
+ baseSize + accountCount * perAccountSize + instructionCount * perInstructionSize
290
+
291
+ return {
292
+ estimatedCU,
293
+ accountCount,
294
+ instructionCount,
295
+ altRecommended:
296
+ accountCount > ALT_THRESHOLD_ACCOUNTS ||
297
+ estimatedSizeBytes > MAX_TX_SIZE_WITHOUT_ALT,
298
+ estimatedSizeBytes,
299
+ }
300
+ }
301
+
302
+ // ─── Congestion Assessment ────────────────────────────────────────────────────
303
+
304
+ /**
305
+ * Assess network congestion level from priority fees
306
+ *
307
+ * @param medianFee - Median priority fee (microlamports per CU)
308
+ * @returns Congestion level
309
+ */
310
+ export function assessCongestion(medianFee: number): CongestionLevel {
311
+ if (medianFee < CONGESTION_THRESHOLDS.low) return 'low'
312
+ if (medianFee < CONGESTION_THRESHOLDS.medium) return 'medium'
313
+ if (medianFee < CONGESTION_THRESHOLDS.high) return 'high'
314
+ return 'extreme'
315
+ }
316
+
317
+ /**
318
+ * Get recommended profile based on congestion
319
+ *
320
+ * @param congestion - Current congestion level
321
+ * @param userPreference - User's preferred profile
322
+ * @returns Recommended profile (may differ from preference in extreme congestion)
323
+ */
324
+ export function getRecommendedProfile(
325
+ congestion: CongestionLevel,
326
+ userPreference: OptimizationProfile = 'standard'
327
+ ): OptimizationProfile {
328
+ // In extreme congestion, don't let users underpay
329
+ if (congestion === 'extreme' && userPreference === 'economy') {
330
+ return 'standard'
331
+ }
332
+
333
+ // In low congestion, economy is fine even for fast preference
334
+ if (congestion === 'low' && userPreference === 'fast') {
335
+ return 'standard'
336
+ }
337
+
338
+ return userPreference
339
+ }
340
+
341
+ // ─── Full Optimization ────────────────────────────────────────────────────────
342
+
343
+ /**
344
+ * Get full optimization result for a transaction
345
+ *
346
+ * @param complexity - Transaction complexity
347
+ * @param profile - Optimization profile
348
+ * @param currentFees - Current priority fee percentiles
349
+ * @returns Full optimization result with recommendations
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * const complexity = estimatePrivacyTxComplexity({
354
+ * transferCount: 1,
355
+ * createsATAs: true,
356
+ * includesMemo: true
357
+ * })
358
+ *
359
+ * const result = optimizeTransaction(complexity, 'standard', feePercentiles)
360
+ *
361
+ * // Apply to transaction builder
362
+ * builder.setComputeUnits(result.budget.units)
363
+ * builder.setPriorityFee(result.budget.microLamportsPerCU)
364
+ * ```
365
+ */
366
+ export function optimizeTransaction(
367
+ complexity: TransactionComplexity,
368
+ profile: OptimizationProfile = 'standard',
369
+ currentFees?: PriorityFeePercentiles
370
+ ): OptimizationResult {
371
+ const congestion = currentFees
372
+ ? assessCongestion(currentFees.p50)
373
+ : 'medium'
374
+
375
+ const adjustedProfile = getRecommendedProfile(congestion, profile)
376
+ const budget = calculateComputeBudget(complexity, adjustedProfile, currentFees)
377
+
378
+ const recommendations: string[] = []
379
+
380
+ // ALT recommendations
381
+ if (complexity.altRecommended) {
382
+ recommendations.push(
383
+ 'Use Address Lookup Tables (ALT) to reduce transaction size'
384
+ )
385
+ }
386
+
387
+ // Congestion-based recommendations
388
+ if (congestion === 'extreme') {
389
+ recommendations.push(
390
+ 'Network is extremely congested - consider waiting or using urgent priority'
391
+ )
392
+ } else if (congestion === 'high') {
393
+ recommendations.push(
394
+ 'High network congestion - fast or urgent profile recommended'
395
+ )
396
+ }
397
+
398
+ // CU recommendations
399
+ if (complexity.estimatedCU > 200000) {
400
+ recommendations.push(
401
+ 'High compute usage - ensure sufficient CU budget to avoid failures'
402
+ )
403
+ }
404
+
405
+ // Versioned tx recommendation
406
+ const useVersionedTx = complexity.accountCount > 10 || complexity.altRecommended
407
+
408
+ if (useVersionedTx) {
409
+ recommendations.push('Use versioned transactions for better compatibility')
410
+ }
411
+
412
+ return {
413
+ budget,
414
+ congestion,
415
+ recommendations,
416
+ useVersionedTx,
417
+ useALT: complexity.altRecommended,
418
+ }
419
+ }
420
+
421
+ // ─── Batch Optimization ───────────────────────────────────────────────────────
422
+
423
+ /**
424
+ * Split transfers into optimal batches
425
+ *
426
+ * Solana has limits on transaction size and compute units.
427
+ * This function splits a large batch into optimal sub-batches.
428
+ *
429
+ * @param transferCount - Total number of transfers
430
+ * @param options - Batch options
431
+ * @returns Array of batch sizes
432
+ *
433
+ * @example
434
+ * ```typescript
435
+ * const batches = calculateOptimalBatches(10, { maxCUPerTx: 400000 })
436
+ * // Returns [3, 3, 3, 1] - 4 transactions
437
+ * ```
438
+ */
439
+ export function calculateOptimalBatches(
440
+ transferCount: number,
441
+ options: {
442
+ /** Max compute units per transaction */
443
+ maxCUPerTx?: number
444
+ /** Max accounts per transaction */
445
+ maxAccountsPerTx?: number
446
+ /** Whether transfers create ATAs */
447
+ createsATAs?: boolean
448
+ } = {}
449
+ ): number[] {
450
+ const { maxCUPerTx = 400000, maxAccountsPerTx = 30, createsATAs = false } = options
451
+
452
+ // Calculate max transfers per batch
453
+ const cuPerTransfer = createsATAs
454
+ ? OPERATION_CU_COSTS.splTransferWithATA
455
+ : OPERATION_CU_COSTS.splTransfer
456
+ const baseCU = OPERATION_CU_COSTS.base + OPERATION_CU_COSTS.computeBudget * 2
457
+ const maxTransfersByCU = Math.floor((maxCUPerTx - baseCU) / cuPerTransfer)
458
+
459
+ const accountsPerTransfer = createsATAs ? 5 : 3
460
+ const baseAccounts = 3
461
+ const maxTransfersByAccounts = Math.floor(
462
+ (maxAccountsPerTx - baseAccounts) / accountsPerTransfer
463
+ )
464
+
465
+ const maxTransfersPerBatch = Math.min(maxTransfersByCU, maxTransfersByAccounts)
466
+
467
+ // Split into batches
468
+ const batches: number[] = []
469
+ let remaining = transferCount
470
+
471
+ while (remaining > 0) {
472
+ const batchSize = Math.min(remaining, maxTransfersPerBatch)
473
+ batches.push(batchSize)
474
+ remaining -= batchSize
475
+ }
476
+
477
+ return batches
478
+ }
479
+
480
+ // ─── Rent Optimization ────────────────────────────────────────────────────────
481
+
482
+ /**
483
+ * Calculate minimum rent for account data
484
+ *
485
+ * @param dataSize - Account data size in bytes
486
+ * @returns Minimum rent in lamports
487
+ */
488
+ export function calculateMinimumRent(dataSize: number): number {
489
+ // Rent is based on data size plus 128 bytes for account header
490
+ const accountSize = dataSize + 128
491
+ // Rent-exempt minimum is ~6.96 lamports per byte for 2 years
492
+ const rentPerByte = 6.96
493
+ return Math.ceil(accountSize * rentPerByte)
494
+ }
495
+
496
+ /**
497
+ * Token account rent (165 bytes data)
498
+ */
499
+ export const TOKEN_ACCOUNT_RENT = calculateMinimumRent(165) // ~2039 lamports
500
+
501
+ /**
502
+ * Mint account rent (82 bytes data)
503
+ */
504
+ export const MINT_ACCOUNT_RENT = calculateMinimumRent(82) // ~1461 lamports
505
+
506
+ // ─── Utility Functions ────────────────────────────────────────────────────────
507
+
508
+ /**
509
+ * Convert lamports to SOL
510
+ */
511
+ export function lamportsToSol(lamports: number): number {
512
+ return lamports / 1_000_000_000
513
+ }
514
+
515
+ /**
516
+ * Convert SOL to lamports
517
+ */
518
+ export function solToLamports(sol: number): number {
519
+ return Math.floor(sol * 1_000_000_000)
520
+ }
521
+
522
+ /**
523
+ * Format priority fee for display
524
+ */
525
+ export function formatPriorityFee(microLamportsPerCU: number): string {
526
+ if (microLamportsPerCU < 1000) {
527
+ return `${microLamportsPerCU} µL/CU`
528
+ }
529
+ return `${(microLamportsPerCU / 1000).toFixed(2)} mL/CU`
530
+ }
531
+
532
+ /**
533
+ * Get optimization profile from user-friendly name
534
+ */
535
+ export function parseOptimizationProfile(name: string): OptimizationProfile {
536
+ const normalized = name.toLowerCase().trim()
537
+ switch (normalized) {
538
+ case 'economy':
539
+ case 'eco':
540
+ case 'low':
541
+ case 'slow':
542
+ return 'economy'
543
+ case 'standard':
544
+ case 'normal':
545
+ case 'default':
546
+ case 'medium':
547
+ return 'standard'
548
+ case 'fast':
549
+ case 'high':
550
+ case 'quick':
551
+ return 'fast'
552
+ case 'urgent':
553
+ case 'max':
554
+ case 'turbo':
555
+ case 'instant':
556
+ return 'urgent'
557
+ default:
558
+ return 'standard'
559
+ }
560
+ }