@sip-protocol/sdk 0.7.3 → 0.8.0

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 (263) hide show
  1. package/README.md +267 -0
  2. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  3. package/dist/browser.d.mts +10 -4
  4. package/dist/browser.d.ts +10 -4
  5. package/dist/browser.js +47556 -19603
  6. package/dist/browser.mjs +628 -48
  7. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  8. package/dist/chunk-5D7A3L3W.mjs +717 -0
  9. package/dist/chunk-64AYA5F5.mjs +7834 -0
  10. package/dist/chunk-GMDGB22A.mjs +379 -0
  11. package/dist/chunk-I534WKN7.mjs +328 -0
  12. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  13. package/dist/chunk-PRRZAWJE.mjs +223 -0
  14. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  15. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  16. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  17. package/dist/constants-LHAAUC2T.mjs +51 -0
  18. package/dist/dist-2OGQ7FED.mjs +3957 -0
  19. package/dist/dist-IFHPYLDX.mjs +254 -0
  20. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  21. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  22. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  23. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  24. package/dist/index.d.mts +9 -3
  25. package/dist/index.d.ts +9 -3
  26. package/dist/index.js +48396 -19623
  27. package/dist/index.mjs +537 -19
  28. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  29. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  30. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  31. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  32. package/dist/proofs/halo2.d.mts +151 -0
  33. package/dist/proofs/halo2.d.ts +151 -0
  34. package/dist/proofs/halo2.js +350 -0
  35. package/dist/proofs/halo2.mjs +11 -0
  36. package/dist/proofs/kimchi.d.mts +160 -0
  37. package/dist/proofs/kimchi.d.ts +160 -0
  38. package/dist/proofs/kimchi.js +431 -0
  39. package/dist/proofs/kimchi.mjs +13 -0
  40. package/dist/proofs/noir.d.mts +1 -1
  41. package/dist/proofs/noir.d.ts +1 -1
  42. package/dist/proofs/noir.js +74 -18
  43. package/dist/proofs/noir.mjs +84 -24
  44. package/dist/solana-U3MEGU7W.mjs +280 -0
  45. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  46. package/package.json +44 -11
  47. package/src/adapters/index.ts +41 -0
  48. package/src/adapters/jupiter.ts +571 -0
  49. package/src/adapters/near-intents.ts +135 -0
  50. package/src/advisor/advisor.ts +653 -0
  51. package/src/advisor/index.ts +54 -0
  52. package/src/advisor/tools.ts +303 -0
  53. package/src/advisor/types.ts +164 -0
  54. package/src/chains/ethereum/announcement.ts +536 -0
  55. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  56. package/src/chains/ethereum/commitment.ts +522 -0
  57. package/src/chains/ethereum/constants.ts +462 -0
  58. package/src/chains/ethereum/deployment.ts +596 -0
  59. package/src/chains/ethereum/gas-estimation.ts +538 -0
  60. package/src/chains/ethereum/index.ts +268 -0
  61. package/src/chains/ethereum/optimizations.ts +614 -0
  62. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  63. package/src/chains/ethereum/registry.ts +584 -0
  64. package/src/chains/ethereum/rpc.ts +905 -0
  65. package/src/chains/ethereum/stealth.ts +491 -0
  66. package/src/chains/ethereum/token.ts +790 -0
  67. package/src/chains/ethereum/transfer.ts +637 -0
  68. package/src/chains/ethereum/types.ts +456 -0
  69. package/src/chains/ethereum/viewing-key.ts +455 -0
  70. package/src/chains/near/commitment.ts +608 -0
  71. package/src/chains/near/constants.ts +284 -0
  72. package/src/chains/near/function-call.ts +871 -0
  73. package/src/chains/near/history.ts +654 -0
  74. package/src/chains/near/implicit-account.ts +840 -0
  75. package/src/chains/near/index.ts +393 -0
  76. package/src/chains/near/native-transfer.ts +658 -0
  77. package/src/chains/near/nep141.ts +775 -0
  78. package/src/chains/near/privacy-adapter.ts +889 -0
  79. package/src/chains/near/resolver.ts +971 -0
  80. package/src/chains/near/rpc.ts +1016 -0
  81. package/src/chains/near/stealth.ts +419 -0
  82. package/src/chains/near/types.ts +317 -0
  83. package/src/chains/near/viewing-key.ts +876 -0
  84. package/src/chains/solana/anchor-transfer.ts +386 -0
  85. package/src/chains/solana/commitment.ts +577 -0
  86. package/src/chains/solana/constants.ts +126 -12
  87. package/src/chains/solana/ephemeral-keys.ts +543 -0
  88. package/src/chains/solana/index.ts +252 -1
  89. package/src/chains/solana/key-derivation.ts +418 -0
  90. package/src/chains/solana/kit-compat.ts +334 -0
  91. package/src/chains/solana/optimizations.ts +560 -0
  92. package/src/chains/solana/privacy-adapter.ts +605 -0
  93. package/src/chains/solana/providers/generic.ts +47 -6
  94. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  95. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  96. package/src/chains/solana/providers/helius.ts +186 -33
  97. package/src/chains/solana/providers/index.ts +31 -0
  98. package/src/chains/solana/providers/interface.ts +61 -18
  99. package/src/chains/solana/providers/quicknode.ts +409 -0
  100. package/src/chains/solana/providers/triton.ts +426 -0
  101. package/src/chains/solana/providers/webhook.ts +338 -67
  102. package/src/chains/solana/rpc-client.ts +1150 -0
  103. package/src/chains/solana/scan.ts +83 -66
  104. package/src/chains/solana/sol-transfer.ts +732 -0
  105. package/src/chains/solana/spl-transfer.ts +886 -0
  106. package/src/chains/solana/stealth-scanner.ts +703 -0
  107. package/src/chains/solana/sunspot-verifier.ts +453 -0
  108. package/src/chains/solana/transaction-builder.ts +755 -0
  109. package/src/chains/solana/transfer.ts +74 -5
  110. package/src/chains/solana/types.ts +57 -6
  111. package/src/chains/solana/utils.ts +110 -0
  112. package/src/chains/solana/viewing-key.ts +807 -0
  113. package/src/compliance/fireblocks.ts +921 -0
  114. package/src/compliance/index.ts +23 -0
  115. package/src/compliance/range-sas.ts +398 -33
  116. package/src/config/endpoints.ts +100 -0
  117. package/src/crypto.ts +11 -8
  118. package/src/errors.ts +82 -0
  119. package/src/evm/erc4337-relayer.ts +830 -0
  120. package/src/evm/index.ts +47 -0
  121. package/src/fees/calculator.ts +396 -0
  122. package/src/fees/index.ts +87 -0
  123. package/src/fees/near-contract.ts +429 -0
  124. package/src/fees/types.ts +268 -0
  125. package/src/index.ts +686 -1
  126. package/src/intent.ts +6 -3
  127. package/src/logger.ts +324 -0
  128. package/src/network/index.ts +80 -0
  129. package/src/network/proxy.ts +691 -0
  130. package/src/optimizations/index.ts +541 -0
  131. package/src/oracle/types.ts +1 -0
  132. package/src/privacy-backends/arcium-types.ts +727 -0
  133. package/src/privacy-backends/arcium.ts +719 -0
  134. package/src/privacy-backends/combined-privacy.ts +866 -0
  135. package/src/privacy-backends/cspl-token.ts +595 -0
  136. package/src/privacy-backends/cspl-types.ts +512 -0
  137. package/src/privacy-backends/cspl.ts +907 -0
  138. package/src/privacy-backends/health.ts +488 -0
  139. package/src/privacy-backends/inco-types.ts +323 -0
  140. package/src/privacy-backends/inco.ts +616 -0
  141. package/src/privacy-backends/index.ts +254 -4
  142. package/src/privacy-backends/interface.ts +649 -6
  143. package/src/privacy-backends/lru-cache.ts +343 -0
  144. package/src/privacy-backends/magicblock.ts +458 -0
  145. package/src/privacy-backends/mock.ts +258 -0
  146. package/src/privacy-backends/privacycash.ts +13 -17
  147. package/src/privacy-backends/private-swap.ts +570 -0
  148. package/src/privacy-backends/rate-limiter.ts +683 -0
  149. package/src/privacy-backends/registry.ts +414 -2
  150. package/src/privacy-backends/router.ts +283 -3
  151. package/src/privacy-backends/shadowwire.ts +449 -0
  152. package/src/privacy-backends/sip-native.ts +3 -0
  153. package/src/privacy-logger.ts +191 -0
  154. package/src/production-safety.ts +373 -0
  155. package/src/proofs/aggregator.ts +1029 -0
  156. package/src/proofs/browser-composer.ts +1150 -0
  157. package/src/proofs/browser.ts +113 -25
  158. package/src/proofs/cache/index.ts +127 -0
  159. package/src/proofs/cache/interface.ts +545 -0
  160. package/src/proofs/cache/key-generator.ts +188 -0
  161. package/src/proofs/cache/lru-cache.ts +481 -0
  162. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  163. package/src/proofs/cache/persistent-cache.ts +788 -0
  164. package/src/proofs/compliance-proof.ts +872 -0
  165. package/src/proofs/composer/base.ts +923 -0
  166. package/src/proofs/composer/index.ts +25 -0
  167. package/src/proofs/composer/interface.ts +518 -0
  168. package/src/proofs/composer/types.ts +383 -0
  169. package/src/proofs/converters/halo2.ts +452 -0
  170. package/src/proofs/converters/index.ts +208 -0
  171. package/src/proofs/converters/interface.ts +363 -0
  172. package/src/proofs/converters/kimchi.ts +462 -0
  173. package/src/proofs/converters/noir.ts +451 -0
  174. package/src/proofs/fallback.ts +888 -0
  175. package/src/proofs/halo2.ts +42 -0
  176. package/src/proofs/index.ts +471 -0
  177. package/src/proofs/interface.ts +13 -0
  178. package/src/proofs/kimchi.ts +42 -0
  179. package/src/proofs/lazy.ts +1004 -0
  180. package/src/proofs/mock.ts +25 -1
  181. package/src/proofs/noir.ts +110 -29
  182. package/src/proofs/orchestrator.ts +960 -0
  183. package/src/proofs/parallel/concurrency.ts +297 -0
  184. package/src/proofs/parallel/dependency-graph.ts +602 -0
  185. package/src/proofs/parallel/executor.ts +420 -0
  186. package/src/proofs/parallel/index.ts +131 -0
  187. package/src/proofs/parallel/interface.ts +685 -0
  188. package/src/proofs/parallel/worker-pool.ts +644 -0
  189. package/src/proofs/providers/halo2.ts +560 -0
  190. package/src/proofs/providers/index.ts +34 -0
  191. package/src/proofs/providers/kimchi.ts +641 -0
  192. package/src/proofs/validator.ts +881 -0
  193. package/src/proofs/verifier.ts +867 -0
  194. package/src/quantum/index.ts +112 -0
  195. package/src/quantum/winternitz-vault.ts +639 -0
  196. package/src/quantum/wots.ts +611 -0
  197. package/src/settlement/backends/direct-chain.ts +1 -0
  198. package/src/settlement/index.ts +9 -0
  199. package/src/settlement/router.ts +732 -46
  200. package/src/solana/index.ts +72 -0
  201. package/src/solana/jito-relayer.ts +687 -0
  202. package/src/solana/noir-verifier-types.ts +430 -0
  203. package/src/solana/noir-verifier.ts +816 -0
  204. package/src/stealth/address-derivation.ts +193 -0
  205. package/src/stealth/ed25519.ts +431 -0
  206. package/src/stealth/index.ts +233 -0
  207. package/src/stealth/meta-address.ts +221 -0
  208. package/src/stealth/secp256k1.ts +368 -0
  209. package/src/stealth/utils.ts +194 -0
  210. package/src/stealth.ts +50 -1504
  211. package/src/sync/index.ts +106 -0
  212. package/src/sync/manager.ts +504 -0
  213. package/src/sync/mock-provider.ts +318 -0
  214. package/src/sync/oblivious.ts +625 -0
  215. package/src/tokens/index.ts +15 -0
  216. package/src/tokens/registry.ts +301 -0
  217. package/src/utils/deprecation.ts +94 -0
  218. package/src/utils/index.ts +9 -0
  219. package/src/wallet/ethereum/index.ts +68 -0
  220. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  221. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  222. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  223. package/src/wallet/ethereum/types.ts +3 -1
  224. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  225. package/src/wallet/hardware/index.ts +10 -0
  226. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  227. package/src/wallet/index.ts +71 -0
  228. package/src/wallet/near/adapter.ts +626 -0
  229. package/src/wallet/near/index.ts +86 -0
  230. package/src/wallet/near/meteor-wallet.ts +1153 -0
  231. package/src/wallet/near/my-near-wallet.ts +790 -0
  232. package/src/wallet/near/wallet-selector.ts +702 -0
  233. package/src/wallet/solana/adapter.ts +6 -4
  234. package/src/wallet/solana/index.ts +13 -0
  235. package/src/wallet/solana/privacy-adapter.ts +567 -0
  236. package/src/wallet/sui/types.ts +6 -4
  237. package/src/zcash/rpc-client.ts +13 -6
  238. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  239. package/dist/chunk-3INS3PR5.mjs +0 -884
  240. package/dist/chunk-3OVABDRH.mjs +0 -17096
  241. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  242. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  243. package/dist/chunk-E6SZWREQ.mjs +0 -57
  244. package/dist/chunk-F6F73W35.mjs +0 -16166
  245. package/dist/chunk-G33LB27A.mjs +0 -16166
  246. package/dist/chunk-HGU6HZRC.mjs +0 -231
  247. package/dist/chunk-L2K34JCU.mjs +0 -1496
  248. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  249. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  250. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  251. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  252. package/dist/constants-VOI7BSLK.mjs +0 -27
  253. package/dist/index-B71aXVzk.d.ts +0 -13264
  254. package/dist/index-BYZbDjal.d.ts +0 -11390
  255. package/dist/index-CHB3KuOB.d.mts +0 -11859
  256. package/dist/index-CzWPI6Le.d.ts +0 -11859
  257. package/dist/index-pOIIuwfV.d.mts +0 -13264
  258. package/dist/index-xbWjohNq.d.mts +0 -11390
  259. package/dist/solana-4O4K45VU.mjs +0 -46
  260. package/dist/solana-5EMCTPTS.mjs +0 -46
  261. package/dist/solana-NDABAZ6P.mjs +0 -56
  262. package/dist/solana-Q4NAVBTS.mjs +0 -46
  263. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -0,0 +1,538 @@
1
+ /**
2
+ * Ethereum Gas Estimation for Privacy Transactions
3
+ *
4
+ * Provides accurate gas estimation for stealth transfers, announcements,
5
+ * and claim operations with EIP-1559 support.
6
+ *
7
+ * @module chains/ethereum/gas-estimation
8
+ */
9
+
10
+ import type { HexString } from '@sip-protocol/types'
11
+ import {
12
+ DEFAULT_GAS_LIMITS,
13
+ ONE_GWEI,
14
+ ONE_ETH,
15
+ type EthereumNetwork,
16
+ } from './constants'
17
+ import { fromWei } from './commitment'
18
+
19
+ // ─── Types ────────────────────────────────────────────────────────────────────
20
+
21
+ /**
22
+ * EIP-1559 gas price components
23
+ */
24
+ export interface EIP1559GasPrice {
25
+ /**
26
+ * Base fee per gas (from network)
27
+ */
28
+ baseFeePerGas: bigint
29
+
30
+ /**
31
+ * Max priority fee (tip to validator)
32
+ */
33
+ maxPriorityFeePerGas: bigint
34
+
35
+ /**
36
+ * Max fee per gas (cap)
37
+ */
38
+ maxFeePerGas: bigint
39
+ }
40
+
41
+ /**
42
+ * Gas estimate breakdown
43
+ */
44
+ export interface GasEstimateBreakdown {
45
+ /**
46
+ * Transfer transaction gas
47
+ */
48
+ transferGas: bigint
49
+
50
+ /**
51
+ * Announcement transaction gas
52
+ */
53
+ announcementGas: bigint
54
+
55
+ /**
56
+ * Total gas limit
57
+ */
58
+ totalGas: bigint
59
+ }
60
+
61
+ /**
62
+ * Detailed gas estimate with EIP-1559 support
63
+ */
64
+ export interface DetailedGasEstimate {
65
+ /**
66
+ * Gas breakdown by operation
67
+ */
68
+ breakdown: GasEstimateBreakdown
69
+
70
+ /**
71
+ * EIP-1559 gas price (if available)
72
+ */
73
+ eip1559?: EIP1559GasPrice
74
+
75
+ /**
76
+ * Legacy gas price (fallback)
77
+ */
78
+ legacyGasPrice: bigint
79
+
80
+ /**
81
+ * Estimated cost in wei
82
+ */
83
+ estimatedCostWei: bigint
84
+
85
+ /**
86
+ * Estimated cost in ETH
87
+ */
88
+ estimatedCostEth: string
89
+
90
+ /**
91
+ * Estimated cost range (min/max)
92
+ */
93
+ costRange: {
94
+ minWei: bigint
95
+ maxWei: bigint
96
+ minEth: string
97
+ maxEth: string
98
+ }
99
+
100
+ /**
101
+ * Timestamp of estimate
102
+ */
103
+ timestamp: number
104
+ }
105
+
106
+ /**
107
+ * Options for gas estimation
108
+ */
109
+ export interface GasEstimationOptions {
110
+ /**
111
+ * Include priority fee buffer percentage (default: 10)
112
+ */
113
+ priorityFeeBuffer?: number
114
+
115
+ /**
116
+ * Use legacy pricing (no EIP-1559)
117
+ */
118
+ legacyPricing?: boolean
119
+
120
+ /**
121
+ * Custom base fee override
122
+ */
123
+ customBaseFee?: bigint
124
+
125
+ /**
126
+ * Custom priority fee override
127
+ */
128
+ customPriorityFee?: bigint
129
+ }
130
+
131
+ /**
132
+ * Cached gas price data
133
+ */
134
+ interface GasPriceCache {
135
+ baseFee: bigint
136
+ priorityFee: bigint
137
+ timestamp: number
138
+ network: EthereumNetwork
139
+ }
140
+
141
+ // ─── Constants ────────────────────────────────────────────────────────────────
142
+
143
+ /**
144
+ * Cache duration for gas prices (30 seconds)
145
+ */
146
+ const GAS_PRICE_CACHE_DURATION = 30_000
147
+
148
+ /**
149
+ * Default priority fee (2 gwei)
150
+ */
151
+ const DEFAULT_PRIORITY_FEE = 2n * ONE_GWEI
152
+
153
+ /**
154
+ * Default base fee assumption (30 gwei)
155
+ */
156
+ const DEFAULT_BASE_FEE = 30n * ONE_GWEI
157
+
158
+ /**
159
+ * Multiplier for max fee (2x base fee)
160
+ */
161
+ const MAX_FEE_MULTIPLIER = 2n
162
+
163
+ /**
164
+ * Gas price by network (approximate baselines)
165
+ */
166
+ const NETWORK_GAS_PRICES: Record<EthereumNetwork, bigint> = {
167
+ mainnet: 30n * ONE_GWEI,
168
+ sepolia: 1n * ONE_GWEI,
169
+ goerli: 1n * ONE_GWEI,
170
+ arbitrum: ONE_GWEI / 10n, // 0.1 gwei
171
+ 'arbitrum-sepolia': ONE_GWEI / 10n,
172
+ optimism: ONE_GWEI / 10n,
173
+ 'optimism-sepolia': ONE_GWEI / 10n,
174
+ base: ONE_GWEI / 10n,
175
+ 'base-sepolia': ONE_GWEI / 10n,
176
+ polygon: 30n * ONE_GWEI,
177
+ 'polygon-mumbai': 1n * ONE_GWEI,
178
+ zksync: ONE_GWEI / 10n,
179
+ scroll: ONE_GWEI / 10n,
180
+ linea: ONE_GWEI / 10n,
181
+ mantle: ONE_GWEI / 10n,
182
+ blast: ONE_GWEI / 10n,
183
+ bsc: 3n * ONE_GWEI, // BSC mainnet ~3-5 gwei
184
+ 'bsc-testnet': 1n * ONE_GWEI,
185
+ localhost: 1n * ONE_GWEI,
186
+ }
187
+
188
+ // ─── Gas Price Cache ─────────────────────────────────────────────────────────
189
+
190
+ let gasPriceCache: GasPriceCache | null = null
191
+
192
+ /**
193
+ * Clear the gas price cache
194
+ */
195
+ export function clearGasPriceCache(): void {
196
+ gasPriceCache = null
197
+ }
198
+
199
+ /**
200
+ * Check if cache is valid
201
+ */
202
+ function isCacheValid(network: EthereumNetwork): boolean {
203
+ if (!gasPriceCache) return false
204
+ if (gasPriceCache.network !== network) return false
205
+ return Date.now() - gasPriceCache.timestamp < GAS_PRICE_CACHE_DURATION
206
+ }
207
+
208
+ /**
209
+ * Get cached or default gas prices
210
+ */
211
+ function getCachedOrDefaultGasPrice(network: EthereumNetwork): {
212
+ baseFee: bigint
213
+ priorityFee: bigint
214
+ } {
215
+ if (isCacheValid(network)) {
216
+ return {
217
+ baseFee: gasPriceCache!.baseFee,
218
+ priorityFee: gasPriceCache!.priorityFee,
219
+ }
220
+ }
221
+
222
+ return {
223
+ baseFee: NETWORK_GAS_PRICES[network] ?? DEFAULT_BASE_FEE,
224
+ priorityFee: DEFAULT_PRIORITY_FEE,
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Update gas price cache
230
+ */
231
+ export function updateGasPriceCache(
232
+ network: EthereumNetwork,
233
+ baseFee: bigint,
234
+ priorityFee: bigint
235
+ ): void {
236
+ gasPriceCache = {
237
+ baseFee,
238
+ priorityFee,
239
+ timestamp: Date.now(),
240
+ network,
241
+ }
242
+ }
243
+
244
+ // ─── Gas Estimation Functions ────────────────────────────────────────────────
245
+
246
+ /**
247
+ * Estimate gas for ETH stealth transfer
248
+ *
249
+ * Includes transfer to stealth address + announcement
250
+ *
251
+ * @param network - Target network
252
+ * @param options - Estimation options
253
+ * @returns Detailed gas estimate
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * const estimate = estimateEthTransferGas('mainnet')
258
+ * console.log(estimate.estimatedCostEth) // '0.003'
259
+ * console.log(estimate.breakdown.transferGas) // 21000n
260
+ * ```
261
+ */
262
+ export function estimateEthTransferGas(
263
+ network: EthereumNetwork = 'mainnet',
264
+ options: GasEstimationOptions = {}
265
+ ): DetailedGasEstimate {
266
+ const breakdown: GasEstimateBreakdown = {
267
+ transferGas: DEFAULT_GAS_LIMITS.ethTransfer,
268
+ announcementGas: DEFAULT_GAS_LIMITS.announcement,
269
+ totalGas: DEFAULT_GAS_LIMITS.ethTransfer + DEFAULT_GAS_LIMITS.announcement,
270
+ }
271
+
272
+ return buildDetailedEstimate(network, breakdown, options)
273
+ }
274
+
275
+ /**
276
+ * Estimate gas for ERC-20 stealth transfer
277
+ *
278
+ * Includes token transfer to stealth address + announcement
279
+ *
280
+ * @param network - Target network
281
+ * @param includeApproval - Whether to include approval gas
282
+ * @param options - Estimation options
283
+ * @returns Detailed gas estimate
284
+ *
285
+ * @example
286
+ * ```typescript
287
+ * const estimate = estimateTokenTransferGas('mainnet', true)
288
+ * console.log(estimate.breakdown.transferGas) // includes approval
289
+ * ```
290
+ */
291
+ export function estimateTokenTransferGas(
292
+ network: EthereumNetwork = 'mainnet',
293
+ includeApproval: boolean = false,
294
+ options: GasEstimationOptions = {}
295
+ ): DetailedGasEstimate {
296
+ let transferGas = DEFAULT_GAS_LIMITS.erc20Transfer
297
+ if (includeApproval) {
298
+ transferGas += DEFAULT_GAS_LIMITS.erc20Approve
299
+ }
300
+
301
+ const breakdown: GasEstimateBreakdown = {
302
+ transferGas,
303
+ announcementGas: DEFAULT_GAS_LIMITS.announcement,
304
+ totalGas: transferGas + DEFAULT_GAS_LIMITS.announcement,
305
+ }
306
+
307
+ return buildDetailedEstimate(network, breakdown, options)
308
+ }
309
+
310
+ /**
311
+ * Estimate gas for claiming from stealth address
312
+ *
313
+ * @param network - Target network
314
+ * @param isTokenClaim - Whether claiming tokens (vs ETH)
315
+ * @param options - Estimation options
316
+ * @returns Detailed gas estimate
317
+ */
318
+ export function estimateClaimGas(
319
+ network: EthereumNetwork = 'mainnet',
320
+ isTokenClaim: boolean = false,
321
+ options: GasEstimationOptions = {}
322
+ ): DetailedGasEstimate {
323
+ const claimGas = isTokenClaim
324
+ ? DEFAULT_GAS_LIMITS.erc20Transfer
325
+ : DEFAULT_GAS_LIMITS.ethTransfer
326
+
327
+ const breakdown: GasEstimateBreakdown = {
328
+ transferGas: claimGas,
329
+ announcementGas: 0n,
330
+ totalGas: claimGas,
331
+ }
332
+
333
+ return buildDetailedEstimate(network, breakdown, options)
334
+ }
335
+
336
+ /**
337
+ * Estimate gas for registry operations
338
+ *
339
+ * @param network - Target network
340
+ * @param operation - Registry operation type
341
+ * @param options - Estimation options
342
+ * @returns Detailed gas estimate
343
+ */
344
+ export function estimateRegistryGas(
345
+ network: EthereumNetwork = 'mainnet',
346
+ operation: 'register' | 'update' | 'query' = 'register',
347
+ options: GasEstimationOptions = {}
348
+ ): DetailedGasEstimate {
349
+ let operationGas: bigint
350
+
351
+ switch (operation) {
352
+ case 'register':
353
+ operationGas = DEFAULT_GAS_LIMITS.registryRegister
354
+ break
355
+ case 'update':
356
+ operationGas = DEFAULT_GAS_LIMITS.registryUpdate
357
+ break
358
+ case 'query':
359
+ operationGas = 0n // View call, no gas
360
+ break
361
+ }
362
+
363
+ const breakdown: GasEstimateBreakdown = {
364
+ transferGas: operationGas,
365
+ announcementGas: 0n,
366
+ totalGas: operationGas,
367
+ }
368
+
369
+ return buildDetailedEstimate(network, breakdown, options)
370
+ }
371
+
372
+ /**
373
+ * Build detailed gas estimate from breakdown
374
+ */
375
+ function buildDetailedEstimate(
376
+ network: EthereumNetwork,
377
+ breakdown: GasEstimateBreakdown,
378
+ options: GasEstimationOptions
379
+ ): DetailedGasEstimate {
380
+ const { baseFee, priorityFee } = getCachedOrDefaultGasPrice(network)
381
+
382
+ const effectiveBaseFee = options.customBaseFee ?? baseFee
383
+ const effectivePriorityFee = options.customPriorityFee ?? priorityFee
384
+
385
+ // Apply priority fee buffer
386
+ const bufferMultiplier = 100n + BigInt(options.priorityFeeBuffer ?? 10)
387
+ const bufferedPriorityFee = (effectivePriorityFee * bufferMultiplier) / 100n
388
+
389
+ // EIP-1559 pricing
390
+ const maxPriorityFeePerGas = bufferedPriorityFee
391
+ const maxFeePerGas = effectiveBaseFee * MAX_FEE_MULTIPLIER + maxPriorityFeePerGas
392
+
393
+ // Legacy pricing (effectiveGasPrice = baseFee + priorityFee)
394
+ const legacyGasPrice = effectiveBaseFee + bufferedPriorityFee
395
+
396
+ // Cost calculation
397
+ const estimatedCostWei = breakdown.totalGas * (effectiveBaseFee + bufferedPriorityFee)
398
+ const minCostWei = breakdown.totalGas * effectiveBaseFee
399
+ const maxCostWei = breakdown.totalGas * maxFeePerGas
400
+
401
+ return {
402
+ breakdown,
403
+ eip1559: options.legacyPricing
404
+ ? undefined
405
+ : {
406
+ baseFeePerGas: effectiveBaseFee,
407
+ maxPriorityFeePerGas,
408
+ maxFeePerGas,
409
+ },
410
+ legacyGasPrice,
411
+ estimatedCostWei,
412
+ estimatedCostEth: fromWei(estimatedCostWei),
413
+ costRange: {
414
+ minWei: minCostWei,
415
+ maxWei: maxCostWei,
416
+ minEth: fromWei(minCostWei),
417
+ maxEth: fromWei(maxCostWei),
418
+ },
419
+ timestamp: Date.now(),
420
+ }
421
+ }
422
+
423
+ // ─── Gas Price Fetching Helpers ──────────────────────────────────────────────
424
+
425
+ /**
426
+ * Parse gas price from RPC response
427
+ *
428
+ * @param response - eth_gasPrice response (hex string)
429
+ * @returns Gas price in wei
430
+ */
431
+ export function parseGasPriceResponse(response: HexString): bigint {
432
+ return BigInt(response)
433
+ }
434
+
435
+ /**
436
+ * Parse fee history from RPC response
437
+ *
438
+ * @param baseFeePerGas - Array of base fees from eth_feeHistory
439
+ * @param reward - Array of priority fees from eth_feeHistory
440
+ * @returns Parsed gas prices
441
+ */
442
+ export function parseFeeHistoryResponse(
443
+ baseFeePerGas: HexString[],
444
+ reward: HexString[][]
445
+ ): { baseFee: bigint; priorityFee: bigint } {
446
+ // Use most recent base fee (last in array is pending block)
447
+ const latestBaseFee = baseFeePerGas.length > 1
448
+ ? BigInt(baseFeePerGas[baseFeePerGas.length - 2])
449
+ : BigInt(baseFeePerGas[0] ?? '0x0')
450
+
451
+ // Use median priority fee from most recent block
452
+ const latestRewards = reward[reward.length - 1] ?? []
453
+ const priorityFees = latestRewards.map(r => BigInt(r))
454
+
455
+ const medianPriorityFee = priorityFees.length > 0
456
+ ? priorityFees.sort((a, b) => (a < b ? -1 : 1))[Math.floor(priorityFees.length / 2)]
457
+ : DEFAULT_PRIORITY_FEE
458
+
459
+ return {
460
+ baseFee: latestBaseFee,
461
+ priorityFee: medianPriorityFee,
462
+ }
463
+ }
464
+
465
+ /**
466
+ * Calculate effective gas price for EIP-1559 transaction
467
+ *
468
+ * @param baseFee - Current base fee
469
+ * @param maxPriorityFee - Max priority fee from user
470
+ * @param maxFee - Max fee cap from user
471
+ * @returns Effective gas price
472
+ */
473
+ export function calculateEffectiveGasPrice(
474
+ baseFee: bigint,
475
+ maxPriorityFee: bigint,
476
+ maxFee: bigint
477
+ ): bigint {
478
+ const effectivePriorityFee = maxPriorityFee < maxFee - baseFee
479
+ ? maxPriorityFee
480
+ : maxFee - baseFee
481
+
482
+ return baseFee + (effectivePriorityFee > 0n ? effectivePriorityFee : 0n)
483
+ }
484
+
485
+ // ─── Cost Formatting ─────────────────────────────────────────────────────────
486
+
487
+ /**
488
+ * Format gas cost for display
489
+ *
490
+ * @param costWei - Cost in wei
491
+ * @param ethPriceUsd - Optional ETH price in USD
492
+ * @returns Formatted cost string
493
+ */
494
+ export function formatGasCost(
495
+ costWei: bigint,
496
+ ethPriceUsd?: number
497
+ ): { eth: string; usd?: string } {
498
+ const eth = fromWei(costWei)
499
+
500
+ if (ethPriceUsd === undefined) {
501
+ return { eth }
502
+ }
503
+
504
+ const ethValue = Number(costWei) / Number(ONE_ETH)
505
+ const usdValue = ethValue * ethPriceUsd
506
+
507
+ return {
508
+ eth,
509
+ usd: usdValue.toFixed(2),
510
+ }
511
+ }
512
+
513
+ /**
514
+ * Get gas price suggestion by speed
515
+ *
516
+ * @param baseFee - Current base fee
517
+ * @param speed - Transaction speed
518
+ * @returns Suggested gas price settings
519
+ */
520
+ export function getGasPriceSuggestion(
521
+ baseFee: bigint,
522
+ speed: 'slow' | 'standard' | 'fast'
523
+ ): EIP1559GasPrice {
524
+ const priorityFees: Record<typeof speed, bigint> = {
525
+ slow: ONE_GWEI,
526
+ standard: 2n * ONE_GWEI,
527
+ fast: 5n * ONE_GWEI,
528
+ }
529
+
530
+ const priorityFee = priorityFees[speed]
531
+ const maxFee = baseFee * 2n + priorityFee
532
+
533
+ return {
534
+ baseFeePerGas: baseFee,
535
+ maxPriorityFeePerGas: priorityFee,
536
+ maxFeePerGas: maxFee,
537
+ }
538
+ }